Netcat – The Admin’s Best Friend

With the seemingly unlimited number of Linux packages available today in repositories, sometimes it’s easy to get lost and miss out on the really high quality packages – those that offer the most impressive functionality.

I’m sure you could name a few ubiquitous networking packages that the majority of admins might have used in the past. I’m thinking about userland packages the likes of ngrep, IPTraf, Tcpdump, Nmap, and iftop.

As well as these well-known tools, a program you almost certainly have come across is the relatively famous Netcat. The outstanding Netcat is often referred to as the Swiss Army Knife of networking; to say that it is versatile is the biggest understatement I’m sure you will hear all week.

Among its formidable feature set, the fantastically minute Netcat can be a random port-scanning hacking tool, a whitehat security tool, and a server or a client; it performs monitoring, supports tunnelling, and is a simple TCP proxy server on top of all that! Hard to believe, I realize, but in this article, I’ll have a more detailed look at what the venerable Netcat can do.

First Things First

Netcat has been around for a long time, and it’s been able to do all sorts of things relating to TCP and UDP since its inception. These days, it handles IPv6 as well as IPv4 beautifully. Its astounding versatility means that integrating it with scripts is a veritable piece of cake. I have heard it said in fact that Netcat actually comes with too many features, but with a minuscule installation footprint, there’s surely not much cause for complaint.

One tool that many admins have used to test open ports in the past is the widely used Telnet client. If you were opening a web page to test an HTTP server, you could use something along the lines of:

# telnet remotehost.tld 80

Once a connection is established, you could pull the page content down with a GET (there’s no prompt inside the Telnet session):

GET /

This is a simple way to check that your newly born HTTP instance is behaving, but what if you need to check a DNS server that is configured not to use TCP but UDP instead? It’s probably no surprise that Netcat handles this task perfectly and with notable simplicity. To check that UDP port 53 is open with verbose feedback you could use:

# netcat -vu ns.nameserver.tld 53

If you want to make sure no data is sent to that port as you connect (it might be useful for a variety of surreptitious or debugging reasons), you can simply scan for listening daemons without transmitting data by adding the -z zero-mode switch after the -u.

Now, instead of UDP ports, I’ll take a quick look at a TCP port range. For example, you might want to use netcat (nc) to check FTP ports – or at least ports in that region:

# nc -v -z examplehost.tld 21-25

If you want to change the source port of your connection to 16000, you could add the -p option:

# nc -p 16000 examplehost.tld 22

To add a timeout for latency testing, you could use the -w parameter followed by the number of seconds – 30 seconds, for example:

# nc -p 16000 -w 30 examplehost.tld 22

If firewalling is in place and you need to originate your connection from a specific IP address to open a port, entering

# nc -s 1.2.3.4 examplehost.tld 8181

will connect to examplhost.tld on port 8181 using the IP address 1.2.3.4 as the source IP address. When Netcat connects successfully with verbose mode enabled, it should report the following for each port:

Connection to examplehost.tld 22 port [tcp/ssh] succeeded!

Initially connecting using the verbose -v option is definitely worth the effort because Netcat exits silently if it succeeds; otherwise, and it just hangs at the command line, which might cause significant amounts of confusion to the newly initiated.

Something else you might consider doing is disabling DNS lookups (using -n), if you expect to perform many of them, because they could impede the speed of output to your display.

Listen Up

By now you should be getting the idea of how versatile Netcat can be. However, I’ve only used Netcat to connect to remote devices so far. Now I’ll look more closely at some other functionality, create a Netcat server, and configure it to listen on a TCP port.

The syntax is really simple, as you can see, for creating a listening instance on port TCP 8080:

# nc -l 8080

You can expand this functionality much further as follows: If you want to send a file (binary or ASCII) to another host, you could use the tool cat (short for concatenate) to print the file through a pipe to your friendly Netcat daemon, which is ready to listen intently on the port number you specify. On the server side, you could use:

# cat filename.tar.gz | nc -l -p 9191

Then assuming, for the purposes of this example, you weren’t inhibited by any firewalls, at the client end, you could pick up that file by connecting to port 9191 with:

# nc serverhost 49191 > filename.tar.gz

Watch out for a gotcha. On Ubuntu Lucid Lynx, I found out that one of the highly dangerous and impressive features of Netcat appears to be disabled by default: the -e switch, which lets you execute a program on a specified port. After studying the Netcat man page, another caveat that also applies to the bundled LTS version is worth mentioning at this stage as well, in case it trips someone up: “UDP port scans will always succeed (i.e., report the port as open).” To Ubuntu’s credit, it dutifully reports: “This is nc from the netcat-openbsd package. An alternative nc is available in the netcat-traditional package.” As a result, if you are lacking the specified features, try using the alternative package.

