Netcat Cheatsheet
Banner Grabbing
Use this Netcat reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Services that announce themselves
Some protocols send a greeting the moment you connect, so connecting is the whole probe. No input needed.
nc -v -w 3 10.0.0.5 22 # SSH version string nc -v -w 3 mail.example.com 25 # SMTP 220 greeting nc -v -w 3 10.0.0.5 21 # FTP 220 nc -v -w 3 10.0.0.5 110 # POP3 +OK nc -v -w 3 10.0.0.5 143 # IMAP * OK
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
| Port | Service | Greeting starts with |
|---|---|---|
| 21 | FTP | 220 |
| 22 | SSH | SSH-2.0- |
| 23 | Telnet | Negotiation bytes, use -t |
| 25 / 587 | SMTP | 220 |
| 110 | POP3 | +OK |
| 143 | IMAP | * OK |
| 3306 | MySQL | Binary, version string is readable inside |
| 5432 | Postgres | Silent, needs a startup packet |
| 6379 | Redis | Silent, send PING |
| 11211 | Memcached | Silent, send stats |
-w is essential here. Without it, a service that greets you and then
waits keeps netcat open indefinitely, and your script hangs.
Services that need a prompt
The rest say nothing until you speak first.
# HTTP printf 'HEAD / HTTP/1.0\r\n\r\n' | nc -w 3 example.com 80 # HTTP/1.1 with a Host header, needed for virtual hosts printf 'HEAD / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' \ | nc -w 3 example.com 80 # Redis printf 'PING\r\n' | nc -w 2 10.0.0.5 6379 # Redis version and config, if unauthenticated printf 'INFO server\r\n' | nc -w 2 10.0.0.5 6379 # Memcached printf 'stats\r\n' | nc -w 2 10.0.0.5 11211 # Whois echo "example.com" | nc -w 5 whois.verisign-grs.com 43
HEAD rather than GET keeps the response to headers only, which is all a
banner grab needs.
TLS ports need TLS
Plain netcat against 443 fails, because your cleartext is not a ClientHello. The server either closes the connection or returns a handshake error.
# This does NOT work printf 'HEAD / HTTP/1.0\r\n\r\n' | nc example.com 443 # Ncat wraps the connection in TLS printf 'HEAD / HTTP/1.0\r\n\r\n' | ncat --ssl -w 3 example.com 443 # openssl s_client, available almost everywhere printf 'HEAD / HTTP/1.0\r\n\r\n' | \ openssl s_client -quiet -connect example.com:443 -servername example.com # Certificate details only openssl s_client -connect example.com:443 -servername example.com \ </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates # STARTTLS on SMTP, which begins in cleartext openssl s_client -starttls smtp -connect mail.example.com:587
-servername sends SNI, which almost every modern host requires. Without
it you get the default virtual host's certificate, or a handshake failure.
| Port | Wrapper |
|---|---|
| 443 | ncat --ssl or openssl s_client |
| 465 | openssl s_client -connect host:465 |
| 587 | openssl s_client -starttls smtp |
| 993 | openssl s_client -connect host:993 |
| 995 | openssl s_client -connect host:995 |
| 636 | openssl s_client -connect host:636 |
| 5432 | openssl s_client -starttls postgres |
Telnet negotiation
A real telnet server opens with IAC negotiation bytes (0xff …), which
print as garbage and can confuse your terminal.
# Answer the negotiation so the session is usable nc -t 10.0.0.5 23 # See the raw bytes instead nc -w 2 10.0.0.5 23 | xxd | head
GNU netcat spells this -T, not -t. netcat-traditional uses -t.
Scripting a sweep
# Grab whatever the port volunteers, across a list for p in 21 22 25 110 143 3306 6379; do echo "=== $p ===" nc -w 2 -v 10.0.0.5 "$p" </dev/null 2>&1 | head -3 done # HTTP server headers across a subnet for h in 10.0.0.{1..254}; do b=$(printf 'HEAD / HTTP/1.0\r\n\r\n' | nc -w 1 "$h" 80 2>/dev/null | \ grep -i '^server:') [ -n "$b" ] && echo "$h $b" done # Parallel version printf '10.0.0.%s\n' {1..254} | xargs -P 40 -I{} sh -c \ 'printf "HEAD / HTTP/1.0\r\n\r\n" | nc -w 1 {} 80 2>/dev/null | \ grep -i "^server:" | sed "s|^|{} |"'
</dev/null on the client matters. Without it netcat inherits the loop's
stdin and swallows the rest of your input, which makes the loop behave
bizarrely.
Better tools for the same job
netcat grabs a banner. Dedicated tools identify the service.
| Need | Command |
|---|---|
| Banner from one port | nc -w 3 -v host port |
| Service and version, many ports | nmap -sV -p 22,80,443 host |
| Full HTTP inspection | curl -sSv -o /dev/null https://host |
| Headers only | curl -sSI https://host |
| TLS configuration audit | nmap --script ssl-enum-ciphers -p 443 host |
| Certificate chain | openssl s_client -showcerts -connect host:443 |
| HTTP over TLS by hand | ncat --ssl host 443 |
# curl beats netcat for anything HTTP, and follows redirects curl -sSI -L https://example.com | grep -iE '^(HTTP|server|location):'
Banner grabbing is a connection to a service you do not control. Do it only against hosts you own or are authorized to test.