Netcat tricks and tips

Netcat is a simple command line utility for working with TCP or UDP connections. It is however surprisingly versatile and can be used for a wide range of tasks.

  .       .       
  \`-"'"-'/       
   } 6 6 {        
  ==. Y ,==       
    /^^^\  .      
   /     \  )     
  (  )-(  )/     _
  -""---""---   / 
 /   Ncat    \_/  
(     ____        
 \_.=|____E       

Note: the examples in the post use the Nmap version of Netcat instead of the original, OpenBSD, or GNU version.

Installing Netcat

For CentOS 7, Netcat is available from the standard repositories:

yum install -y nmap-ncat

There is also a Windows version of Netcat available on the Nmap site.

Sending and receiving text

Netcat can be told to listen on a port using the -l option, followed by a port:

nc -l 2222

Once Netcat is listening, another instance of Netcat can be used to connect to the port:

nc localhost 2222

After the connection is made, stdin will be sent via the TCP connection from the client to the server and vice versa:

$ nc localhost 2222
Hello from client...
Hello from server

The client can then terminate the connection by sending an end-of-file character ( ctrl+d ). Alternatively either side can kill Netcat with ctrl+c.

Note: the Nmap version of Netcat also has a --chat option. If this option is used Netcat will start a simple chat server:

$ nc localhost 2222
<announce> ::1 is connected as <user5>.
<announce> already connected: nobody.
hello, is anyone there?
<user0> maybe...

Port scanning

Netcat can be used to quickly check if a port is open:

$ echo -n | nc -vw1 127.0.0.1 22
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:22.
SSH-2.0-OpenSSH_6.6.1
Ncat: 0 bytes sent, 23 bytes received in 0.02 seconds.

In the example above, Netcat successfully connects to TCP port 22. -v is used to give verbose output, -w1 is used to set the timeout to 1 second, and echo -n is used to make sure stdin is closed.

If the port is closed you will normally either get a Connection refused message:

$ echo -n | nc -vw1 127.0.0.1 2222
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection refused.

Or the connection will time out after a second:

$ echo -n | nc -vw1 8.8.8.8 2222
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connection timed out.

There are however other messages you can get:

$ echo -n | nc -vw1 127.0.0.0 2222
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Network is unreachable.

$ echo -n | nc -vw1 bad-hostname 2222
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Could not resolve hostname "bad-hostname": Name or service not known. QUITTING.

The return code from Netcat can be used in scripts, for example:

#!/bin/sh
for port in 22 80 443
do
  if echo -n | nc -w1 localhost "$port" > /dev/null 2>&1; then
    echo "port ${port} on localhost: open"
  else
    echo "port ${port} on localhost: closed"
  fi
done

Note: nmap is probably a better tool if you want to quickly scan multiple ports.

HTTP client

Netcat can also be used as a simple HTTP client:

$ printf 'GET / HTTP/1.1\nhost: example.com\n\n' | nc example.com 80
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Content-Type: text/html
Date: Fri, 14 Apr 2017 18:06:48 GMT
Etag: "359670651+gzip+ident"
...

This is particularly useful if you want to send custom headers or malformed requests. It's also worth noting that the Nmap version of Netcat can use the --ssl option if the remote server is using SSL or TLS.

HTTP server

Netcat can also be used to start a very simple HTTP server:

nc -kl 8000 --sh-exec "echo -e 'HTTP/1.1 200 OK\r\n'; date"

Note: the -k option is used to keep Netcat listening after the first request.

Remote shell

Input sent to Netcat can be redirected to another process using the --exec option. For example:

# Start listening
$ nc -l 2222 --exec /bin/bash

# Connect and run commands
$ nc localhost 2222
uptime
 19:32:39 up  2:30,  4 users,  load average: 0.16, 0.05, 0.06

Note: blindly executing commands you receive from an unauthenticated TCP connection is rarely a good idea!

Copying files

Netcat can also be used to copy files over a network. First set Netcat to listen and redirect stdout to a file on the receiving end:

nc -l 2222 > received_file.txt

Then send the file:

nc localhost 2222 < info.txt

If you're worried about sending information in the clear, gpg can be used to encrypt the data before it's sent:

gpg --batch --passphrase secret_key --symmetric -o - info.txt | nc localhost 2222

And decrypt the data being received:

nc -l 2222 | gpg --batch --passphrase secret_key -o received_file.txt

Note: secure copy (scp) is a far easier way to copy files if sshd is up and running.

Further reading

The original version of Netcat has a README that's worth reading. The Nmap version of Netcat also has a guide which has more information and some interesting examples.