Socat – ssl-enabled netcat + much more

During recent VA testing, I needed an ssl-enabled Netcat to shovel some hand-crafted attacks at a web server.

After looking at and rejecting ncat - too rough around the edges – I turned to socat.

Socat turned out to be a well-honed jewel of a program. This write-up gives a quick overview of features, and also quickly documents install and basic use.

The basic idea

The program has an elegant design.

The man page says it all:

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.

Conceptually the program works like this:

Figure 1 Socat's Bidirectional Data flow

Specifying the command

The command syntax is:

socat [options] <address> <address>

where the "address" can be any of:

Opens <filename> and uses the file descriptor for writing
Forks a sub-process, uses exec()
Forks a sub-process, uses system()
FD:<fdnum>    (file descriptor)
Uses the Unix file descriptor specified
Uses the specified file descriptor
"Generic open" of a file: Could be a file, or a Unix socket
Just open file but fails if Unix socket specified
Open the named pipe
Create an unnamed pipe – works as echo since everything written to it automatically reappears as read data
Connects to <filename> assuming it is a UNIX domain socket.
Listens on <filename> using a UNIX domain stream socket and accepts a connection.
Opens a raw IPv4 socket. If desired, can even send IP hdrs as part of the data
Idem for IPv6
Idem using Tcp V4
Listens on Tcp V4 <port>
TCP6:<host>:<port>; TCP6-LISTEN:<port>
Idem using Tcp V6
UDP4:<host>:<port>; UDP4-LISTEN:<port>
Idem using Udp V4
UDP6:<host>:<port>; UDP6-LISTEN:<port>
Idem using Udp V6
Establish an SSL connection
Listens of tcp4 <port>, behaves as an SSL server
Connects to an HTTP proxy server on port 8080, and send a CONNECT request for <hostname> on Tcp v4 <port>
Generates a pseudo-terminal and uses its master side. Another process can open the slave side and use it like a serial port or dumb terminal
Use GNU readline and history on stdio to allow editing / reusing of input lines
Connects via <socks-server> [IPv4 address] to <host> [IPv4 address] on <port> [TCP service], using socks V4 protocol.
Idem with socks V4a protocol
There are a multitude of options to allow fine-tuning of a given connection.

Some examples

The program distro includes a file with lots of examples. Here are a few:

socat - TCP:
Similar to "netcat 80
socat - TCP-LISTEN:25,crlf
Listen on port 25, wait for an incoming connection, use CR+NL on this connection, relay data to and from stdio
socat TCP-LISTEN:80,reuseaddr,fork,su=nobody TCP:www.dmz.mydomain.org:80
Reverse proxy TCP port 80 from everywhere (internet, intranet, dmz) through the firewall to the DMZ webserver
socat UNIX-LISTEN:/tmp/.X11-unix/X1,fork PROXY:firewall:loopback:6000
Found an XWindow Server on an Http proxy with IP filters but allows Http CONNECT to loopback? …

So prepare your host: rm -f /tmp/.X11-unix/X1

Then relay a pseudo display :1 on your machine to victim:0
xterm1$ socat -d -d exec:"ssh target ~/bin/socat -d -d unix-l:/tmp/.X11-unix/X1 -" unix:/tmp/.X11-unix/X0

xterm2$ ssh target

target$ DISPLAY=:1 myxapplication
Access local display from ssh server, when ssh port forwarding is disabled

// socat must be installed on ssh server host

// might have to use xauth...

// this example is one-shot, because ',' cannot be passed to remote socat
(echo -e "CONNECT HTTP/1.0\n"; sleep 5; echo -e "GET /download/file HTTP/1.0\n"; sleep 10) |socat -d -d -t 3600 - tcp:proxy:8080,crlf
Download with proxy CONNECT


Installation is simple. I did my install on a development RHEL5 with OpenSSL and standard development tools installed.

Once I remembered to remount my external USB drive with the EXEC option so that "configure" could execute gcc, then standard gnu install worked fine:

make install

Had to allocate /usr/local/man/man1 for the manpage before installing.

USing socat as ssl-enabled Netcat

This section documents basic use of socat as an ssl-enabled netcat replacement.

Build an input file containing Http headers

Did a wireshark trace of an ordinary web site (www.cisco.com) to get some http headers:

GET / HTTP/1.1

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv: Gecko/2009082505 Red Hat/3.0.14-1.el5_4 Firefox/3.0.14

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-us,en;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Connection: keep-alive

Web servers want CRLF, so used unix2dos command to do this.

unix2dos http-request

Note the blank line at the end to tell the web server that there are no more headers.

This then became the input file containing http headers to send to the web server.

Specifying the socat cmd

OpenSSL will verify the certificate to ensure the CA is known. So need to tell OpenSSL where to find the list of CAs.

The socat cmd is:

socat -ddd -v ./http-request OPENSSL:mail.google.com:443,cafile=/etc/pki/tls/certs/ca-bundle.crt

Note that this will send the whole input file to the server in one operation. Then socat will write the web server's response (in clear text) to the end of the "http-request" file.

Interactive mode

Another possibility is full interactive mode. Each line (i.e. http header) can be edited before sending it along to the web server.

Here is the cmd that can be used:

socat -ddd -v readline,history=http-request OPENSSL:mail.google.com:443,cafile=/etc/pki/tls/certs/ca-bundle.crt

Standard GNU readline / history file support is used, so on my PC, ESC got me to history mode and "up" key moved back through the history file.

The web server's output will be echoed back (in the clear) to STDOUT.

This gives full manual control of all data sent to the web server.

Here is the output: Sample session output

No comments: