NC(1)

๐Ÿ’– NC(1) โ€” General Commands Manual ๐Ÿ’–

okay bestie, this is the General Commands Manual entry for nc (section 1) and it's literally iconic ๐Ÿ’…โœจ


๐ŸŽ€ NAME ๐ŸŽ€

nc โ€” arbitrary TCP and UDP connections and listens ๐Ÿฆ‹

๐ŸŒธ SYNOPSIS ๐ŸŒธ

nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
   [-m minttl] [-O length] [-P proxy_username] [-p source_port]
   [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit]
   [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]]
   [destination] [port]

โœจ DESCRIPTION โœจ

okay so the nc (or netcat) utility is used for literally just about anything under the sun involving TCP, UDP, or Unix-domain sockets ๐Ÿ˜ญ it can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and handle both IPv4 and IPv6. the way that it scripts nicely? chef's kiss ๐Ÿ’‹ and unlike telnet(1), it sends its error messages to standard error instead of standard output, which telnet(1) does with some of them. no cap, that's a whole vibe ๐Ÿ™ˆ

common uses include:

  • simple TCP proxies ๐Ÿงš
  • shell-script based HTTP clients and servers ๐Ÿ’ป
  • network daemon testing ๐Ÿ”ฅ
  • a SOCKS or HTTP ProxyCommand for ssh(1) ๐Ÿซถ
  • and much, much more ๐Ÿ’…

