Netcat is a simple Unix utility which reads and writes data across network connections, using TCP or UDP protocol. It is designed to be a reliable "back-end" tool that can be used directly or easily driven by other programs and scripts. At the same time, it is a feature-rich network debugging and exploration tool, since it can create almost any kind of connection you would need and has several interesting built-in capabilities. Netcat, or "nc" as the actual program is named, should have been supplied long ago as another one of those cryptic but standard Unix tools. |
/\_/\
/ 0 0 \
====v====
\ W /
| | _
/ ___ \ /
/ / \ \ |
(((-----)))-'
/
( ___
\__.=|___E
/
|
||
In the simplest usage, "nc host port" creates a TCP connection to the given
port on the given target host. Your standard input is then sent to the host,
and anything that comes back across the connection is sent to your standard
output. This continues indefinitely, until the network side of the connection
shuts down. Note that this behavior is different from most other applications
which shut everything down and exit after an end-of-file on the standard input.
Netcat can also function as a server, by listening for inbound connections
on arbitrary ports and then doing the same reading and writing. With minor
limitations, netcat doesn't really care if it runs in "client" or "server"
mode -- it still shovels data back and forth until there isn't any more left.
In either mode, shutdown can be forced after a configurable time of inactivity
on the network side.
And it can do this via UDP too, so netcat is possibly the "udp telnet-like" application you always wanted for testing your UDP-mode servers. UDP, as the "U" implies, gives less reliable data transmission than TCP connections and some systems may have trouble sending large amounts of data that way, but it's still a useful capability to have. You may be asking "why not just use telnet to connect to arbitrary ports?" Valid question, and here are some reasons. Telnet has the "standard input EOF" problem, so one must introduce calculated delays in driving scripts to allow network output to finish. This is the main reason netcat stays running until the *network* side closes. Telnet also will not transfer arbitrary binary data, because certain characters are interpreted as telnet options and are thus removed from the data stream. Telnet also emits some of its diagnostic messages to standard output, where netcat keeps such things religiously separated from its *output* and will never modify any of the real data in transit unless you *really* want it to. And of course telnet is incapable of listening for inbound connections, or using UDP instead. Netcat doesn't have any of these limitations, is much smaller and faster than telnet, and has many other advantages. Some of netcat's major features are:
Netcat is entirely my own creation, although plenty of other code was used as examples. It is freely given away to the Internet community in the hope that it will be useful, with no restrictions except giving credit where it is due. No GPLs, Berkeley copyrights or any of that nonsense. The author assumes NO responsibility for how anyone uses it. If netcat makes you rich somehow and you're feeling generous, mail me a check. If you are affiliated in any way with Microsoft Network, get a life. Always ski in control. Comments, questions, and patches to hobbit@avian.org. Building Compiling is fairly straightforward. Examine the Makefile for a SYSTYPE that matches yours, and do "make ". The executable "nc" should appear. If there is no relevant SYSTYPE section, try "generic". If you create new sections for generic.h and Makefile to support another platform, please follow the given format and mail back the diffs. There are a couple of other settable #defines in netcat.c, which you can include as DFLAGS="-DTHIS -DTHAT" to your "make" invocation without having to edit the Makefile. See the following discussions for what they are and do. If you want to link against the resolver library on SunOS [recommended] and you have BIND 4.9.x, you may need to change XLIBS=-lresolv in the Makefile to XLIBS="-lresolv -l44bsd". Linux sys/time.h does not really support presetting of FD_SETSIZE; a harmless warning is issued. Some systems may warn about pointer types for signal(). No problem, though. Exploration of features Where to begin? Netcat is at the same time so simple and versatile, it's like trying to describe everything you can do with your Swiss Army knife. This will go over the basics; you should also read the usage examples and notes later on which may give you even more ideas about what this sort of tool is good for. If no command arguments are given at all, netcat asks for them, reads a line from standard input, and breaks it up into arguments internally. This can be useful when driving netcat from certain types of scripts, with the side effect of hiding your command line arguments from "ps" displays. The host argument can be a name or IP address. If -n is specified, netcat will only accept numeric IP addresses and do no DNS lookups for anything. If -n is not given and -v is turned on, netcat will do a full forward and reverse name and address lookup for the host, and warn you about the all-too-common problem of mismatched names in the DNS. This often takes a little longer for connection setup, but is useful to know about. There are circumstances under which this can *save* time, such as when you want to know the name for some IP address and also connect there. Netcat will just tell you all about it, saving the manual steps of looking up the hostname yourself. Normally mismatch- checking is case-insensitive per the DNS spec, but you can define ANAL at compile time to make it case-sensitive -- sometimes useful for uncovering minor errors in your own DNS files while poking around your networks. A port argument is required for outbound connections, and can be numeric or a name as listed in /etc/services. If -n is specified, only numeric arguments are valid. Special syntax and/or more than one port argument cause different behavior -- see details below about port-scanning. The -v switch controls the verbosity level of messages sent to standard error. You will probably want to run netcat most of the time with -v turned on, so you can see info about the connections it is trying to make. You will probably also want to give a smallish -w argument, which limits the time spent trying to make a connection. I usually alias "nc" to "nc -v -w 3", which makes it function just about the same for things I would otherwise use telnet to do. The timeout is easily changed by a subsequent -w argument which overrides the earlier one. Specifying -v more than once makes diagnostic output MORE verbose. If -v is not specified at all, netcat silently does its work unless some error happens, whereupon it describes the error and exits with a nonzero status. Refused network connections are generally NOT considered to be errors, unless you only asked for a single TCP port and it was refused. Note that -w also sets the network inactivity timeout. This does not have any effect until standard input closes, but then if nothing further arrives from the network in the next seconds, netcat tries to read the net once more for good measure, and then closes and exits. There are a lot of network services now that accept a small amount of input and return a large amount of output, such as Gopher and Web servers, which is the main reason netcat was written to "block" on the network staying open rather than standard input. Handling the timeout this way gives uniform behavior with network servers that *don't* close by themselves until told to. UDP connections are opened instead of TCP when -u is specified. These aren't really "connections" per se since UDP is a connectionless protocol, although netcat does internally use the "connected UDP socket" mechanism that most kernels support. Although netcat claims that an outgoing UDP connection is "open" immediately, no data is sent until something is read from standard input. Only thereafter is it possible to determine whether there really is a UDP server on the other end, and often you just can't tell. Most UDP protocols use timeouts and retries to do their thing and in many cases won't bother answering at all, so you should specify a timeout and hope for the best. You will get more out of UDP connections if standard input is fed from a source of data that looks like various kinds of server requests. To obtain a hex dump file of the data sent either way, use "-o logfile". The dump lines begin with "<" or ">" to respectively indicate "from the net" or "to the net", and contain the total count per direction, and hex and ascii representations of the traffic. Capturing a hex dump naturally slows netcat down a bit, so don't use it where speed is critical. Netcat can bind to any local port, subject to privilege restrictions and ports that are already in use. It is also possible to use a specific local network source address if it is that of a network interface on your machine. [Note: this does not work correctly on all platforms.] Use "-p portarg" to grab a specific local port, and "-s ip-addr" or "-s name" to have that be your source IP address. This is often referred to as "anchoring the socket". Root users can grab any unused source port including the "reserved" ones less than 1024. Absence of -p will bind to whatever unused port the system gives you, just like any other normal client connection, unless you use -r [see below]. Listen mode will cause netcat to wait for an inbound connection, and then the same data transfer happens. Thus, you can do "nc -l -p 1234 < filename" and when someone else connects to your port 1234, the file is sent to them whether they wanted it or not. Listen mode is generally used along with a local port argument -- this is required for UDP mode, while TCP mode can have the system assign one and tell you what it is if -v is turned on. If you specify a target host and optional port in listen mode, netcat will accept an inbound connection only from that host and if you specify one, only from that foreign source port. In verbose mode you'll be informed about the inbound connection, including what address and port it came from, and since listening on "any" applies to several possibilities, which address it came *to* on your end. If the system supports IP socket options, netcat will attempt to retrieve any such options from an inbound connection and print them out in hex. If netcat is compiled with -DGAPING_SECURITY_HOLE, the -e argument specifies a program to exec after making or receiving a successful connection. In the listening mode, this works similarly to "inetd" but only for a single instance. Use with GREAT CARE. This piece of the code is normally not enabled; if you know what you're doing, have fun. This hack also works in UDP mode. Note that you can only supply -e with the name of the program, but no arguments. If you want to launch something with an argument list, write a two-line wrapper script or just use inetd like always. If netcat is compiled with -DTELNET, the -t argument enables it to respond to telnet option negotiation [always in the negative, i.e. DONT or WONT]. This allows it to connect to a telnetd and get past the initial negotiation far enough to get a login prompt from the server. Since this feature has the potential to modify the data stream, it is not enabled by default. You have to understand why you might need this and turn on the #define yourself. Data from the network connection is always delivered to standard output as efficiently as possible, using large 8K reads and writes. Standard input is normally sent to the net the same way, but the -i switch specifies an "interval time" which slows this down considerably. Standard input is still read in large batches, but netcat then tries to find where line breaks exist and sends one line every interval time. Note that if standard input is a terminal, data is already read line by line, so unless you make the -i interval rather long, what you type will go out at a fairly normal rate. -i is really designed for use when you want to "measure out" what is read from files or pipes. Port-scanning is a popular method for exploring what's out there. Netcat accepts its commands with options first, then the target host, and everything thereafter is interpreted as port names or numbers, or ranges of ports in M-N syntax. CAVEAT: some port names in /etc/services contain hyphens -- netcat currently will not correctly parse those, so specify ranges using numbers if you can. If more than one port is thus specified, netcat connects to *all* of them, sending the same batch of data from standard input [up to 8K worth] to each one that is successfully connected to. Specifying multiple ports also suppresses diagnostic messages about refused connections, unless -v is specified twice for "more verbosity". This way you normally get notified only about genuinely open connections. Example: "nc -v -w 2 -z target 20-30" will try connecting to every port between 20 and 30 [inclusive] at the target, and will likely inform you about an FTP server, telnet server, and mailer along the way. The -z switch prevents sending any data to a TCP connection and very limited probe data to a UDP connection, and is thus useful as a fast scanning mode just to see what ports the target is listening on. To limit scanning speed if desired, -i will insert a delay between each port probe. There are some pitfalls with regard to UDP scanning, described later, but in general it works well. For each range of ports specified, scanning is normally done downward within that range. If the -r switch is used, scanning hops randomly around within that range and reports open ports as it finds them. [If you want them listed in order regardless, pipe standard error through "sort"...] In addition, if random mode is in effect, the local source ports are also randomized. This prevents netcat from exhibiting any kind of regular pattern in its scanning. You can exert fairly fine control over your scan by judicious use of -r and selected port ranges to cover. If you use -r for a single connection, the source port will have a random value above 8192, rather than the next one the kernel would have assigned you. Note that selecting a specific local port with -p overrides any local-port randomization. Many people are interested in testing network connectivity using IP source routing, even if it's only to make sure their own firewalls are blocking source-routed packets. On systems that support it, the -g switch can be used multiple times [up to 8] to construct a loose-source-routed path for your connection, and the -G argument positions the "hop pointer" within the list. If your network allows source-routed traffic in and out, you can test connectivity to your own services via remote points in the internet. Note that although newer BSD-flavor telnets also have source-routing capability, it isn't clearly documented and the command syntax is somewhat clumsy. Netcat's handling of "-g" is modeled after "traceroute". Netcat tries its best to behave just like "cat". It currently does nothing to terminal input modes, and does no end-of-line conversion. Standard input from a terminal is read line by line with normal editing characters in effect. You can freely suspend out of an interactive connection and resume. ^C or whatever your interrupt character is will make netcat close the network connection and exit. A switch to place the terminal in raw mode has been considered, but so far has not been necessary. You can send raw binary data by reading it out of a file or piping from another program, so more meaningful effort would be spent writing an appropriate front-end driver. Netcat is not an "arbitrary packet generator", but the ability to talk to raw sockets and/or nit/bpf/dlpi may appear at some point. Such things are clearly useful; I refer you to Darren Reed's excellent ip_filter package, which now includes a tool to construct and send raw packets with any contents you want. Example uses -- the light side Again, this is a very partial list of possibilities, but it may get you to think up more applications for netcat. Driving netcat with simple shell or expect scripts is an easy and flexible way to do fairly complex tasks, especially if you're not into coding network tools in C. My coding isn't particularly strong either [although undoubtedly better after writing this thing!], so I tend to construct bare-metal tools like this that I can trivially plug into other applications. Netcat doubles as a teaching tool -- one can learn a great deal about more complex network protocols by trying to simulate them through raw connections! An example of netcat as a backend for something else is the shell-script Web browser, which simply asks for the relevant parts of a URL and pipes "GET /what/ever" into a netcat connection to the server. I used to do this with telnet, and had to use calculated sleep times and other stupidity to kludge around telnet's limitations. Netcat guarantees that I get the whole page, and since it transfers all the data unmodified, I can even pull down binary image files and display them elsewhere later. Some folks may find the idea of a shell-script web browser silly and strange, but it starts up and gets me my info a hell of a lot faster than a GUI browser and doesn't hide any contents of links and forms and such. This is included, as scripts/web, along with several other web-related examples. Netcat is an obvious replacement for telnet as a tool for talking to daemons. For example, it is easier to type "nc host 25", talk to someone's mailer, and just ^C out than having to type ^]c or QUIT as telnet would require you to do. You can quickly catalog the services on your network by telling netcat to connect to well-known services and collect greetings, or at least scan for open ports. You'll probably want to collect netcat's diagnostic messages in your output files, so be sure to include standard error in the output using `>& file' in *csh or `> file 2>&1' in bourne shell. A scanning example: "echo QUIT | nc -v -w 5 target 20-250 500-600 5990-7000" will inform you about a target's various well-known TCP servers, including r-services, X, IRC, and maybe a few you didn't expect. Sending in QUIT and using the timeout will almost guarantee that you see some kind of greeting or error from each service, which usually indicates what it is and what version. [Beware of the "chargen" port, though...] SATAN uses exactly this technique to collect host information, and indeed some of the ideas herein were taken from the SATAN backend tools. If you script this up to try every host in your subnet space and just let it run, you will not only see all the services, you'll find out about hosts that aren't correctly listed in your DNS. Then you can compare new snapshots against old snapshots to see changes. For going after particular services, a more intrusive example is in scripts/probe. Netcat can be used as a simple data transfer agent, and it doesn't really matter which end is the listener and which end is the client -- input at one side arrives at the other side as output. It is helpful to start the listener at the receiving side with no timeout specified, and then give the sending side a small timeout. That way the listener stays listening until you contact it, and after data stops flowing the client will time out, shut down, and take the listener with it. Unless the intervening network is fraught with problems, this should be completely reliable, and you can always increase the timeout. A typical example of something "rsh" is often used for: on one side, nc -l -p 1234 | uncompress -c | tar xvfp -
and then on the other side
tar cfp - /some/dir | compress -c | nc -w 3 othermachine 1234
will transfer the contents of a directory from one machine to another, without
having to worry about .rhosts files, user accounts, or inetd configurations
at either end. Again, it matters not which is the listener or receiver; the
"tarring" machine could just as easily be running the listener instead. One
could conceivably use a scheme like this for backups, by having cron-jobs fire
up listeners and backup handlers [which can be restricted to specific addresses
and ports between each other] and pipe "dump" or "tar" on one machine to "dd
of=/dev/tapedrive" on another as usual. Since netcat returns a nonzero exit
status for a denied listener connection, scripts to handle such tasks could
easily log and reject connect attempts from third parties, and then retry.
Another simple data-transfer example: shipping things to a PC that doesn't have
any network applications yet except a TCP stack and a web browser. Point the
browser at an arbitrary port on a Unix server by telling it to download
something like http://unixbox:4444/foo, and have a listener on the Unix side
ready to ship out a file when the connect comes in. The browser may pervert
binary data when told to save the URL, but you can dig the raw data out of
the on-disk cache.
If you build netcat with GAPING_SECURITY_HOLE defined, you can use it as an "inetd" substitute to test experimental network servers that would otherwise run under "inetd". A script or program will have its input and output hooked to the network the same way, perhaps sans some fancier signal handling. Given that most network services do not bind to a particular local address, whether they are under "inetd" or not, it is possible for netcat avoid the "address already in use" error by binding to a specific address. This lets you [as root, for low ports] place netcat "in the way" of a standard service, since inbound connections are generally sent to such specifically-bound listeners first and fall back to the ones bound to "any". This allows for a one-off experimental simulation of some service, without having to screw around with inetd.conf. Running with -v turned on and collecting a connection log from standard error is recommended. Netcat as well can make an outbound connection and then run a program or script on the originating end, with input and output connected to the same network port. This "inverse inetd" capability could enhance the backup-server concept described above or help facilitate things such as a "network dialback" concept. The possibilities are many and varied here; if such things are intended as security mechanisms, it may be best to modify netcat specifically for the purpose instead of wrapping such functions in scripts. Speaking of inetd, netcat will function perfectly well *under* inetd as a TCP connection redirector for inbound services, like a "plug-gw" without the authentication step. This is very useful for doing stuff like redirecting traffic through your firewall out to other places like web servers and mail hubs, while posing no risk to the firewall machine itself. Put netcat behind inetd and tcp_wrappers, perhaps thusly: www stream tcp nowait nobody /etc/tcpd /bin/nc -w 3 realwww 80
and you have a simple and effective "application relay" with access control
and logging. Note use of the wait time as a "safety" in case realwww isn't
reachable or the calling user aborts the connection -- otherwise the relay may
hang there forever.
You can use netcat to generate huge amounts of useless network data for
various performance testing. For example, doing
yes AAAAAAAAAAAAAAAAAAAAAA | nc -v -v -l -p 2222 > /dev/null
on one side and then hitting it with
yes BBBBBBBBBBBBBBBBBBBBBB | nc othermachine 2222 > /dev/null
from another host will saturate your wires with A's and B's. The "very
verbose" switch usage will tell you how many of each were sent and received
after you interrupt either side. Using UDP mode produces tremendously MORE
trash per unit time in the form of fragmented 8 Kbyte mobygrams -- enough to
stress-test kernels and network interfaces. Firing random binary data into
various network servers may help expose bugs in their input handling, which
nowadays is a popular thing to explore. A simple example data-generator is
given in data/data.c included in this package, along with a small collection
of canned input files to generate various packet contents. This program is
documented in its beginning comments, but of interest here is using "%r" to
generate random bytes at well-chosen points in a data stream. If you can
crash your daemon, you likely have a security problem.
The hex dump feature may be useful for debugging odd network protocols,
especially if you don't have any network monitoring equipment handy or aren't
root where you'd need to run "tcpdump" or something. Bind a listening netcat
to a local port, and have it run a script which in turn runs another netcat
to the real service and captures the hex dump to a log file. This sets up a
transparent relay between your local port and wherever the real service is.
Be sure that the script-run netcat does *not* use -v, or the extra info it
sends to standard error may confuse the protocol. Note also that you cannot
have the "listen/exec" netcat do the data capture, since once the connection
arrives it is no longer netcat that is running.
Binding to an arbitrary local port allows you to simulate things like r-service clients, if you are root locally. For example, feeding "^@root^@joe^@pwd^@" [where ^@ is a null, and root/joe could be any other local/remote username pair] into a "rsh" or "rlogin" server, FROM your port 1023 for example, duplicates what the server expects to receive. Thus, you can test for insecure .rhosts files around your network without having to create new user accounts on your client machine. The program data/rservice.c can aid this process by constructing the "rcmd" protocol bytes. Doing this also prevents "rshd" from trying to create that separate standard-error socket and still gives you an input path, as opposed to the usual action of "rsh -n". Using netcat for things like this can be really useful sometimes, because rsh and rlogin generally want a host *name* as an argument and won't accept IP addresses. If your client-end DNS is hosed, as may be true when you're trying to extract backup sets on to a dumb client, "netcat -n" wins where normal rsh/rlogin is useless. If you are unsure that a remote syslogger is working, test it with netcat. Make a UDP connection to port 514 and type in "<0>message", which should correspond to "kern.emerg" and cause syslogd to scream into every file it has open [and possibly all over users' terminals]. You can tame this down by using a different number and use netcat inside routine scripts to send syslog messages to places that aren't configured in syslog.conf. For example, "echo '<38>message' | nc -w 1 -u loggerhost 514" should send to auth.notice on loggerhost. The exact number may vary; check against your syslog.h first. Netcat provides several ways for you to test your own packet filters. If you bind to a port normally protected against outside access and make a connection to somewhere outside your own network, the return traffic will be coming to your chosen port from the "outside" and should be blocked. TCP may get through if your filter passes all "ack syn", but it shouldn't be even doing that to low ports on your network. Remember to test with UDP traffic as well! If your filter passes at least outbound source-routed IP packets, bouncing a connection back to yourself via some gateway outside your network will create "incoming" traffic with your source address, which should get dropped by a correctly configured anti-spoofing filter. This is a "non-test" if you're also dropping source-routing, but it's good to be able to test for that too. Any packet filter worth its salt will be blocking source-routed packets in both directions, but you never know what interesting quirks you might turn up by playing around with source ports and addresses and watching the wires with a network monitor. You can use netcat to protect your own workstation's X server against outside access. X is stupid enough to listen for connections on "any" and never tell you when new connections arrive, which is one reason it is so vulnerable. Once you have all your various X windows up and running you can use netcat to bind just to your ethernet address and listen to port 6000. Any new connections from outside the machine will hit netcat instead your X server, and you get a log of who's trying. You can either tell netcat to drop the connection, or perhaps run another copy of itself to relay to your actual X server on "localhost". This may not work for dedicated X terminals, but it may be possible to authorize your X terminal only for its boot server, and run a relay netcat over on the server that will in turn talk to your X terminal. Since netcat only handles one listening connection per run, make sure that whatever way you rig it causes another one to run and listen on 6000 soon afterward, or your real X server will be reachable once again. A very minimal script just to protect yourself could be while true ; do
nc -v -l -s -p 6000 localhost 2
done
which causes netcat to accept and then close any inbound connection to your
workstation's normal ethernet address, and another copy is immediately run by
the script. Send standard error to a file for a log of connection attempts.
If your system can't do the "specific bind" thing all is not lost; run your
X server on display ":1" or port 6001, and netcat can still function as a probe
alarm by listening on 6000.
Does your shell-account provider allow personal Web pages, but not CGI scripts?
You can have netcat listen on a particular port to execute a program or script
of your choosing, and then just point to the port with a URL in your homepage.
The listener could even exist on a completely different machine, avoiding the
potential ire of the homepage-host administrators. Since the script will get
the raw browser query as input it won't look like a typical CGI script, and
since it's running under your UID you need to write it carefully. You may want
to write a netcat-based script as a wrapper that reads a query and sets up
environment variables for a regular CGI script. The possibilities for using
netcat and scripts to handle Web stuff are almost endless. Again, see the
examples under scripts/.
Example uses -- the dark side Equal time is deserved here, since a versatile tool like this can be useful to any Shade of Hat. I could use my Victorinox to either fix your car or disassemble it, right? You can clearly use something like netcat to attack or defend -- I don't try to govern anyone's social outlook, I just build tools. Regardless of your intentions, you should still be aware of these threats to your own systems. The first obvious thing is scanning someone *else's* network for vulnerable services. Files containing preconstructed data, be it exploratory or exploitive, can be fed in as standard input, including command-line arguments to netcat itself to keep "ps" ignorant of your doings. The more random the scanning, the less likelihood of detection by humans, scan-detectors, or dynamic filtering, and with -i you'll wait longer but avoid loading down the target's network. Some examples for crafting various standard UDP probes are given in data/*.d. Some configurations of packet filters attempt to solve the FTP-data problem by just allowing such connections from the outside. These come FROM port 20, TO high TCP ports inside -- if you locally bind to port 20, you may find yourself able to bypass filtering in some cases. Maybe not to low ports "inside", but perhaps to TCP NFS servers, X servers, Prospero, ciscos that listen on 200x and 400x... Similar bypassing may be possible for UDP [and maybe TCP too] if a connection comes from port 53; a filter may assume it's a nameserver response. Using -e in conjunction with binding to a specific address can enable "server takeover" by getting in ahead of the real ones, whereupon you can snarf data sent in and feed your own back out. At the very least you can log a hex dump of someone else's session. If you are root, you can certainly use -s and -e to run various hacked daemons without having to touch inetd.conf or the real daemons themselves. You may not always have the root access to deal with low ports, but what if you are on a machine that also happens to be an NFS server? You might be able to collect some interesting things from port 2049, including local file handles. There are several other servers that run on high ports that are likely candidates for takeover, including many of the RPC services on some platforms [yppasswdd, anyone?]. Kerberos tickets, X cookies, and IRC traffic also come to mind. RADIUS-based terminal servers connect incoming users to shell-account machines on a high port, usually 1642 or thereabouts. SOCKS servers run on 1080. Do "netstat -a" and get creative. There are some daemons that are well-written enough to bind separately to all the local interfaces, possibly with an eye toward heading off this sort of problem. Named from recent BIND releases, and NTP, are two that come to mind. Netstat will show these listening on address.53 instead of *.53. You won't be able to get in front of these on any of the real interface addresses, which of course is especially interesting in the case of named, but these servers sometimes forget about things like "alias" interface addresses or interfaces that appear later on such as dynamic PPP links. There are some hacked web servers and versions of "inetd" floating around that specifically bind as well, based on a configuration file -- these generally *are* bound to alias addresses to offer several different address-based services from one machine. Using -e to start a remote backdoor shell is another obvious sort of thing, easier than constructing a file for inetd to listen on "ingreslock" or something, and you can access-control it against other people by specifying a client host and port. Experience with this truly demonstrates how fragile the barrier between being "logged in" or not really is, and is further expressed by scripts/bsh. If you're already behind a firewall, it may be easier to make an *outbound* connection and then run a shell; a small wrapper script can periodically try connecting to a known place and port, you can later listen there until the inbound connection arrives, and there's your shell. Running a shell via UDP has several interesting features, although be aware that once "connected", the UDP stub sockets tend to show up in "netstat" just like TCP connections and may not be quite as subtle as you wanted. Packets may also be lost, so use TCP if you need reliable connections. But since UDP is connectionless, a hookup of this sort will stick around almost forever, even if you ^C out of netcat or do a reboot on your side, and you only need to remember the ports you used on both ends to reestablish. And outbound UDP-plus-exec connection creates the connected socket and starts the program immediately. On a listening UDP connection, the socket is created once a first packet is received. In either case, though, such a "connection" has the interesting side effect that only your client-side IP address and [chosen?] source port will thereafter be able to talk to it. Instant access control! A non-local third party would have to do ALL of the following to take over such a session:
Got an unused network interface configured in your kernel [e.g. SLIP], or support for alias addresses? Ifconfig one to be any address you like, and bind to it with -s to enable all sorts of shenanigans with bogus source addresses. The interface probably has to be UP before this works; some SLIP versions need a far-end address before this is true. Hammering on UDP services is then a no-brainer. What you can do to an unfiltered syslog daemon should be fairly obvious; trimming the conf file can help protect against it. Many routers out there still blindly believe what they receive via RIP and other routing protocols. Although most UDP echo and chargen servers check if an incoming packet was sent from *another* "internal" UDP server, there are many that still do not, any two of which [or many, for that matter] could keep each other entertained for hours at the expense of bandwidth. And you can always make someone wonder why she's being probed by nsa.gov. Your TCP spoofing possibilities are mostly limited to destinations you can source-route to while locally bound to your phony address. Many sites block source-routed packets these days for precisely this reason. If your kernel does oddball things when sending source-routed packets, try moving the pointer around with -G. You may also have to fiddle with the routing on your own machine before you start receiving packets back. Warning: some machines still send out traffic using the source address of the outbound interface, regardless of your binding, especially in the case of localhost. Check first. If you can open a connection but then get no data back from it, the target host is probably killing the IP options on its end [this is an option inside TCP wrappers and several other packages], which happens after the 3-way handshake is completed. If you send some data and observe the "send-q" side of "netstat" for that connection increasing but never getting sent, that's another symptom. Beware: if Sendmail 8.7.x detects a source-routed SMTP connection, it extracts the hop list and sticks it in the Received: header! SYN bombing [sometimes called "hosing"] can disable many TCP servers, and if you hit one often enough, you can keep it unreachable for days. As is true of many other denial-of-service attacks, there is currently no defense against it except maybe at the human level. Making kernel SOMAXCONN considerably larger than the default and the half-open timeout smaller can help, and indeed some people running large high-performance web servers have *had* to do that just to handle normal traffic. Taking out mailers and web servers is sociopathic, but on the other hand it is sometimes useful to be able to, say, disable a site's identd daemon for a few minutes. If someone realizes what is going on, backtracing will still be difficult since the packets have a phony source address, but calls to enough ISP NOCs might eventually pinpoint the source. It is also trivial for a clueful ISP to watch for or even block outgoing packets with obviously fake source addresses, but as we know many of them are not clueful or willing to get involved in such hassles. Besides, outbound packets with an [otherwise unreachable] source address in one of their net blocks would look fairly legitimate. Notes A discussion of various caveats, subtleties, and the design of the innards. As of version 1.07 you can construct a single file containing command arguments and then some data to transfer. Netcat is now smart enough to pick out the first line and build the argument list, and send any remaining data across the net to one or multiple ports. The first release of netcat had trouble with this -- it called fgets() for the command line argument, which behind the scenes does a large read() from standard input, perhaps 4096 bytes or so, and feeds that out to the fgets() library routine. By the time netcat 1.00 started directly read()ing stdin for more data, 4096 bytes of it were gone. It now uses raw read() everywhere and does the right thing whether reading from files, pipes, or ttys. If you use this for multiple-port connections, the single block of data will now be a maximum of 8K minus the first line. Improvements have been made to the logic in sending the saved chunk to each new port. Note that any command-line arguments hidden using this mechanism could still be extracted from a core dump. When netcat receives an inbound UDP connection, it creates a "connected socket" back to the source of the connection so that it can also send out data using normal write(). Using this mechanism instead of recvfrom/sendto has several advantages -- the read/write select loop is simplified, and ICMP errors can in effect be received by non-root users. However, it has the subtle side effect that if further UDP packets arrive from the caller but from different source ports, the listener will not receive them. UDP listen mode on a multihomed machine may have similar quirks unless you specifically bind to one of its addresses. It is not clear that kernel support for UDP connected sockets and/or my understanding of it is entirely complete here, so experiment... You should be aware of some subtleties concerning UDP scanning. If -z is on, netcat attempts to send a single null byte to the target port, twice, with a small time in between. You can either use the -w timeout, or netcat will try to make a "sideline" TCP connection to the target to introduce a small time delay equal to the round-trip time between you and the target. Note that if you have a -w timeout and -i timeout set, BOTH take effect and you wait twice as long. The TCP connection is to a normally refused port to minimize traffic, but if you notice a UDP fast-scan taking somewhat longer than it should, it could be that the target is actually listening on the TCP port. Either way, any ICMP port-unreachable messages from the target should have arrived in the meantime. The second single-byte UDP probe is then sent. Under BSD kernels, the ICMP error is delivered to the "connected socket" and the second write returns an error, which tells netcat that there is NOT a UDP service there. While Linux seems to be a fortunate exception, under many SYSV derived kernels the ICMP is not delivered, and netcat starts reporting that *all* the ports are "open" -- clearly wrong. [Some systems may not even *have* the "udp connected socket" concept, and netcat in its current form will not work for UDP at all.] If -z is specified and only one UDP port is probed, netcat's exit status reflects whether the connection was "open" or "refused" as with TCP. It may also be that UDP packets are being blocked by filters with no ICMP error returns, in which case everything will time out and return "open". This all sounds backwards, but that's how UDP works. If you're not sure, try "echo w00gumz | nc -u -w 2 target 7" to see if you can reach its UDP echo port at all. You should have no trouble using a BSD-flavor system to scan for UDP around your own network, although flooding a target with the high activity that -z generates will cause it to occasionally drop packets and indicate false "opens". A more "correct" way to do this is collect and analyze the ICMP errors, as does SATAN's "udp_scan" backend, but then again there's no guarantee that the ICMP gets back to you either. Udp_scan also does the zero-byte probes but is excruciatingly careful to calculate its own round-trip timing average and dynamically set its own response timeouts along with decoding any ICMP received. Netcat uses a much sleazier method which is nonetheless quite effective. Cisco routers are known to have a "dead time" in between ICMP responses about unreachable UDP ports, so a fast scan of a cisco will show almost everything "open". If you are looking for a specific UDP service, you can construct a file containing the right bytes to trigger a response from the other end and send that as standard input. Netcat will read up to 8K of the file and send the same data to every UDP port given. Note that you must use a timeout in this case [as would any other UDP client application] since the two-write probe only happens if -z is specified. Many telnet servers insist on a specific set of option negotiations before presenting a login banner. On a raw connection you will see this as small amount of binary gook. My attempts to create fixed input bytes to make a telnetd happy worked some places but failed against newer BSD-flavor ones, possibly due to timing problems, but there are a couple of much better workarounds. First, compile with -DTELNET and use -t if you just want to get past the option negotiation and talk to something on a telnet port. You will still see the binary gook -- in fact you'll see a lot more of it as the options are responded to behind the scenes. The telnet responder does NOT update the total byte count, or show up in the hex dump -- it just responds negatively to any options read from the incoming data stream. If you want to use a normal full-blown telnet to get to something but also want some of netcat's features involved like settable ports or timeouts, construct a tiny "foo" script: #! /bin/sh
exec nc -otheroptions targethost 23
and then do
nc -l -p someport -e foo localhost &
telnet localhost someport
and your telnet should connect transparently through the exec'ed netcat to
the target, using whatever options you supplied in the "foo" script. Don't
use -t inside the script, or you'll wind up sending *two* option responses.
I've observed inconsistent behavior under some Linuxes [perhaps just older
ones?] when binding in listen mode. Sometimes netcat binds only to "localhost"
if invoked with no address or port arguments, and sometimes it is unable to
bind to a specific address for listening if something else is already listening
on "any". The former problem can be worked around by specifying "-s 0.0.0.0",
which will do the right thing despite netcat claiming that it's listening on
[127.0.0.1]. This is a known problem -- for example, there's a mention of it
in the makefile for SOCKS. On the flip side, binding to localhost and sending
packets to some other machine doesn't work as you'd expect -- they go out with
the source address of the sending interface instead. The Linux kernel contains
a specific check to ensure that packets from 127.0.0.1 are never sent to the
wire; other kernels may contain similar code. Linux, of course, *still*
doesn't support source-routing, but they claim that it and many other network
improvements are at least breathing hard.
There are several possible errors associated with making TCP connections, but to specifically see anything other than "refused", one must wait the full kernel-defined timeout for a connection to fail. Netcat's mechanism of wrapping an alarm timer around the connect prevents the *real* network error from being returned -- "errno" at that point indicates "interrupted system call" since the connect attempt was interrupted. Some old 4.3 BSD kernels would actually return things like "host unreachable" immediately if that was the case, but most newer kernels seem to wait the full timeout and *then* pass back the real error. Go figure. In this case, I'd argue that the old way was better, despite those same kernels generally being the ones that tear down *established* TCP connections when ICMP-bombed. Incoming socket options are passed to applications by the kernel in the kernel's own internal format. The socket-options structure for source-routing contains the "first-hop" IP address first, followed by the rest of the real options list. The kernel uses this as is when sending reply packets -- the structure is therefore designed to be more useful to the kernel than to humans, but the hex dump of it that netcat produces is still useful to have. Kernels treat source-routing options somewhat oddly, but it sort of makes sense once one understands what's going on internally. The options list of addresses must contain hop1, hop2, ..., destination. When a source-routed packet is sent by the kernel [at least BSD], the actual destination address becomes irrelevant because it is replaced with "hop1", "hop1" is removed from the options list, and all the other addresses in the list are shifted up to fill the hole. Thus the outbound packet is sent from your chosen source address to the first *gateway*, and the options list now contains hop2, ..., destination. During all this address shuffling, the kernel does NOT change the pointer value, which is why it is useful to be able to set the pointer yourself -- you can construct some really bizarre return paths, and send your traffic fairly directly to the target but around some larger loop on the way back. Some Sun kernels seem to never flip the source-route around if it contains less than three hops, never reset the pointer anyway, and tries to send the packet [with options containing a "completed" source route!!] directly back to the source. This is way broken, of course. [Maybe ipforwarding has to be on? I haven't had an opportunity to beat on it thoroughly yet.] "Credits" section: The original idea for netcat fell out of a long-standing desire and fruitless search for a tool resembling it and having the same features. After reading some other network code and realizing just how many cool things about sockets could be controlled by the calling user, I started on the basics and the rest fell together pretty quickly. Some port-scanning ideas were taken from Venema/Farmer's SATAN tool kit, and Pluvius' "pscan" utility. Healthy amounts of BSD kernel source were perused in an attempt to dope out socket options and source-route handling; additional help was obtained from Dave Borman's telnet sources. The select loop is loosely based on fairly well-known code from "rsh" and Richard Stevens' "sock" program [which itself is sort of a "netcat" with more obscure features], with some more paranoid sanity-checking thrown in to guard against the distinct likelihood that there are subtleties about such things I still don't understand. I found the argument-hiding method cleanly implemented in Barrett's "deslogin"; reading the line as input allows greater versatility and is much less prone to cause bizarre problems than the more common trick of overwriting the argv array. After the first release, several people contributed portability fixes; they are credited in generic.h and the Makefile. Lauren Burka inspired the ascii art for this revised document. Dean Gaudet at Wired supplied a precursor to the hex-dump code, and mudge@l0pht.com originally experimented with and supplied code for the telnet-options responder. Outbound "-e " resulted from a need to quietly bypass a firewall installation. Other suggestions and patches have rolled in for which I am always grateful, but there are only 26 hours per day and a discussion of feature creep near the end of this document. Netcat was written with the Russian railroad in mind -- conservatively built and solid, but it *will* get you there. While the coding style is fairly "tight", I have attempted to present it cleanly [keeping *my* lines under 80 characters, dammit] and put in plenty of comments as to why certain things are done. Items I know to be questionable are clearly marked with "XXX". Source code was made to be modified, but determining where to start is difficult with some of the tangles of spaghetti code that are out there. Here are some of the major points I feel are worth mentioning about netcat's internal design, whether or not you agree with my approach. Except for generic.h, which changes to adapt more platforms, netcat is a single source file. This has the distinct advantage of only having to include headers once and not having to re-declare all my functions in a billion different places. I have attempted to contain all the gross who's-got-what-.h-file things in one small dumping ground. Functions are placed "dependencies-first", such that when the compiler runs into the calls later, it already knows the type and arguments and won't complain. No function prototyping -- not even the __P(()) crock -- is used, since it is more portable and a file of this size is easy enough to check manually. Each function has a standard-format comment ahead of it, which is easily found using the regexp " :$". I freely use gotos. Loops and if-clauses are made as small and non-nested as possible, and the ends of same *marked* for clarity [I wish everyone would do this!!]. Large structures and buffers are all malloc()ed up on the fly, slightly larger than the size asked for and zeroed out. This reduces the chances of damage from those "end of the buffer" fencepost errors or runaway pointers escaping off the end. These things are permanent per run, so nothing needs to be freed until the program exits. File descriptor zero is always expected to be standard input, even if it is closed. If a new network descriptor winds up being zero, a different one is asked for which will be nonzero, and fd zero is simply left kicking around for the rest of the run. Why? Because everything else assumes that stdin is always zero and "netfd" is always positive. This may seem silly, but it was a lot easier to code. The new fd is obtained directly as a new socket, because trying to simply dup() a new fd broke subsequent socket-style use of the new fd under Solaris' stupid streams handling in the socket library. The catch-all message and error handlers are implemented with an ample list of phoney arguments to get around various problems with varargs. Varargs seems like deliberate obfuscation in the first place, and using it would also require use of vfprintf() which not all platforms support. The trailing sleep in bail() is to allow output to flush, which is sometimes needed if netcat is already on the other end of a network connection. The reader may notice that the section that does DNS lookups seems much gnarlier and more confusing than other parts. This is NOT MY FAULT. The sockaddr and hostent abstractions are an abortion that forces the coder to deal with it. Then again, a lot of BSD kernel code looks like similar struct-pointer hell. I try to straighten it out somewhat by defining my own HINF structure, containing names, ascii-format IP addresses, and binary IP addresses. I fill this structure exactly once per host argument, and squirrel everything safely away and handy for whatever wants to reference it later. Where many other network apps use the FIONBIO ioctl to set non-blocking I/O on network sockets, netcat uses straightforward blocking I/O everywhere. This makes everything very lock-step, relying on the network and filesystem layers to feed in data when needed. Data read in is completely written out before any more is fetched. This may not be quite the right thing to do under some OSes that don't do timed select() right, but this remains to be seen. The hexdump routine is written to be as fast as possible, which is why it does so much work itself instead of just sprintf()ing everything together. Each dump line is built into a single buffer and atomically written out using the lowest level I/O calls. Further improvements could undoubtedly be made by using writev() and eliminating all sprintf()s, but it seems to fly right along as is. If both exec-a-prog mode and a hexdump file is asked for, the hexdump flag is deliberately turned off to avoid creating random zero-length files. Files are opened in "truncate" mode; if you want "append" mode instead, change the open flags in main(). main() may look a bit hairy, but that's only because it has to go down the argv list and handle multiple ports, random mode, and exit status. Efforts have been made to place a minimum of code inside the getopt() loop. Any real work is sent off to functions in what is hopefully a straightforward way. Obligatory vendor-bash: If "nc" had become a standard utility years ago, the commercial vendors would have likely packaged it setuid root and with -DGAPING_SECURITY_HOLE turned on but not documented. It is hoped that netcat will aid people in finding and fixing the no-brainer holes of this sort that keep appearing, by allowing easier experimentation with the "bare metal" of the network layer. It could be argued that netcat already has too many features. I have tried to avoid "feature creep" by limiting netcat's base functionality only to those things which are truly relevant to making network connections and the everyday associated DNS lossage we're used to. Option switches already have slightly overloaded functionality. Random port mode is sort of pushing it. The hex-dump feature went in later because it *is* genuinely useful. The telnet-responder code *almost* verges on the gratuitous, especially since it mucks with the data stream, and is left as an optional piece. Many people have asked for example "how 'bout adding encryption?" and my response is that such things should be separate entities that could pipe their data *through* netcat instead of having their own networking code. I am therefore not completely enthusiastic about adding any more features to this thing, although you are still free to send along any mods you think are useful. Nonetheless, at this point I think of netcat as my tcp/ip swiss army knife, and the numerous companion programs and scripts to go with it as duct tape. Duct tape of course has a light side and a dark side and binds the universe together, and if I wrap enough of it around what I'm trying to accomplish, it *will* work. Alternatively, if netcat is a large hammer, there are many network protocols that are increasingly looking like nails by now... from http://sysunconfig.net/unixtips/netcat_readme.html --------- Using netcat to build a simple TCP proxy in Linux
Recently I wanted to analyze the network communication between a local
application and a remote server. The usual way to accomplish this is to
use a system-wide packet analyzer like Wireshark or tcpdump.
These tools require the system to be set up to allow packet filtering
with special privileges granted to the local user that wants to inspect
the network traffic passing through the system.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| #!/bin/sh -e
if [ $# != 3 ]
then
echo "usage: $0 <src-port> <dst-host> <dst-port>"
exit 0
fi
TMP=`mktemp -d`
BACK=$TMP/pipe.back
SENT=$TMP/pipe.sent
RCVD=$TMP/pipe.rcvd
trap 'rm -rf "$TMP"' EXIT
mkfifo -m 0600 "$BACK" "$SENT" "$RCVD"
sed 's/^/ => /' <"$SENT" &
sed 's/^/<= /' <"$RCVD" &
nc -l -p "$1" <"$BACK" | tee "$SENT" | nc "$2" "$3" | tee "$RCVD" >"$BACK"
|
If the script is saved as "tcp-proxy.sh" it can be executed like this:
./tcp-proxy.sh 8080 tweakers.net 80
Repeating the earlier HTTP request causes the script to print out the request and response data with lines prefixed according to the direction of network traffic:
=> HEAD HTTP://tweakers.net HTTP/1.1
=> User-Agent: curl/7.26.0
=> Host: tweakers.net
=> Accept: */*
=> Proxy-Connection: Keep-Alive
=>
<= HTTP/1.1 200 OK
<= Server: Apache
<= X-Tweakers-Server: phobos
<= Expires: Mon, 26 Jul 1995 05:00:00 GMT
<= Last-Modified: Mon, 11 Jun 2012 19:23:09 GMT
[..]
Closing Remarks
- This configuration works best with text-only line-based protocols. Although it's possible to replace the sed processes with e.g. hexdump (which prints binary data in a human-readable format), the output of the two processes gets messed up because the script output is still line-buffered.
- An advantage of the above script is that it can be easily customized to format traffic in different ways, or even dynamically alter the netwerk conversation, by inserting tools like grep or sed into the pipeline. For example, we might insert grep -v ^Proxy-Connection: to filter out the non-standard HTTP header that curl sends to the webserver.
- The GNU version of netcat differs slightly from both the original netcat and the FreeBSD port of netcat. Although any implementation could be used in principle, some modifications to the script may be necessary.
from https://notes.tweakblogs.net/blog/7955/using-netcat-to-build-a-simple-tcp-proxy-in-linux.html
On Ncat
Traditionally called the “Swiss Army knife” for reading, writing and redirecting traffic across network connections, Ncat is used in a variety of different ways, including controlling and debugging network connections. It is an improved replacement for netcat and is included when downloading Nmap.
Although for some use cases it can act as a drop-in replacement for netcat, it is different in several important areas in that it offers:
- Security and authentication via TLS
- Support for IPv6
- Connection brokering
- Proxy connections
Here are some of its use cases:
- Act as a TCP client or server for HTTP, FTP and other TCP/IP connections. This enables fine control over what a client sends to a server, and it also allows investigation into what a client is doing.
- Set up secure channels using TLS.
- Redirect or proxy TCP and UDP (among others) connections to other hosts.
- Acts as a network
cat
.
Since Ncat is a pipeline tool that reads from stdin
and writes to stdout
, it can be used in any manner of of I/O redirection with which you’re accustomed. None of the streams are altered unless given the the -C
flag (adds CRLF
for EOL
sequence).
Ncat either operates in connect mode (client) or listen mode (server). Let’s take a look at some use cases
Connect Mode
One of the simplest uses is to connect to a TCP server, like Telnet:
ncat -C benjamintoll.com 80
> HTTP / GET/1.0
>
>
Using TLS:
ncat -C --ssl theowlsnestfarm.com 443
> HTTP / GET/1.0
>
>
Listen Mode
Here is Ncat listening as a server:
ncat -l localhost 10003 < <(echo -e "HTTP/1.0 200 OK\n\n<h1>hello world</h1>")
Simply point a browser to localhost:10003
.
Note that, in the previous example, Ncat is expecting a file descriptor to be redirected to stdin
, so you could replace the process substitution here with a regular file.
The following would also do the same as the previous listening Ncat example:
echo -e "HTTP/1.0 200 OK\n\n<h1>hello world</h1>" | ncat -l localhost 10003
Or:
cat | ncat -l localhost 10003
> HTTP/1.0 200 OK
>
> <h1>hello world</h1>
>
Note that there are also many examples of using TLS with both server and client certificates in the Ncat guide.
Access Control
Ncat also supports access control. You can whitelist and blacklist by host (--allow
and --deny
, respectively) or by lists in a file (--allowfile
or --denyfile
). Ncat supports the following syntax:
- IPv4 and IPv6 addresses
- hostnames
- IPv4 octet ranges
- CIDR netmasks
For example:
ncat -l --allow 2001:db8::7d
ncat -l --deny google.com
ncat -l --allow 192.168.0.0/24
ncat -l --allowfile trusted_hosts.txt
You can also limit the number of connections:
ncat -l --max-conns 3
Naturally, this is not secure and shouldn’t be replied upon in any significant way, but I think it’s good enough for a quick file transfer or chat session or the like.
Command Execution
Ncat allows a server to respond with the results of a command executed by means of:
- Directly executing a binary
- Passing a command string to be interpreted by a shell
- Invoking a Lua script
For example, the following commands will do the same thing, i.e., list the contents of the directory of the Ncat “server”:
ncat -le "/bin/ls -al"
ncat -l --sh-exec "ls -al"
The client request:
ncat localhost
Although I don’t use it very frequently, it does come in handy.
File Transfer
I usually prefer scp
over Ncat when transferring a single file, except in one instance - archive files. I find it preferable to use Ncat because doing the operation as a stream means that I don’t have to create a temporary archive file.
For example, the following will stream a bzip2 archive from trout
to chomsky
:
chomsky$ ncat -l 1972 | tar xjv
trout$ tar cjv keygen.c Makefile | ncat --send-only chomsky 1972
As you can see, the listening Ncat on chomsky
receives the stream and pipes it to tar
, thereby “untarring” it without further intervention from me. As an added bonus, the --send-only
flag will automatically close the connection as soon as the transfer is complete.
Using a Broker
chomsky$ ncat -l --broker
nero$ ncat chomsky > outputfile
trout$ ncat --send-only chomsky < inputfile
Chat
Simple two user chat:
germanicus$ ncat -kl --max-conns 1
nero$ ncat germanicus
Note that without the access control flag other clients can connect to the listening Ncat but that that will only establish its own channel with the “server”. In other words, none of the other clients will “hear” the conversation. Use it or don’t :)
If multi-user chat is desired, simply start Ncat in listening mode with the --broker
flag:
ncat -l --broker
A multi-user chat with designated usernames can be used with the --chat
option. For example, all messages all prefaced with <usern>
, where n
is the client connection’s file descriptor (this cannot be changed). This will automatically enable connection brokering.
ncat -l --chat
Anything received on one channel is broadcast out to all the other channels, but note that the server doesn’t receive any client messages.
Incidentally, I wrote a simple chat program that does the same, and it does allow the connecting client to choose a unique username.
from https://www.benjamintoll.com/2018/04/30/on-ncat/
------
netcat, all u need to know
Table of Contents
Netcat is a tool that reads and writes data across network connections, using TCP or UDP protocol. Netcat has been referred to as the TCP/IP / networking swiss army knife. In this article we’ll look at different applications of netcat and how it can be useful in day to day activities of a pentester, security professional, sysadmin etc…
If you would like to test out these commands in a lab environment without the need to install them on your own machine have a look at my scena
rio on CYBERRANGES using the link below.
Variants
There are several variants of netcat but most of the core functionality and command line options are very similar. Netcat having being initially written for Unix, the variants we will look at are linux based. You can also find netcat ports for windows that support similar commands to what we’ll look at.
Netcat Traditional
Netcat traditional is the original implementation and was written by a guy known as Hobbit. This does not typically come preinstalled unless you are using a distro like kali linux. It is no longer maintained and is on version 1.10.
By running apt search netcat
on an ubuntu/debian based machine, it appears as netcat or netcat-traditional.
To install it you can then run sudo apt install netcat-traditional
or via compiling from source which you can get from the project page https://nc110.sourceforge.io/.
If you install the different variants of netcat on your system you may have to invoke the command with the full binary name. In this case we’ll run nc.traditional -h
to see the command line options.
You notice the -e option, this is not available in the openbsd version. This is the feature that is considered a security hole. More on this when we get to the shells section.
GNU Netcat
GNU Netcat is a rewrite of the original netcat to make it more portable with new features and fully GNU compliant. This means it can be easily installed on almost all linux distros. This version is not available via package manager. It seems to also be no longer maintained as it’s latest version is 0.7.1 from 2004.
To get it you can download the source files from the project website http://netcat.sourceforge.net then compile it.
You need gcc and make to install successfully. The binary will be installed to /usr/local/bin/netcat. Below are the commands to use.
Netcat OpenBSD
The Netcat OpenBSD version is a rewrite of the original netcat to include support for IPv6, proxies and unix sockets. In addition to those enhancements it is compiled to remove a feature that is considered a gaping security hole of the application.
This version is the most common and is what you will find installed by default in ubuntu distro (both desktop and server). For other linux distros you may have to install it yourself.
By running apt search netcat
on an ubuntu machine, it appears as netcat-openbsd package.
To install it you can then run sudo apt install netcat-openbsd
. When netcat is installed it is symlinked to nc and netcat for ease of invoking the command. We can see this by checking the realpath of nc and netcat, they point to the same nc.openbsd binary. This can be different depending on which variant you have installed in your system.
The command line options available can be seen by running netcat -h
.
Ncat
Ncat is the reimplementation of netcat from the nmap project. This version is more feature rich and improved. I personally use this on a day to day.
When installing nmap you get ncat installed as well, this applies for windows and linux. You can then run ncat -h
to see the command line options available.
You can also compile from source to install it which can be downloaded from the nmap website https://nmap.org/ncat/.
Features
Now that we understand the different variants, let’s look at the most common features you’d use netcat for. Most of the syntax is common across the different variants.
We’ll focus on the 2 most recent variants, netcat-openbsd and ncat because they are the most recently maintained and updated.
Server / Client mode
Server mode
In server mode you can use netcat to listen for connections. What this does is open a port (either tcp or udp) on the system.
By default netcat listens on tcp. The below command will listen on all interfaces on port 8080.
To specify the interface to listen on, for example localhost, you can use the below syntax for openbsd variant. Sometimes it may not be the best idea to listen on all interfaces depending on the situation.
Ncat prefers a different syntax when specifying the interface.
To listen on udp the syntax is similar to tcp but including -u option.
As you noticed, the command line options can be used grouped together or separated.
Client mode
In client mode you can use netcat to connect to an open port on a system. This can be beneficial for manually checking service banners or just checking if the port is open.
For a tcp connection when connecting to IP 127.0.0.1 on port 8080, the syntax is as below.
For a udp connection we only add the -u option.
Reverse / Bind Shells
Familiarity with the concept of reverse shells and bind shells is needed as it is not discussed in detail in this section as we are only looking at how netcat facilitates them.
This is very popular to pentesters and use of netcat makes it easy. I will use the server / client model for explanation.
The commands used only work on ncat,netcat traditional and gnu netcat. Netcat OpenBSD is compiled to not have this feature as it is considered a security risk.
Reverse shells
For a reverse shell, we use netcat in server mode to listen for connections then supply the shell from the client. This will allow the session on the server to run commands on the client once the shell is received. From a pentesting perspective the server would be the attacker machine and the client the victim machine.
Server (attacker machine)
Client (victim machine)
Something to note is that, just because the openbsd version does not have this -e option, does not mean that it is impossible to get a reverse shell when it’s installed. There are still ways it can be used to achieve a reverse shell.
Bind shells
For a bind shell, netcat in server mode listens for a connection and serves the shell process to any connecting client. Netcat running in client mode can then connect to the server and get shell access to the server and run commands. From a pentesting perspective the server would be the victim machine and the client the attacker machine.
Server (victim machine)
Client (attacker machine)
File Transfer
Due to the ability to write to the connections raw, we can transfer files over the connection from one system to another without distortion.
For this we don’t really care about which is the server and which is the client because the transfer can go either direction but we need to run the listener first.
To transfer a file on server1 to server2 over port 8080 can be done as below:
To do the same in the opposite direction:
Port Scanning
This feature is not implemented in ncat but is available in the other variants. According to their website they omitted this feature because they have a better tool for that, which would be nmap.
Therefore if you find a system with netcat-openbsd and can’t install nmap you can run basic port scans as below.
To scan TCP ports on a target we can use the below syntax.
To scan UDP ports on a target we can use the below syntax.
Traffic Redirection
This is only possible on the variants that support the -e option.
Take the below scenario where server1 cannot connect directly to server3 but can only go through server2.
server1 <-------------> server2 <-------------> server3
To redirect traffic from server1 to a web app running on server3 (192.168.125.40) on port 8080 we can execute the below ncat command on server2.
Now you can reach the web app on server3 by accessing server2 on port 8000.
Ncat Additional Features
From the features the security risks can be seen because there’s no encryption on the connection as netcat will write to the connection in its rawest form, therefore anyone sniffing the network can capture all your traffic unencrypted in the case of shells and file transfer. For bind shells, there’s no authentication therefore anyone connecting to the port the bind shell is listening on will be able to run commands on the machine.
When using ncat, some of these concerns are addressed as it allows for use of ssl as well as access control.
Encrypted Shells
For a reverse shell we’ll use the same command syntax but add --ssl
to the command, same goes for bind shells.
Server (attacker machine)
Client (victim machine)
Access Control
When using netcat in server mode the --allow
option can specify one host or network range to be allowed to connect to the port, this can be good for the bind shell situation. Similarly, you can use –deny to deny access from a specific host or network range.
The above command will set the bind shell to only accept connections from localhost.
Conclusion
Netcat is a really great tool for network related activities, I find it really useful during CTFs and sometimes use it during pentests. There’s several other options that we haven’t looked into feel free to explore them, but I think we’ve covered should be enough for most of your use cases.
I haven’t explained the specific command line options -like -v -n because the help menu clearly explains them.
Challenge for you, play around with netcat for windows (specifically ncat because of ssl feature). It’s a nice utility that can help you get reverse shells and doesn’t get flagged as a virus.
Happy Hacking!
References
https://en.wikipedia.org/wiki/Netcat
https://nmap.org/ncat/guide/index.html
http://netcat.sourceforge.net/
https://eternallybored.org/misc/netcat/
from https://blog.ikuamike.io/posts/2021/netcat/
related post: https://briteming.blogspot.com/2019/09/netcat.html
Thanks for this post. It proves very informative for me. Great post to read. Keep blogging.
ReplyDeleteIf you are looking for the top security companies in London that provide its customer with remarkable security services. Check out this site for security services and largest security guard companies