Netcat – The admin's best friend
Utile
With the seemingly unlimited number of Linux packages that are available today, sometimes it's easy to become distracted 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, for example, about userland packages like ngrep, IPTraf, Tcpdump, Nmap, and iftop.
As well as these tools, however, you almost certainly will have encountered the relatively famous Netcat. Among its formidable feature set, the fantastic Netcat can be a random port-scanning hacking tool, a whitehat security tool, and a server or a client; it performs monitoring, supports tunneling, and is a simple TCP proxy server on top of that! Hard to believe, I realize, but in this article, I'll take a more detailed look at what the venerable Netcat can do.
First Things First
Netcat [1] 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; however with a minuscule installation footprint, there's surely not much cause for complaint.
One tool that many admins have put to use in the past to test open ports is the widely used Telnet client.
For example, 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 for TCP but for 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 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 with 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, then you can enter:
# nc -s 1.2.3.4 examplehost.tld 8181
to connect to examplehost.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, 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 an 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 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 that 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, I noticed another caveat regarding the bundled LTS version that is worth mentioning at this stage, in case it trips someone up: "UDP port scans will always succeed (i.e., report the port as open)."
To Ubuntu's credit, the page 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 security hole and essentially means that 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, spawning a remote shell on the client side is as simple as doing:
# nc server 15015
without using SSH or Telnet.
Nitty-Gritty
Now, I'll look at some trickier examples. Imagine you knew that 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 successfully downloaded a file. This example should 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:
{ echo -ne U "HTTP/1.0 200 OK\r\nContent-Length: \ $(wc -c <filename.tar.gz)\r\n\r\n"; \ cat filename.tar.gz; } | nc -l -p 15000
If all else fails, you can always use Telnet as follows:
# telnet remotehost.tld 15000
pushing Netcat aside for now.
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 a two-way pipe:
# mkfifo twowaypipe # nc -l 15015 0<twowaypipe | \ nc www.remotewebsite.tld 80 1>twowaypipe
I would suggest testing the way your version of Netcat and your browser react and practicing 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 in particular: Ncat.
The Ncat [2] version of Netcat offers a host of features, such as SSL capabilities, that make it worth a closer look. You can accomplish port forwarding with the -c
switch on the Ncat version of Netcat with the following 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 chatting exchange useful sometimes. On your first server, you open up a port:
# ncat -l 4444
On the other host, you 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 much as ping
might do), 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 following simple command:
# 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, 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 an outstanding tool; to my mind, it's the epitome of versatility. I've only touched on some of its functionality here, and it has much, much more to discover. I hope this article encourages you to learn more about this complex but intriguing network and filesystem tool.