TCP/IP, Ports and Network Connections*
Much of computer security revolves around network security. In the vast, interconnected networks that make up most of todays computer systems the network is the most common point of entry for intruders. Understanding how the network is designed to work and how it actually functions can illuminate the abuses of networking that make attacks possible as well as aid in the identification of malicious activity. Knowledge of typical activity on one's network is critical to identifying anomalous activity and preventing break ins. Often times there are signatures indicative of reconnaissance leading up to a successful intrusion and understand and reacting to these signatures may help prevent exploitation of networked resources.
The core of many networked services is TCP/IP or Transmission Control Protocol/Internet Protocol. TCP is actually a communication layer that sits on top of IP and is dependent upon it. We distinguish TCP/IP from other protocols such as UDP or ICMP that also reside upon the IP communications layer. TCP/IP is distinguished from IP in that it adds port information to the communications stream as well as mechanisms to insure reliability and delivery. By itself IP does not provide these mechanisms. Many services such as HTTP and SSH rely on TCP/IP to make sure that signal transmission occurs in a complete and reliable way. Other protocols such as UDP are faster, but do not make guarantees about message delivery for various reasons.
TCP/IP guarantees delivery by sequencing packets so that if a packet is lost in delivery it can be re-requested and redelivered. Additionally TCP/IP provides some checksums to ensure that the packet data hasn't become corrupted in transmission. Packet sequencing is a tricky process since the sequencing must be unique in order to avoid message collision.
TCP/IP Three Way Handshake
In order for a TCP/IP communication to occur a connection must first be established. This is no simple task, as the nodes involved in the communication must negotiate several elements of the communication before they get started. For a connection to be successfully establish between two machines a proper connection 'handshake' must be completed. For the sake of our discussion we will examine this handshake between two computers: a client machine and a server. The client machine is the computer initiating the connection, and the server is the remote machine to which the query is being sent. The client machine initiates the handshake and the server responds. Both computers take an active role in negotiating the connection. Because TCP/IP relies on fragmentation of data during the communication, the two machines must agree on the protocol (including port information) as well as sequencing.
TCP/IP packets have several parts which can be subdivided into packet headers and packet payloads. Packet headers include connection and routing information while packet payloads include the actual data being transmitted. The connection is started when the client sends a packet with a SYN (for synchronize) flag set to the server. This is also known as a SYN packet. The SYN packet is sent to initiate the connection, it is basically a 'hello' between the two machines. The remote machine will then respond with a packet with both the SYN and ACK flags set in the header, known as a synchronize acknowledge packet. This indicates that the remote machine has received the SYN request and agrees to acknowledge (ACK) a valid communication. The client then sends an ACK packet to acknowledge the communication and begin data transfer. Using snort we can look at a sample three way communication between two machines (in this case negotiating an SSH connection):
11/18-09:46:42.766150 184.108.40.206:2411 -> 220.127.116.11:22 TCP TTL:128 TOS:0x0 ID:17598 IpLen:20 DgmLen:48 DF ******S* Seq: 0xE280F44F Ack: 0x0 Win: 0xFAF0 TcpLen: 28 TCP Options (4) => MSS: 1460 NOP NOP SackOK =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 11/18-09:46:42.786253 18.104.22.168:22 -> 22.214.171.124:2411 TCP TTL:56 TOS:0x0 ID:0 IpLen:20 DgmLen:48 DF ***A**S* Seq: 0x3EC12955 Ack: 0xE280F450 Win: 0x16D0 TcpLen: 28 TCP Options (4) => MSS: 1460 NOP NOP SackOK =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 11/18-09:46:42.786319 126.96.36.199:2411 -> 188.8.131.52:22 TCP TTL:128 TOS:0x0 ID:17599 IpLen:20 DgmLen:40 DF ***A**** Seq: 0xE280F450 Ack: 0x3EC12956 Win: 0xFAF0 TcpLen: 20 =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
This exchange shows three distinct packets captured from the exchange (separated by the =+=+= lines). These are the packets involved in the three way handshake. The first and the third packet are from the client, the middle packet is the response from the server.
The third line of the packet details shows the flags on the packets. This is the portion of the packet header that includes the asterisks (*). There are 8 possible flags (each one is a bit that can be set or not set). Two are never used and the other six are U for urgent, A for acknowledgement, P for push, R for reset, S for synchronize, and F for finish. Looking at the above three packets you can clearly see the three way handshake with the S flag on the first packet, the AS flags on the second packet and the A flag on the third packet.
Let's take a look at the three packets in more detail to understand exactly what is going on in the communication. The first packet in our communication looks like this:
11/18-09:46:42.766150 184.108.40.206:2411 -> 220.127.116.11:22 TCP TTL:128 TOS:0x0 ID:17598 IpLen:20 DgmLen:48 DF ******S* Seq: 0xE280F44F Ack: 0x0 Win: 0xFAF0 TcpLen: 28 TCP Options (4) => MSS: 1460 NOP NOP SackOK
The first line begins by showing the date/time stamp on the packet, in this case November 18th at 9:46 AM. Then we see the IP address of the packet sender 18.104.22.168 followed by a colon and the packets originating port 2411. The arrow indicated the packet was sent to the IP address that follows, 22.214.171.124 and a colon and the destination port. The destination port in this case is a low numbered port (below 1024) and it corresponds to the well known port for SSH. You'll notice that the requesting port is a high port. This is because on a typical Unix machine only root can bind ports below 1024.
The second line shows that this is a TCP communication and includes information about the packet itself. This starts with the TTL or Time To Live. Originally this was intended to be correlated to an actual time stamp, but in implementation it actually refers to the number of hops that the packet should survive. This is useful in case a packet ever gets caught in a routing loop. Each router forwards the packet along and decrements the TTL by one. When the packet TTL reaches zero routers will drop it. This limits an infinite loop scenario. The TTL of 128 is notable in that it differs from the server TTL of 56. Most Unix machines use a TTL of 64, showing that the returning packet has made some hops to get where it is. The high TTL of 128 is typical for a Windows based operating system. This information can be useful in machine fingerprinting which is discussed below.
Following the TTL is the TOS or Type of Service. This is rarely used and we can see that it isn't set in any of the packets. Following the TOS is the ID field. The ID is especially important for fragmentation which occurs when information is too big to fit into a single packet. You'll notice that the ID field increments on the client machine. The next fields specify sizes of the packet as well as optional flags. In the case of the first packet we see that the DF flag is set, this is the 'Do not fragment' flag.
The third line incudes the flags discussed above, along with the sequence number. This is a hexadecimal value used to reconstruct TCP/IP streams (place the packets back in order). The next field is the Ack field which is actually used to carry the value of the sequence on the next packet that the sender expects. Looking at these two fields in tandem over the course of the three packets we can see a pattern:
Seq: 0xE280F44F Ack: 0x0 Seq: 0x3EC12955 Ack: 0xE280F450 Seq: 0xE280F450 Ack: 0x3EC12956
We can note that the first packet, the SYN packet, sends a sequence number of 0xE280F44F and Acknowledges a null value as the packet sequence number it expects in response. The server responds with it's own sequence number of 0x3EC12955 and Acknowledges that the next packet it expects from the client is 0xE280F450 (which is one more than the hexadecimal value of 0xE280F44F since hex is numbered 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f - thus, after f is 0). Then we see the client respond with the appropriately sequence packet 0xE280F450 and Acknowledge the next incremental sequence number from the server 0x3EC12956 (which is one greater than the server's previous sequence number of 0x3EC12955).
So after the first packet is sent to start the handshake we see the second packet respond from port 22 to the client on port 2411 with the appropriate sequence numbers and flags:
11/18-09:46:42.786253 126.96.36.199:22 -> 188.8.131.52:2411 TCP TTL:56 TOS:0x0 ID:0 IpLen:20 DgmLen:48 DF ***A**S* Seq: 0x3EC12955 Ack: 0xE280F450 Win: 0x16D0 TcpLen: 28 TCP Options (4) => MSS: 1460 NOP NOP SackOK
The third packet is the final acknowledgement packet, carrying simply the 'A' header flag for acknowledgment. Also note the Seq: number (0xE280F450) is the same as the previous packets Ack: specification.
11/18-09:46:42.786319 184.108.40.206:2411 -> 220.127.116.11:22 TCP TTL:128 TOS:0x0 ID:17599 IpLen:20 DgmLen:40 DF ***A**** Seq: 0xE280F450 Ack: 0x3EC12956 Win: 0xFAF0 TcpLen: 20
It is useful to understand this communication in order to look more closely at the low level communications of your machine. Very similar to a three way handshake is the common communication termination sequence. This starts with a packet being sent with the F flag sent (a FIN packet) to which the other machine should respond with a packet with the F and A flags set (FIN/ACK). Finally the first computer should respond with an ACK packet. This is not always the way that communications end, but it is the most common (simply sending a FIN packet and awaiting an ACK is enough to tear down the connection).
The RST flag is also interesting to note in that it requests that the entire communication be torn down immediately. This is potentially useful when a machine must terminate connections quickly without awaiting responses (for instance if it was shutting down or rebooting)
Using Netstat to Review Your Local Communications
The netstat program is available at the command line on most Windows and Linux/Unix operating systems (usually in C:\Windows\System32\ on windows and /bin/netstat on Linux) can be used to review the local connections on your host machine. This is useful for identifying local ports that are open and listening for remote connections as well as seeing who is connected to your computer. On a Windows machine you can open up a command prompt and type in 'netstat -an'. The dash indicates optional arguments and the 'a' and 'n' are arguments for ALL and NUMERICAL FORMAT (for ports and protocols). You can type in 'netstat -help' to see all the optional arguments you can use. You should get something that looks like:
TCP 0.0.0.0:5800 0.0.0.0:0 LISTENING TCP 0.0.0.0:5900 0.0.0.0:0 LISTENING TCP 127.0.0.1:1904 0.0.0.0:0 LISTENING TCP 127.0.0.1:1904 127.0.0.1:1905 ESTABLISHED TCP 127.0.0.1:1905 127.0.0.1:1904 ESTABLISHED TCP 18.104.22.168:139 0.0.0.0:0 LISTENING TCP 22.214.171.124:139 126.96.36.199:32931 TIME_WAIT
The first column shows the communication type (TCP or UDP for Universal Datagram Packet which is a stateless communication protocol - meaning there isn't a challenge response or three way handshake or any confirmation that packets are received - most commonly used for DNS communications when there is a problem (port 53)). The first column is the local computer TCP/IP address, a colon, and the port number. The third column is the remote IP address and port and the last column is the state of the communication.
It is useful to check this information to find if there are Trojans listening or with active connections on your system, for example if you see a 'LISTENING' connection on either of the following two ports your computer might be running a Trojan (a backdoor that lets remote hackers connect to your computer):
Port 12345(TCP) Netbus Port 31337(UDP) Back Orifice
The last column, the state of the connection bears some explaining because you can see all sorts of information here:
Closed - indicates that the connection between the two machines has been terminated
Closing - the two machines are negotiating a termination of the connection
Close Wait - the remote connection has initiated a close connection request
Established - the two machines are actively communicating on the port
Fin Wait 1 - the software using the connection has terminated the connection
Fin Wait 2 - the remote machine has requested a termination
Last Ack - the local machine is waiting to destroy the connection
Listening - the local machine is actively waiting for a connection request
Syn Rcvd - the local machine has received a synchronize request
Syn Sent - the local machine has sent a synchronize request
Time_Wait - the local machine is waiting for the connection to tear down
Note that you might see a lot of TIME_WAIT listings. This is because your computer will hold onto connections for a specific period of time (sometimes very long) to keep choppy connections open (basically your computer is waiting for a remote response). However, as we observed above a TCP/IP teardown doesn't occur in a standard way. If a client machine simply stops transmitting packets and closes it's local connection this can result in the hold maintaining a TIME_WAIT on a connection that will never be reopened. This is a critical part of DDOS (Distributed Denial of Service) attacks since a computer must utilize a certain portion of resources (memory) to hold the connection open. If an attacker were to send a bunch of SYN requests and tear down their own connections without any FIN packets to the target the target could become bogged down in holding open the requests and might run out of threads to allocate for further incoming requests. This would effectively shut down whatever service the machine was attempting to hold open.
For information about how to configure your Windows machine to adjust how it handles TCP/IP connections (and prevent DoS attacks) see http://support.microsoft.com/?kbid=315669. If your computer holds onto communications for a very long time you may enable a denial of service. Holding open a large number of idle connections consumes resources and memory and eventually your machine might crash.
It is important to know what ports SHOULD be open in order to determine if anything funny is going on (make sure you know what services are open and running on your machine). On a windows machine you can check the 'Services' tab on your Computer Manager to see many of the services that are listening on your machine.
Using NMAP to Discover Open Ports
You can also use insecure.org's nmap port scanner to figure out what ports are open and listening on your machine. Nmap is the industry default scanner. What a scanner does is connect to ports to determine if they are up and running. In order to run nmap, you first have to install libpcap (or the windows version winpcap), which is a set of libraries relating to your Ethernet card. Be sure to install winpcap on your windows machine before you install nmap or you'll get weird errors and your machine might crash when you run nmap. After winpcap is install you can install nmapwin (or the windows version of nmap) and fire it up. The interface is pretty intuitive.
Try it out by running a scan on your own machine. Open up a command prompt and type in 'ipconfig /all' to get your IP address and plug this into the 'Host:' field and hit scan. You should get a nice list of ports and protocols that are open on your machine. Keep in mind that this is a local scan and might not be entirely accurate. This is because firewall technology will block remote port requests, but not local ones, so you may find services that are available locally but not from beyond your computer.
A local scan is a scan of your own computer. Nmap opens up test connections to various ports on your machine to see if they are active. Because these connection requests are coming internally you might get ports that any firewalls you have installed would otherwise block (internal scans generally bypass firewalls). A remote scan would originate these requests from outside your computer and would allow your firewall to intercept the scan. This is good to remember since you might want to get an accurate picture of what your machine looks like to the rest of the world, in which case you need to scan your computer from another machine.
Nmap is pretty accurate in the ports it finds. Keep in mind though that port numbers are arbitrary. Just because FTP usually runs on port 21 doesn't mean that someone couldn't set it up to run on port 25, in which case nmap would report an open SMTP port when in fact port 25 would be an FTP port.
Nmap is extremely powerful and fast, it can scan hundreds of computer in a matter of minutes. Because you can plug in a series of computers into the 'Host:' field, you don't even have to type in each IP address manually. Sometime system crackers will find a vulnerability that works to break into a machine with a certain service open on a certain port. The cracker will then scan huge ranges of computer looking for that port. You might notice on your firewall logs that you get random hits on ports you don't even have open, this is probably indicative of a cracker scanning across the internet looking for a vulnerable machine. Also watch your firewall logs to see if someone scans several hundred ports on your computer in a short period of time, this is probably a remote scan of your computer.
Because nmap is the industry default scanner it is both very good and very detectable. Because intrusion detection and firewall systems manufacturers understand nmap well, it is easy to spot an nmap scan. You can decrease your chances of being detected by adjusting the Timing options of the scan (under the 'Timing' tab).
Also note that nmap can perform SYN stealth scans. In doing these types of scans nmap forgoes the normal three way handshake to discover open ports. Instead nmap sends a simple 'SYN' packet and always responds with a RST packet (tearing down the connection) it analyzes whether the port is open or not based on weather it receives a SYN/ACK or a RST in response to the first SYN packet. Because a full connection is never established, this type of scan can sometimes evade firewalls or detection (although that is less common as this type of scan becomes more popular).
Nmap is also remarkable in that it can do TCP/IP fingerprinting. Using information such as the fact that Windows generally sets a TTL of 128 on packets nmap can derive a fairly accurate guess of the operating system running on the remote machine. Because TCP/IP isn't implemented uniformly and there are slight variations between operating systems (and even separate versions of operating systems) you can get fairly reliable results. Keep in mind, however, that systems administrators can alter their TCP/IP settings to deliver false readings to nmap.
Nmap can also read banners and other telling information in response packet payloads from it's connection requests. This means that nmap can often times identify not only what service is running on what port, but also the specific type of software and other information such as vendor and release information. Like TCP/IP fingerprinting though, this too can be spoofed by clever systems administrators.
* This article was formerly published as 'Computer Security Class 3'.