Actions: | Security

AllGoodBits.org

Navigation: Home | Services | Tools | Articles | Other

Network Socket Programming with netcat(1) and shell

netcat

Sometimes we want to send or receive data across the network directly, using lightweight tools providing as much visibility as possible. netcat is one such tool.

Here is a minimal example of sending:

cat file | nc <remotehost>.example.com -p <portnumber>

Yes, this is just one simple way, there are others, possibly better [1].

Sometimes we want to receive data easily:

nc -l -p <portnumber> [| <some command>] > $HOME/outputfile

Once I wanted to receive data, save it and send it on elsewhere. This listens on 8192, saves to a file, prepends an identifier (which happened to be an API key for a SaaS) and sends it on to a specified port on a remote host:

nc -lk 8192 | tee -a /var/log/foo.log | sed -u -e 's/^/by236-32654980709-1902-ugwd/' | nc some.remotehost.com 2003

These kinds of command patterns are excellent examples of the great power and flexibility enabled by unix pipes. Either of those pipelines could easily have other commands added, here are a couple of simple examples.

gzip(1) to add compression/decompression:

cat file | gzip | nc <remotehost> -p <portnumber>
nc -l -p <portnumber> | gzip -d > $HOME/outputfile

pv(1) to watch progress:

cat file | pv -ptbar | nc <remotehost> -p <portnumber>
nc -l -p <portnumber> | pv -ptbar > $HOME/outputfile

processing tools such as sed(1) and tr(1)

shell

Some shells create pseudo-devices that represent network sockets that present just as ordinary files and can read from and written in the same ways. I know that it has worked with bash(1) for years and ksh(1) at least since ksh-93, perhaps before.

This opens a socket on port 80 of remotehost.example.com, makes an HTTP request, and displays the reply:

exec 3<> /dev/tcp/remotehost.example.com/80
echo -e "GET /index.html HTTP/1.0\n\n" 1>&3
while read 0<&3; do echo $REPLY; done

See Also

[1]I am aware of the useless use of cat(1) here, but I think this usage is more readable than "nc <remotehost> -p <portnumber> < file".