Netcat (nc)#

The nc command is a linux utility that allows you to write to and listen to the network. See the official documentation of the canonical GNU net cat realization here.

Help#

The classic --help option doesn’t work for the nc command - use -h instead. Or just check it in the following cell.

nc -h
OpenBSD netcat (Debian patchlevel 1.226-1ubuntu2)
usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
	  [-m minttl] [-O length] [-P proxy_username] [-p source_port]
	  [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
	  [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
	  [destination] [port]
	Command Summary:
		-4		Use IPv4
		-6		Use IPv6
		-b		Allow broadcast
		-C		Send CRLF as line-ending
		-D		Enable the debug socket option
		-d		Detach from stdin
		-F		Pass socket fd
		-h		This help text
		-I length	TCP receive buffer length
		-i interval	Delay interval for lines sent, ports scanned
		-k		Keep inbound sockets open for multiple connects
		-l		Listen mode, for inbound connects
		-M ttl		Outgoing TTL / Hop Limit
		-m minttl	Minimum incoming TTL / Hop Limit
		-N		Shutdown the network socket after EOF on stdin
		-n		Suppress name/port resolutions
		-O length	TCP send buffer length
		-P proxyuser	Username for proxy authentication
		-p port		Specify local port for remote connects
		-q secs		quit after EOF on stdin and delay of secs
		-r		Randomize remote ports
		-S		Enable the TCP MD5 signature option
		-s sourceaddr	Local source address
		-T keyword	TOS value
		-t		Answer TELNET negotiation
		-U		Use UNIX domain socket
		-u		UDP mode
		-V rtable	Specify alternate routing table
		-v		Verbose
		-W recvlimit	Terminate after receiving a number of packets
		-w timeout	Timeout for connects and final net reads
		-X proto	Proxy protocol: "4", "5" (SOCKS) or "connect"
		-x addr[:port]	Specify proxy address and port
		-Z		DCCP mode
		-z		Zero-I/O mode [used for scanning]
	Port numbers can be individual or ranges: lo-hi [inclusive]

Modes#

There is two modes of the nc process:

  • Listener: listens to the messages. Can be specified by -l option, requires port as a positional argument.

  • Writer: sends messages. Requires host and port to which send messages as positional arguments.


Consider the example where we start nc in a listener mode in docker and send to it messages from the host machine.

The following cell runs an nc in listen mode and redirects everything it hears to the /tmp/nc_out file.

(nc -l -w 30 -p 1234 &> /tmp/nc_out &) &> /dev/null

Now you can run nc localhost 1234 in the terminal, every line you type will be written to port 1234 on localhost. Due to the liminations of represenations in jupyter notebook, we can’t show here, how it works, but the following cell sends a line to the listener.

echo "my message by network" | nc -w 1 localhost 1234

Finally, let’s check if the line was really redirected by the listener to the /tmp/nc_out.

cat /tmp/nc_out
my message by network

Infinite sender#

Sometimes, for debugging purposes, it’s useful to have an infinite sender - every time something tries to connect, it sends something.


The following cell shows how such a tool can be started using typical bash syntax.

while true; do echo "hello world" | nc localhost 12345; done &
[1] 1755455

And now every time you add a listener to it the listener will immeditely throw the message specified in the writer.

nc -w 1 -l localhost 12345
hello world

Packages#

There are two versions of the nc command, they are used for the same purposes but have some peculiarities associated with working with them.

  • Use apt install netcat-openbsd for the Ubuntu installation. We’ll using this version in the general examples.

  • Use apt  install netcat-traditional for a different version.


The following cell installs both the traditional and OpenBSD versions of the program - it’s no problem to have both.

apt install netcat-openbsd netcat-traditional &> /dev/null

You can identify what exactly version you’re using by by looking at first line of the help.

nc -h 2>&1 | head -n 1
OpenBSD netcat (Debian patchlevel 1.219-1)

The default nc command refers to the OpenBSD version. However, you can access a specific version by using nc.traditional for traditional version and nc.openbsd for the OpenBSD version.

nc.traditional -h 2>&1 | head -n 1
[v1.10-47]
nc.openbsd -h 2>&1 | head -n 1
OpenBSD netcat (Debian patchlevel 1.219-1)

Adress and port#

For the nc command, you must specify the address and port. There are few options to specify them. Use the syntax:

  • nc -l -p <port> to listen on the specified port on localhost.

  • nc -l <address> <port> to listen on the specified port of the specified address.

  • Note: if you are using nc.traditional you can’t use nc -l <address> <port> - you have to specify port with -p parameter and address with -s


The following cell starts an infinite sender that we’ll use to test different listening options.

while true; do echo "hello world" | nc localhost 12345; done &
[4] 3605158

Listening on the port 12345, the localhost as address is not explicitly specified.

nc -w 1 -l -p 12345
hello world

Using the <address> <port> syntax as a positional argument allows you to specify address and port explicitly.

nc -w 1 -l localhost 12345
hello world

You can spend some time trying to get nc.traditional to work with this syntax, but it’s not possible, the following cell shows that it doesn’t work.

timeout 1s nc.traditional -l localhost 12345
true

But by specifying the address through the s parameter and the port through p parameter, it will work with nc.traditional as well.

timeout 1s nc.traditional -l -s localhost -p 12345
true
hello world