Disabling the -e switch by default makes perfect sense, but it ruins my fun a little. Potentially, it’s a massive gaping security hole and essentially means if you can circumvent a system’s firewall, you can leave a back door open – most likely unbeknownst to the admin of that device – so a hacker can get into your system at will. In this case, I could have left /bin/sh or /bin/bash shells open to accept connections remotely.

For the curious, you achieve this on port 15015 on the server with:

# nc -l -p 15015 -e /bin/bash

Then, to spawn a remote shell on the client side without using SSH or Telnet is as simple as:

# nc server 15015

Nitty-Gritty

Now on to some trickier examples. Imagine you knew Netcat could be a security hole and didn’t trust yourself to close the open port created by a listener from Netcat after you had successffully downloaded a file. This example should apparently close the port after the file transfer has completed (but not without moving to the netcat-traditional package, as mentioned before):

{ echo -ne "HTTP/1.0 200 OK\r\n\r\n"; cat filename.tar.gz; } | nc -l -p 15000

Be warned that this might not work for you, but with some trial and error, to enable some extra interaction, you could try to open this file in your web browser. Some browsers need the length of the file specified, so you could also try to use this example instead:

{ echo -ne "HTTP/1.0 200 OK\r\nContent-Length: $(wc -c 

If all else fails (and pushing Netcat aside for a moment), you could always use Telnet as follows:

# telnet remotehost.tld 15000

Going This Way and That

For simple proxying with Netcat, try:

# nc -l 15015 | nc www.remotewebsite.tld 80

Here, you can redirect connections to 15015 to the HTTP port on www.remotewebsite.tld.

One limitation with this approach, however, is that pipes (represented by the “|” symbol) only push data in one direction. so although the connections are redirected, you won’t receive any data back! The way around this is to make the pipe a two-way pipe:

# mkfifo twowaypipe
# nc -l 15015 0twowaypipe

I would suggest trialing the way your version of Netcat and your browser react and practice with a combination of Telnet, nc www.remotewebsite.tld 80, and your browser if you encounter any difficulties.

To confirm that I was redirected correctly, I used lsof -i, and sure enough, it worked well, at least on my setup.

Forward Ports Somewhere Else

Because Netcat has been around for so many years (apparently version 1.1 was written in 1996), many versions and variants have been created in the meantime. I have not mentioned the many variants in any detail, but one in particular might be of interest to those who want to use Netcat for port forwarding, among other features: Ncat.

The Ncat version of Netcat has a host of features, such as SSL capabilties, that make it worth a look. You can accomplish port forwarding with the -c switch on the Ncat version of Netcat with this command line:

# nc -u -l -p port1 -c ' nc -u -l -p port2'

Somewhat astonishingly, you can also unwrap SSL traffic and walk through the SMTP handshake and data exchange. I find this two-chatting exchange useful sometimes: On your first server you open up a port:

# ncat -l 4444

On the other host, simply connect and type away to your heart’s content:

# ncat otherhost 4444

The Ncat package variant brings yet something else to the chat party, however. If you use the --chat switch, many users can join in, and Ncat will even highlight who has said what with useful <userNUM> prefixes.

With a doff of my cap to the olden days of Unix and the Internet, Ncat can offer all sorts of relatively simple services. For example, it can run an Echo service (originally rolled out to give response times from a system like the package ping might), and it can offer a Chargen service (character generation for remote debugging). Some services add some levity, such as the Quote of the Day service (qotd), in which a port is left open and gives out suitably dry humor or a piece of quoted wisdom on request. My favorite is a simple clock-like service that uses the /bin/date binary to tell anyone that asks the current date and time (a little like NTP).This can be accomplished with the simple command line:

# ncat -l 1313 --keep-open --send-only --exec "/bin/date"

Note that if you want to open a port below 1024, you will need to have elevated privileges because these are protected, non-ephemeral ports. Simply add --udp to opt for a UDP instead of a TCP port. For security, you can use the --send-only parameter, so you don’t need to worry about inbound data causing headaches.

To connect to your daytime service using Ncat and receive a timely response back, all you need to do is:

# ncat localhost 1313
Sat Apr 21 13:47:57 BST 2012

On Ubuntu/Debian Ncat is available via the nmap package, so you can install it by running

apt-get install nmap

A comprehensive and extremely useful guide for the Ncat variant of Netcat is available on the Nmap website.

This is The End

I hope you agree that Netcat is something to behold; to my mind, it’s the epitome of versatility. I’ve only touched on its full functionality, and it has much, much more to discover. I hope this article encourages you to delve further into this complex but intriguing network and filesystem tool.

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.