-----[ Twisted Wire #2: Exploring TCP with Netcat ---[ by Kurruppt of SiN -----[ 02/01/2000 ---[ www.TheCyberUnderground.com by Kurruppt2k - kurruppt@thecyberunderground.com (www.thecyberunderground.com)(www.sinsecurity.net) TCP/IP. What an amazing phenomenon when a client and a server dance so eloquently together. This article/text will be nothing new to socket programming ubercoders, but will give newbies and novices a taste of how the Internet really works. Netcat is a great little program originally written by Hobbit for Unix, then ported to Windows by Mudge of L0pht. It's really just a TCP client in the simplest form. With it you can connect directoy to a port on a host, and send characters to it, or listen on a certain port of your local machine. With some of its more elaborite switches, netcat can even portscan. But we'll focus on what it was created for - playing with raw sockets. What the hell is a socket? We'll use FTP for our example. When you attempt to FTP to a remote host, your FTP client does a number of things to establish a connection. One: it starts the SYN-ACK-SYN/ACK three packet handshake to establish a connection. I won't go into depth about how this works, as there are plenty of whitepapers on the subject already, but if you're not fermilliar with the process, your FTP client basically sends out a packet to determine if the port (in this exmple port 21) is open. If so, it finalizes the connection and what is known as a 'socket' is created. A socket is - simplisticly - a two way tcp/ip connection. When your FTP client talks to the FTP server, it sends data out port 21 to the server's port 21. Then, the FTP server replies out a high-number port (above 1024 - this actual number is randomly decided, we'll say its 1113 for the example) to port 1113 on your box, which is listening for replies. This two way connection is a socket - each port is an simplex connection (data travels in only one direction), which is why a socket contains two "channels" or ports. Now that a socket has been created, all the TCP service (port) and IP info is part of that socket. Meaning all the FTP client has to do to communicate (send characters) to the server is write to the socket. It doesn't have to worry about port numbers, IP addresses, and the like. Netcat and Raw Sockets Okay, we know what sockets are and that they are the basis for any TCP/IP communications. With that in mind, we can understand what netcat does. When you use netcat without any switches like so: nc 10.10.10.1 123 it will create a socket between your computer and 10.10.10.1 on port 123. From there, you can type characters that are sent directly to whatever deamon you're connected to. This is similar to telnetting to a port, except that telnet isn't quite raw TCP, as it breaks all communications into 8 bit chunks of data. (Although, if you'd like to force telnet negotiations as defined in the telnet RFC, you can use the -t switch on the Windows versoin of netcat.) This is usefull to connect to some service and talk to it - and find out what kind of commands are used in it's 'protocol.' For example, to see how SMTP works, you could connect to the sendmail service on your local linux box like so: nc localhost 25 -v And you'll get the typical sendmail banner: 220 localhost.localdomain ESMTP Sendmail 8.11.0/8.11.0; Mon, 25 Dec 2000 17:53:03 -0600 This is an old trick, but here's the important thing - because we connected directly (raw TCP - no telnet) and got a banner, we can conclude that sendmail will send out this data immediately after a socket has been established. Typically, the client will have to send some kind of initializatin string to start a 'session.' But netcat does not send any string at all when it connect, it JUST establishes a socket. Meaning you could open netscape and request: http://localhost:25/ and as soon as a session is established the SMTP deamon will spew this info (although a web browser won't know what to do with it, and you'd probalby get some kind of error message). Another trick that illustrates this is the following. Use netcat to connect directly to the web service at www.thecyberunderground.com like so: echo get / http/1.1 | nc www.thecyberunderground.com 80 > out.txt What this does is connect to the server on port 80, send the text 'get / http/1.0' to the server, and save whatever data the server sends back to out.txt. Now 'cat out.txt'. What do you see? Yup - its the html page for /, which in this case is indes.html. This illustrates that an HTTP client (browser) connects to the server, and uses the GET command to "download" a web page. Simple. (Note: this might not always work, as two carriage returns are necessary after a GET command). Server Side Netcat True, netcat is great for establishing raw tcp connections and finding out exaclty how specific services work. On the other side of the fence its server-side TCP raw-socket connectivity. You can tell netcat to listen on a certain port like so: nc -l -p 999 -v After issuing this command, you'll see (on Unix anyway): listening on [any] 999 ... Now open up a new shell and telnet to your local port 999, or better yet, telnet to your favorite unix shell provider, then telnet to your IP and port 999. On the window that you started nc you'll see: listening on [any] 2000 ... connect to [127.0.0.1] from nether.net [0.0.0.0] 2213 This means a socket was just established to your open port 999. From your unix shell account, type 'hello.' You'll see 'hello' appear under 'connected to...' where nc is listening. THIS IS HOW TCP WORKS. When a service, like FTP, listens on a port like your netcat is doiong, it waits for certain 'commands' (specified by the protocol). In the example of FTP, commands like USER, PASS, PUT, BIN, etc. Ascii characters are sent over the wire, just like when you 'talk' to your listening netcat. Next we'll explore the whole idea of a client and a server sending commands and replies to one another. If you have a webserver running on your computer (IIS, Apache), kill it. Then (as root on Unix) tell netcat to listen on port 80 like so: nc -l -p 80 -v You'll see the 'listening on [any] 80 ...' again, meaning the port is open and awainting a connection. Now fire up your browser, and request: http://localhost/ which will of course connect to port 80. Now check out the windows you have nc listening on. You'll see: listening on [any] 2000 ... connect to [127.0.0.1] from localhost.localdomain [127.0.0.1] 1082 GET / HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686) Host: localhost:2000 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 What is all that? Well, your browser (one) connected to your port 80 and established a socket with the open port, (two) after the connection was established, immediately sent the above text to what it thinks is a web deamon. As we learned in earlier, the web server will then await HTTP commands, such as GET or POST. Now that we've communicated directly with both the HTTP client and HTTP server, we can understand what's happening in an HTTP (or any TCP) conversation. By using netcat to talk to the deamon and the client (browser), we know that the an HTTP conversation looks something like: CLIENT establishes socket with SERVER (SYN-ACK-SYN/ACK) (Next, remember that unlike SMTP, the HTTP deamon doesn't do or say anthing until the client 'initializes' the conversation). CLIENT tells SERVER a little about itself and requests a certain page by sending the text: GET /somefile.html HTTP/1.0 Connection: Keep-Alive User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.2.16-22 i686) Host: localhost:2000 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 SERVER takes into consideration the file types that CLIENT will accept, and returns the requested webpage by sending the text: