netcat Explained: Testing Ports, Moving Files, and Debugging Protocols

netcat Explained: Testing Ports, Moving Files, and Debugging Protocols

netcat does one thing: it reads and writes data over network connections. That sounds too simple to be useful and turns out to cover an enormous amount of everyday debugging.

Which netcat

There are several implementations with incompatible flags, which is the main source of confusion.

  • OpenBSD netcat, the default on Debian and Ubuntu, and the one most examples assume
  • GNU netcat, older, different options
  • Ncat, from the nmap project, with TLS support and more features
nc -h 2>&1 | head -3

The most consequential difference is -N, which the OpenBSD version needs to close the connection after input ends. Without it, transfers hang.

Is this port open

nc -zv example.com 443           # scan one port, verbose, no data
nc -zv example.com 20-25         # a small range
nc -zv -w 3 example.com 22       # with a 3 second timeout
nc -zvu example.com 53           # UDP

-z means scan without sending data. -v prints the result. Always add -w in scripts, or a filtered port will hang until the TCP timeout.

For more than a handful of ports, use nmap instead. netcat is for the quick check.

UDP scanning is inherently unreliable, because a UDP service that does not reply is indistinguishable from a dropped packet. A UDP “open” result from netcat means very little on its own.

Talking to a service by hand

This is where netcat earns its reputation.

nc example.com 80

Then type:

GET / HTTP/1.1
Host: example.com
Connection: close

The blank line matters. You get the raw HTTP response including headers, with no client interpreting anything for you.

Same for SMTP:

nc mail.example.com 25
EHLO test.example.com
QUIT

The banner and capability list tell you whether the server is reachable, what it advertises, and whether STARTTLS is offered, in about ten seconds. This is far faster than configuring a mail client to find out.

For TLS-wrapped protocols netcat cannot help, because it does not speak TLS. Use openssl instead:

openssl s_client -connect example.com:443
openssl s_client -starttls smtp -connect mail.example.com:587

Listening

nc -l 8080                       # listen on 8080
nc -lk 8080                      # keep listening after a client disconnects

Useful for confirming that traffic reaches a machine at all. Start a listener, connect from elsewhere, and see whether anything arrives. If it does not, the problem is between the two, and firewall rules are the first suspect.

To see exactly what a client sends:

nc -lk 8080 | tee capture.txt

Point a misbehaving webhook or client at it and read the raw request. This answers “what is that thing actually sending” definitively, which no amount of reading its documentation will.

Moving a file quickly

On the receiving machine:

nc -l 9000 > received.tar.gz

On the sender:

nc -N receiver.local 9000 < archive.tar.gz

-N closes the connection when input ends. Without it both sides wait forever, which is the most commonly reported netcat problem.

There is no encryption, no authentication, and no integrity check, so this is for a trusted local network and nothing else. Verify afterwards:

sha256sum archive.tar.gz     # on both ends

For anything crossing an untrusted network, use rsync over SSH.

A throwaway web server

while true; do
  printf 'HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok' | nc -l 8080
done

Handy for testing a load balancer health check or confirming a firewall rule without deploying anything real.

Piping through it

Because netcat is a normal filter, it composes:

# Send a whole directory
tar czf - /data | nc -N receiver 9000
nc -l 9000 | tar xzf -          # on the receiver

# Stream a database dump
pg_dump mydb | nc -N backup-host 9000

Again, plaintext. Fine inside a rack, wrong across the internet.

The security note

netcat is a favourite tool for reverse shells and data exfiltration, precisely because it is small, general, and often already installed.

That does not make the tool bad, but it does mean two things. Finding netcat running on a production server you did not put it on is worth investigating. And many hardened base images remove it deliberately, so scripts that assume it is present will fail.

Frequently Asked Questions

What is netcat used for?

Opening raw TCP or UDP connections from the command line. That covers testing whether a port is reachable, talking to a text protocol by hand, transferring a file between two machines quickly, and listening on a port to see what connects.

Which version of netcat do I have?

Usually OpenBSD netcat on Debian and Ubuntu, or the GNU version elsewhere, and the flags differ. Run nc -h and look at the options. The OpenBSD version wants -N to close on end of input, which the traditional version does not have.

Is netcat a security risk?

The tool is neutral, but it is genuinely useful to attackers for reverse shells and data exfiltration, which is why finding it unexpectedly on a production server is worth investigating. Many hardened images remove it for that reason.

How is netcat different from telnet for testing ports?

netcat handles binary data cleanly, supports UDP, can listen as well as connect, and exits sensibly in scripts. telnet works for quick text protocol checks and mangles anything binary because it interprets certain byte sequences as commands.

Why does my netcat file transfer hang at the end?

The sending side has finished but the connection stays open. Use -N on the sender with OpenBSD netcat, which shuts down the socket after end of input. Without it both sides wait indefinitely for data that is not coming.

Should I use netcat or nmap for port scanning?

nmap for anything beyond a couple of ports, since it is faster, does service detection, and was built for the job. netcat is fine for checking one or two ports quickly when nmap is not installed, using nc -zv.