Monday, May 19, 2014

Building your own TCP 3-way handshake – Packet Crafting – The Scapy Way

In my previous post relating to understanding the TCP’s Initial Sequence Number (ISN), I mentioned that understanding the TCP 3-Way Handshake is critical to understanding the ISN.

In this post we will build our own TCP 3-Way handshake and push some data over the connection. We will basically be completing the connection setup from previous post in which we worked on the TCP ISN. Moreover, the objective of this post, is to reinforce the information from the previous post.

So how will we build and verify our handshake? We will do it using the 3 lines below. 

originalPkt = sr1(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="S",sport=5000,dport=80,seq=12345)) 

send(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="A",sport=5000,dport=80,seq=originalPkt.ack,ack=originalPkt.seq+1),count=1)

send(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="PA",sport=5000,dport=80,seq=originalPkt.ack,ack=originalPkt.seq+1)/"HEAD / HTTP/1.0\r\nUser-Agent: Security Nik Testing\r\nHost: securitynik.lab\r\n\r\n",count=1)

Obviously there are many ways to do this but for this lab, this is what we will use. We will analyze this using tcpdump for better understanding.


Let’s break this down!
The Initial Syn Packet
originalPkt = sr1(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="S",sport=5000,dport=80,seq=12345))
1. We use the variable “originalPkt”, for storing the response for the packet we are sending from source IP 10.0.0.100 to destination IP 10.0.0.50. 
2. In the TCP Layer, we set the SYN flag (S), source port 5000, destination port 80, and an Initial Sequence Number (ISN) 12345

Let’s look at this from tcpdump’s perspective once sent.

IP 10.0.0.100.5000 > 10.0.0.50.80: Flags [S], seq 12345, win 8192, length 0


As can be seen, the information in tcpdump matches what we sent in our crafted SYN packet


Let’s look at how we craft our final ACK packet.

Because we used the “originalPkt” as a variable, we can now reference the values which were received in that variable. First, let’s see what tcpdump saw for the response.
IP 10.0.0.50.80 > 10.0.0.100.5000: Flags [S.], seq 983686717, ack 12346, win 8192, options [mss 1460], length 0

Looking at the above line, the server responded with its Syn+Ack. What is of the most importance to us in this response, is the server’s initial Sequence Number (ISN). In this case the server’s ISN is “983686717”. Now that we have the server’s ISN let’s go ahead and build our final ACK packet.

send(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="A",sport=5000,dport=80,seq=originalPkt.ack,ack=originalPkt.seq+1),count=1)

For our final ACK packet, we set the following.
1. Flags=“A” - ACK Flag
2. seq=originalPkt.ack - The sequence number we will use for our final ACK will be the Acknowledgement Number which was sent from the Server. In this case it is “ack 12346”
3. ack=originalPkt.seq+1 - Because we need to acknowledge the server’s sequence number which is unknown, we now extract that sequence number from the variable originalPkt and add 1 to this number.

Let’s send this on its way and see what tcpdump sees.
IP 10.0.0.100.5000 > 10.0.0.50.80: Flags [.], ack 983686718, win 8192, length 0

Awesome!!! We completed our TCP 3-way handshake. 


So let’s verify this is working as expected by sending some crafted data to the server.

send(IP(src="10.0.0.100",dst="10.0.0.50")/TCP(flags="PA",sport=5000,dport=80,seq=originalPkt.ack,ack=originalPkt.seq+1)/"HEAD / HTTP/1.0\r\nUser-Agent: Security Nik Testing\r\nHost: securitynik.lab\r\n\r\n",count=1)


Let’s see what tcpdump sees
IP 10.0.0.100.5000 > 10.0.0.50.80: Flags [P.], seq 12346:12422, ack 983686718, win 8192, length 76 E..t....@.e...d
..2...P..0::..>P. .44..HEAD / HTTP/1.0
User-Agent: Security Nik Testing
Host: securitynik.lab

Looks like we send some data successfully. Hmmm, I wonder how the server handled this? Let’s find out.

IP 10.0.0.50.80 > 10.0.0.100.5000: Flags [FP.], seq 983686718:983686962, ack 12422, win 65392, length 244
E...J.@....h..2
..d.P..:..>..0.P..p>N..HTTP/1.1 200 OK
Content-Length: 1398
Content-Type: text/html
Last-Modified: Sat, 17 May 2014 03:28:48 GMT
Accept-Ranges: bytes
ETag: "651ae21d8071cf1:0"
Server: Microsoft-IIS/8.0
Date: Mon, 19 May 2014 22:06:09 GMT
Connection: close

Nice!!!!! Looks like we profiled the server and know now that it a Microsoft-IIS/8.0 server

As can be seen, building your own TCP 3-Way handshake is not that difficult once you have the right understanding of how the protocols works.

Something to think about!
While we were able to establish the connection and generate a response from the server, do notice in the response from the server the FPA (FIN, PUSH and ACK flags) are all set. In this case, because we are not acknowledging the server’s FIN, it will try to resend the data. However, if no FIN ACK is received, it will eventually tear down the communication with a RST packet.

Additional Reading:
http://www.ietf.org/rfc/rfc793.txt
http://www.packetstan.com
http://projects.webappsec.org/w/page/13246925/Fingerprinting
http://www.secdev.org/projects/scapy/
http://www.net-square.com/httprint_paper.html

No comments:

Post a Comment