When things just don't work
It's been maddening. I had this great idea where I would download the Wireguard deb file, modify it to have some pre-configured commands that run after installation which would connect it to my command and control server, and then have the beacon launch to reach out over this VPN tunnel Wireguard made. I would repackage it and send it off to some dev as a phishing exercise. It was going to work great, the end user would be blind to it apart from a random Wireguard interface they would see and some running processes. But it was a lot more difficult than I imagined to automate this.
What did work?
Let's quickly go over what did work for this. Wireguard makes it so easy and fast to make a VPN tunnel between two servers. In less than 10 commands on each endpoint, we can have a working private tunnel that is really well encrypted and is blazing fast. There is almost no noticeable latency compared to something like OpenVPN.
The quickstart guide available made this so simple to do and it had all the commands you would need. Getting this running through the postinst script located in the deb file was fairly easy.Then, you ship the private key and reverse shell inside the usr directory and, after installation, our postinst script generates the pubkey consistently and finishes the rest of our setup before running the reverse shell.
One specific configuration point you need ahead of time is knowing the other ends IP. This is fine for your beacon, your C2 IP probably doesn't change often. But your C2 needs to know your beacons public IP ahead of time before you try to set the bridge up. This was the primary pain point I ran into when trying to automate it all through a shell script.
Where I got hung up
There were a few methods I played around with for determining the IP of the host. I could curl ipchicken.com and then send that either encoded or encrypted in some manner over the network. This though would raise a lot of flags in the SIEM since I was using a CLI tool to determine my public IP. I could try to map each public IP that the company had on record, but this would get messy very fast and wasn't guaranteed at all to work. I wanted to do everything I could to prevent the beacon from reaching out to my C2 before the VPN was established. I also wanted to keep this all packaged up inside the deb file. I could make a chron job scheduled task for the beacon to launch an hour after installation of the main package and send off the public IP immediately, automate the C2 to collect these IPs and associated public keys, and then create a channel with them. But this would fail on our goal of not communicating outside of the VPN and it would leave a very traceable event in the chron job. It was at this point I decided to table this for now and look at other methods.
I don't think this is necessarily a bad idea. There's quite a bit of potential here for something in the future and it's worth keeping in mind when thinking of new ways to get footholds on servers. For now though, this is on hold.