Netcat (nc): “TCP/IP Swiss Army Knife”
by anil on May 26, 2009
Many of us use telnet
as a network debugging tool quite often. Just with its hostname
and port
options we find it very useful. But, I’m sure that many would recall following situations where we find the telnet
client inadequate:
- To test a UDP service
- Want to send a pre-prepared set of request/responses to a server (to test a service)
- Specify a Gateway for the TCP or UDP connection (checking routing and firewalling)
- Receive and store dump of the traffic (network and application troubleshooting)
- Send a UDP broadcast over the subnet (Network and application testing)
- To set the ToS (type of service) flag in IP packet (to test QoS settings)
- To copy a file over network without any regular services running
- Do a port scan (without opening I/O)
- Mimic the request/response sequence of a service/client you want to test
There is a less-known tool called nc
–acronym for Netcat–which was ranked 4th in the latest Top 100 Network Security Tools 2006 conducted by Insecure.org
and always in the top 5 in previous years as well.
nc
can perform all the above and more. As it is rightly assigned with the caption of “TCP/IP swiss army knife.” Here is a quick set of commands to use nc
for the use of a network administrator/troubleshooter.
Please note that Linux and BSD ports of nc
differs in behaviour and syntax. This post is mostly based on the Linux port. I have tried to mention the difference where ever possible.
- Test a TCP Service:
nc <hostname> <port number>
e.g.:nc www.google.com 80
If you need to run a shell command after the TCP connection is established, use the “-c” option.
nc -c wwwclient www.google.com 80
There is an important behaviour you need to notice while using -c and -e (invokes a script) options: the called command is supposed to handle both input and output of
nc
. This means that while passing anecho
command, for example, with -c option, you cannot expect nc to print the response to standard out. For example, the following command writes nothing to standard out:nc -c “echo GET / HTTP/1.0” www.google.com 80
This is because nc pipes the HTTP response from www.google.com to
echo
. The -e option has the same behaviour. In the BSD port ofnc
there is no-c
option available. And the-e
has a very different meaning.If you want to make a request to a server in two or more lines (as in the case of, say, HTTP protocol), write them down in a file and cat-pipe that file to NC. For example if you want to find the public IP address of your Internet gateway, create a text file http.txt with the following content:
<code>
GET /ip HTTP/1.0
Host: www.linuxense.com</code>
Now issue this command:cat http.txt|nc www.linuxense.com 80
In certain protocols, such as SMTP, it needs to wait for the server to make a response before nc sends the next request. In such situation the -i option comes handy; it waits for the specified number of seconds before it sends the next line.
Now try this SMTP transaction. Save the following in to a file named, say, smtp.txt
<code>
helo greetings
mail from: <me@myhost>
rcpt to: <you@yourhost>
data
Subject: test from NetcatHello,
This is a test from NetcatSee ya!
~me
.
</code>
Now play out this transaction:
cat smtp.txt | nc -i 2 your_smtp_server 25
See the
-i
in action.There is a
-n
option that disables any DNS look up. This is useful if you are providing the IP address of the host and to explicitly say so tonc
.Use
-p
option to specify a source port. It is even possible to specify a range of port as in80-1024
(both inclusive). If you omit the-p
option, it will use a random port. - Emulate TCP Service
Use the
-l
flag to instructnc
to stay in listen mode. Use the following to bindnc
to port 8000:nc -l 8000
Normally
nc
quits when the remote connection closes. To make it stay listening for another connection, use-k
(found to work only in BSD port).Here
-p
option to specify the port it is listening to is allowed in Linux. In the BSD port, this is illegal. - Emulate a UDP Service
Use the
-u
option,nc
will turn the protocol to UDP. Almost all options which are valid for TCP mode (default mode) are valid with this option too.Emulate a DNS service:
nc -u -l -p 53
(note that all parameters are similar to those in TCP mode. The option-u
makes all the difference).Here, the
-p
is a required option in Linux where us in BSD it is not permitted.Now, run a dig command at it:
dig @localhost www.linuxense.com
You will see a partially readable line being printed on the console and this is how a DNS query looks like. Capture this into a file:
nc -u -i -p 53 > dns-query.txt
And playback it at a functional DNS server and see the output:
cat dns-query.txt |nc -u mydnsserver 53
-
Specifying Source IP Address:
If you are on your gateway and you want to specify the source IP address of packets leaving the gateway, use the
-s
option. For example:nc -s 192.168.1.1 remotehost 80
- Run a Zero I/O Port Scan
See this example:
nc -z -v remotehost 80
The
-z
runsnc
in zero I/O scan mode.-v
option is to turn on the verbose mode.It is also possible to specify a range of IP addresses as follows (both IP addresses are inclusive):
nc -zv remotehost 80-1024
- Set "Type of Service" (ToS) Flag
The flag
-x
allows to set the IP ToS flag. Possible values are "Minimize-Delay", "Maximize-Throughput", Maximize-Reliability", "Minimize-Cost". - Set Up a Service Gateway/Proxy
This is a quick and trivial service gateway you can try out in a few seconds. You device more sophisticated gateways with
nc
. BSD port ofnc
provides built-in support for this functionality with-X
andconnect
verb.
If you enjoy reading this post and liked nc
, please post here the nc
tricks and hacks you invent.
--
Related post:
Learn IP Networking
Further reading:
BSD nc man page
GNU Netcat official homepage