Netcat Refresher

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!

Noise machine

Not too long ago, I went to the MIT Flea Market which is an awesome flea market for all things hacker/maker. You can find all sorts of cool stuff ranging from tools to electronics to computers. I ended up finding a super old 2003 Apple Xserve server that this one table was selling for only $5, so of course I had to buy it, despite having zero experience with working with an actual server before.

In the time I’ve had it, I’ve done some of the basics, such as set up a basic web server which currently hosts a webpage for my apartment, but to be honest, this isn’t useful. Lately I’ve been trying to think of other ways to make the server something more than a noisy box in our living room.

Something I thought of that would at least provide some small bit of utility was to use the server as a dedicated torrent box that anyone in the apartment could use to download and seed torrents. This offers a lot of advantages over just using your own computer, especially for a college student who only has a laptop which has to be carried around frequently. Instead of leaving my computer on all night, why not just give that work to the server, who isn’t doing anything anyway?

Unfortunately the options weren’t too great for torrent clients because the server is so old; it’s running Mac 10.4, OS X Tiger! [^1] However, I was able to install a legacy version of Transmission on it which works just fine. The key feature that I needed in order to make this work was this ability for the client to watch a certain directory for new torrent files and automatically add them to the queue. From that point, there were a couple of different ways that I thought of going about this.

  1. I could add a page to the website that would let a user upload a torrent file, which would then be put into the directory that the torrent client was watching. This would be very straightforward to implement.

  2. I could take advantage of Dropbox. I could create a shared folder that anyone in the apartment could add torrent files to.[^2] From there, I could simply point Transmission to watch that shared directory and I’d be done!

With either of these methods, it would be nice for everyone to be able to watch the status of these torrents, so without even checking if my legacy version of Transmission offered a remote web interface (such as what uTorrent offers) I began looking for ways to hack this together myself. I found a couple of Python Transmission API’s that I might have been able to use, but while digging through the Transmission preferences, I found a web interface option that made my life a lot easier.

Anyway, I went with option #2 above, just because it seemed easier and faster. I set up the shared folder in no time at all, but then I ran into a problem when I tried to test this out. My version of Transmission doesn’t have an option to move the actual downloaded data file once it’s completed downloading, which means that it would just get put into the same directory as the torrent files. That being a Dropbox directory, that wouldn’t work because that (potentially huge) file would be synced to everyone’s Dropbox accounts, taking up space, and letting everyone see what you downloaded.

The solution that I decided on using was changing the directory that Transmission was watching and then using cron and a python script to move all the torrent files from the shared dropbox directory into the actual watched directory. This is better because it eliminates any sort of Dropbox folder clog and offers slightly more privacy because after a certain (relatively short) time period, the file is moved out of Dropbox and no longer available for everyone to look at.

This setup works pretty well, the Dropbox sync works nearly instantly and I have cron setup to run the python script every 15 minutes, because I doubt anyone would need to torrent something so urgently that they couldn’t wait, at most, 15 minutes for it to start. Once the script is run, the files are moved, Transmission notices, and gets to work. Anyone can check on the status of their download[^3] through the web interface, running on port 9091 of the web server.

At this point, the only thing left was to set up a way for people to actually get their files back from the server. It took some digging around in the settings of the server admin panel, but I was able to set up a public network share that allows anyone on the network to access the directory containing the data files.[^4]

And that’s it! It might have been a simple project, but this was my first experience with working with a server and it was pretty gratifying to set up something actually useful for my apartment.


[^1]: I don’t really want to bother with updating the OS right now, I’d rather just make do with what I have.

[^2]: And delete, I suppose. But that would be a dick move.

[^3]: And all others, defeating the point of any sort of privacy mentioned earlier.

[^4]: Further eliminating any notion of privacy.