๐Ÿ’œ The options are as follows ๐Ÿ’œ

  • -4 โ€” use IPv4 addresses only ๐ŸŒˆ
  • -6 โ€” use IPv6 addresses only ๐ŸŒˆ
  • -b โ€” allow broadcast ๐Ÿ“ฃ
  • -C โ€” send CRLF as the line-ending ๐ŸŽ€. every line feed (LF) character from the input data gets translated into CR+LF before it's written to the socket. line feeds that are already preceded by a carriage return (CR) are left alone, and received data is not affected at all
  • -D โ€” enable debugging on the socket ๐Ÿ”
  • -d โ€” do not attempt to read from stdin ๐Ÿ™…โ€โ™€๏ธ
  • -F โ€” pass the first connected socket using sendmsg(2) to stdout and exit ๐Ÿฆ‹. this is seriously useful alongside -X when you want nc to handle the proxy connection setup and then leave the rest of the connection to another program, like ssh(1) using the ssh_config(5) ProxyUseFdpass option. it can't be used with -U ๐Ÿšซ
  • -h โ€” print out the nc help text and exit ๐Ÿ“–
  • -I length โ€” specify the size of the TCP receive buffer ๐ŸŒŠ
  • -i interval โ€” sleep for interval seconds between lines of text sent and received โณ. this also adds a delay between connections to multiple ports
  • -k โ€” when a connection is completed, listen for another one ๐Ÿ”. it requires -l. when it's used together with the -u option, the server socket is not connected, so it can receive UDP datagrams from multiple hosts ๐Ÿ‘‘
  • -l โ€” listen for an incoming connection instead of initiating one to a remote host ๐Ÿ‘‚. the destination and port to listen on can be given as non-optional arguments, or with the -s and -p options respectively. it can't be used together with -x or -z โŒ. also, any timeouts set with -w get ignored
  • -M ttl โ€” set the TTL / hop limit of outgoing packets ๐Ÿ“ฆ
  • -m minttl โ€” ask the kernel to drop incoming packets whose TTL / hop limit is under minttl ๐Ÿ›ก๏ธ
  • -N โ€” shutdown(2) the network socket after EOF on the input ๐Ÿ”Œ. some servers need this to finish their work
  • -n โ€” do not perform domain name resolution ๐Ÿ™…. if a name can't be resolved without DNS, an error will be reported
  • -O length โ€” specify the size of the TCP send buffer ๐Ÿ“ค
  • -P proxy_username โ€” specify a username to present to a proxy server that requires authentication ๐Ÿ”‘. if no username is specified, authentication will not be attempted. right now, proxy authentication is only supported for HTTP CONNECT proxies
  • -p source_port โ€” specify the source port nc should use ๐Ÿšช, subject to privilege restrictions and availability
  • -q seconds โ€” after EOF on stdin, wait the specified number of seconds and then quit โฐ. if seconds is negative, it waits forever (that's the default ๐Ÿ’€). specifying a non-negative seconds implies -N
  • -r โ€” choose source and/or destination ports randomly ๐ŸŽฒ, instead of sequentially within a range or in the order the system assigns them
  • -S โ€” enable the RFC 2385 TCP MD5 signature option ๐Ÿ”
  • -s sourceaddr โ€” set the source address to send packets from ๐Ÿ“, which is useful on machines with multiple interfaces. for Unix-domain datagram sockets, it specifies the local temporary socket file to create and use so datagrams can be received. it can't be used together with -x ๐Ÿšซ
  • -T keyword โ€” change the IPv4 TOS / IPv6 traffic class value ๐ŸŽš๏ธ. keyword may be one of critical, inetcontrol, lowcost, lowdelay, netcontrol, throughput, reliability, or one of the DiffServ Code Points: ef, af11 ... af43, cs0 ... cs7; or a number in either hex or decimal ๐Ÿ”ข
  • -t โ€” send RFC 854 DON'T and WON'T responses to RFC 854 DO and WILL requests ๐Ÿงธ. this is what makes it possible to use nc to script telnet sessions
  • -U โ€” use Unix-domain sockets ๐Ÿงฆ. it can't be used together with -F or -x. on Linux, if the name starts with an at symbol (@), it's read as an abstract namespace socket: the leading @ gets replaced with a NUL byte before binding or connecting. for the details, check out unix(7) ๐Ÿ“š
  • -u โ€” use UDP instead of TCP ๐ŸŒธ. it can't be used together with -x. for Unix-domain sockets, it uses a datagram socket instead of a stream socket. if a Unix-domain socket is used, a temporary receiving socket is created in /tmp unless the -s flag is given
  • -V rtable โ€” set the routing table to be used ๐Ÿ—บ๏ธ
  • -v โ€” produce more verbose output ๐Ÿ“ข
  • -W recvlimit โ€” terminate after receiving recvlimit packets from the network ๐Ÿ›‘
  • -w timeout โ€” connections that can't be established, or that sit idle, time out after timeout seconds โŒ›. the -w flag has no effect on the -l option, i.e. nc will listen forever for a connection, with or without the -w flag ๐Ÿ‘€. the default is no timeout
  • -X proxy_protocol โ€” use proxy_protocol when talking to the proxy server ๐Ÿ›ฃ๏ธ. supported protocols are 4 (SOCKS v.4), 5 (SOCKS v.5), and connect (HTTPS proxy). if the protocol isn't specified, SOCKS version 5 is used
  • -x proxy_address[:port] โ€” connect to the destination using a proxy at proxy_address and port ๐Ÿช„. if port isn't specified, the well-known port for the proxy protocol is used (1080 for SOCKS, 3128 for HTTPS). an IPv6 address can be specified unambiguously by enclosing proxy_address in square brackets. a proxy can't be used with any of the options -lsuU ๐Ÿ™…โ€โ™€๏ธ
  • -Z โ€” DCCP mode ๐ŸŒ€
  • -z โ€” only scan for listening daemons, without sending any data to them ๐Ÿ”Ž. it can't be used together with -l

destination can be a numerical IP address or a symbolic hostname (unless the -n option is given) ๐Ÿ . in general, a destination must be specified, unless the -l option is given (in which case the local host is used). for Unix-domain sockets, a destination is required and it's the socket path to connect to (or to listen on if the -l option is given) ๐Ÿงญ

port can be specified as a numeric port number or as a service name ๐Ÿ”ข. port ranges may be specified as numeric port numbers of the form nn-mm. in general, a destination port must be specified, unless the -U option is given. for some options, the value 0 requests that the system choose a port number ๐ŸŽฐ

more to come, bestie! ๐Ÿซถ

โœจ TALKING TO SERVERS โœจ

okay so sometimes it's lowkey iconic to talk to servers "by hand" instead of clicking through a fancy UI ๐Ÿ’… it's super helpful for troubleshooting, especially when you need to check exactly what data a server is sending back for the commands your client sent. like, want to grab the home page of a website? just do:

$ printf "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80

heads up, this also shows the headers the web server sends back ๐Ÿ™ˆ if they're in your way, you can filter them with a tool like sed(1) ๐Ÿฆ‹

once you know what format a server wants, you can build up way more complicated stuff. for example, you can submit an email to an SMTP server like this ๐Ÿ’Œ

$ nc [-C] localhost 25 << EOF
HELO host.example.com
MAIL FROM:<user@host.example.com>
RCPT TO:<user2@host.example.com>
DATA
Body of email.
.
QUIT
EOF

๐Ÿ” PORT SCANNING ๐Ÿ”

it can be super useful to know which ports are open and which ones have services running on a target machine โœจ the -z flag tells nc to just report open ports instead of starting a connection. it's usually a good idea to pair it with -v so you get verbose output on stderr ๐Ÿงš

for example:

$ nc -zv host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded!
Connection to host.example.com 25 port [tcp/smtp] succeeded!

the port range limits the search to ports 20 through 30, and they get scanned in increasing order (unless you set the -r flag) ๐ŸŒธ

you can also hand it a list of ports to scan, like so:

$ nc -zv host.example.com http 20 22-23
nc: connect to host.example.com 80 (tcp) failed: Connection refused
nc: connect to host.example.com 20 (tcp) failed: Connection refused
Connection to host.example.com port [tcp/ssh] succeeded!
nc: connect to host.example.com 23 (tcp) failed: Connection refused

the ports get scanned in the order you typed them in (unless -r is set) ๐Ÿ’œ

also, sometimes you wanna know what server software is running and which versions, and that info is often hiding in the greeting banners ๐Ÿ‘€ to grab those, nc has to make a connection first, then break it once the banner shows up. you can do that with a small timeout using the -w flag, or by sending a "QUIT" command to the server. no cap, both are very slay ๐Ÿ’…

$ echo "QUIT" | nc host.example.com 20-30
SSH-1.99-OpenSSH_3.6.1p2
Protocol mismatch.
220 host.example.com IMS SMTP Receiver Version 0.84 Ready

๐ŸŽ€ EXAMPLES ๐ŸŽ€

okay here are some looks you can copy ๐Ÿซถ

Open a TCP connection to port 42 of host.example.com, using port 31337 as the source port, with a timeout of 5 seconds โฑ๏ธ

$ nc -p 31337 -w 5 host.example.com 42

Open a UDP connection to port 53 of host.example.com ๐ŸŒˆ

$ nc -u host.example.com 53

Open a TCP connection to port 42 of host.example.com using 10.1.2.3 as the IP for the local end of the connection ๐Ÿฆ‹

$ nc -s 10.1.2.3 host.example.com 42

Create and listen on a Unix-domain stream socket ๐Ÿงš

$ nc -lU /var/tmp/dsocket

Connect to port 42 of host.example.com via an HTTP proxy at 10.2.3.4, port 8080. this one could also be used by ssh(1), so check out the ProxyCommand directive in ssh_config(5) for more info โœจ

$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42

same thing again, but this time with proxy authentication enabled, using the username "ruser" in case the proxy asks for it ๐Ÿ”

$ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42

๐Ÿ’– SEE ALSO ๐Ÿ’–

cat(1), ssh(1)

๐Ÿซถ AUTHORS ๐Ÿซถ

Original implementation by Hobbit <hobbit@avian.org>. Rewritten with IPv6 support by Eric Jackson <ericj@monkey.org>. Modified for Debian port by Aron Xu โŸจaron@debian.orgโŸฉ ๐ŸŒธ

โš ๏ธ CAVEATS โš ๏ธ

not me being dramatic but UDP port scans using the -uz combo will ALWAYS report success, no matter what state the target machine is in ๐Ÿ’€

however, if you pair it with a traffic sniffer on the target machine or some middle device, -uz can actually be useful for communications diagnostics ๐Ÿ” just keep in mind the amount of UDP traffic generated might be limited by hardware resources and/or configuration settings ๐Ÿ™ˆ


bestie, that's the whole page and you're officially a netcat main character now ๐ŸŽ€๐Ÿ’– this was a Debian thing, April 1, 2024, NC(1) ๐Ÿงšโœจ stay iconic ๐Ÿ˜ญ๐Ÿ’…

๐Ÿ“ฆ where this page comes from