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 an echo 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 of nc 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 Netcat

    Hello,
    This is a test from Netcat

    See 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 to nc.

    Use -p option to specify a source port. It is even possible to specify a range of port as in 80-1024 (both inclusive). If you omit the -p option, it will use a random port.

  • Emulate TCP Service

    Use the -l flag to instruct nc to stay in listen mode. Use the following to bind nc 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 runs nc 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 of nc provides built-in support for this functionality with -X and connect 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

One comment

[…] reports back the consensus,.. that doesn't exist AFAIK. Heres some great starter info on Netcat: http://anil.org.in/2009/05/26/netcat…ss-army-knife/ And some on dsnmasq: […]

by Bash script that acts as a DNS proxy, except it queries several DNS servers on March 6, 2014 at 2:36 am. #

Leave your comment

Required.

Required. Not published.

If you have one.