Reverse SSH Redirectors

I'm a fan of redirectors. They're quick and simple to set up (especially if you're using something like Terraform and allow you to both keep the labour-intensive pieces of your infrastructure, such as C2 servers, relatively static while still hiding their IPs from your target.

Getting this running smoothly took a little bit of doing so I'll be focusing on the gotchas of the configuration to (hopefully) save you some headache.


Up until recently, I'd just used socat TCP4-LISTEN:443,fork TCP4:<C2_IP>:443 for this. Stand up a cloud server, redirect inbound tcp/443 to tcp/443 on your C2 IP, and you're good to go.

+--------+   tcp/443   +------------+   tcp/443   +------+
| Target +------------>+ Redirector +------------>+  C2  |
+--------+             +------------+             +------+

This works well, but after reading Tim MalcomVetter's post on safe red team architecture, I've rethought things a bit and am really happy with the results.


SSH Reverse Tunnels are in the same league as object-oriented programming and subnetting. They make absolutely no sense until they do and then you love them. Put simply, they allow you to reach out to a server over SSH and forward a port on that machine to a local port on yours.

This allows us to do something like this instead:

+--------+   tcp/443   +------------+   tcp/22   +------+
| Victim +------------>+ Redirector +<-----------+  C2  |
+--------+             +------------+            +------+

Instead of forwarding traffic into our C2, we allow SSH out. We connect to the redirectors on our terms and can sever that connection immediately without needing to jump into a firewall.

Let's look at how this works in practice.

Redirector Configuration

We're going to need to make a few configuration changes to SSH on our redirectors to allow our remote tunnel to work.

First, open up /etc/ssh/sshd_config and ensure you have the following lines somewhere in it:

# Allow anyone to connect to forwarded ports
GatewayPorts yes

# Allow both local and remote (to external machines) port forwards
AllowTcpForwarding yes

Restart SSH and you're good to go.

C2 Configuration

You can complete this step using either SSH or AutoSSH. I'm going to use the former, although the process should be nearly identical for both.

Since I don't like losing shells after accidentally closing windows or losing connections, we're going to do this in a tmux session.

# Create and attach to a new tmux session
tmux new-session -s ssh-443
tmux attach-session -t ssh-443

# Initiate SSH tunnel
ssh <USER>@<REDIRECTOR IP> -R *:443:localhost:443

# Detach from the session. Or add another window and begin pwnage. Up to you.
C-b d

This will forward tcp/443 on your redirector through ssh to tcp/443 on your C2 machine. You can now bind handlers or listeners to and catch shells like you normally would.

It's pretty obvious that the -R specifies a remote tunnel, but let's take a closer look at the port forward configuration:

We Need to Go Deeper

We can also chain these commands ad nauseum. Once the remote tunnel to your redirector is established, just create another one from that machine to the next. And on and on.