Showing posts with label Packet Capture. Show all posts
Showing posts with label Packet Capture. Show all posts

Friday, August 12, 2016

Calculating Seq & Ack Numbers in Packets

I thought it'd be interesting to walk through a Wireshark PCAP packet capture and see if I can explain how certain fields like the Lengths, Sequence, Ack #s, etc. were calculated. It involves a client (10.8.8.101) making a single HTTP GET request to a web server (108.60.15.36) over port 80 and getting an HTTP 200 success response back. Note this PCAP originated from the awesome Malware Traffic Analysis blog and is a real capture from the locky malspam @malware_traffic analyzed.



The first 3 packets above are the initial TCP handshake.

1.) You see a SYN from the client (10.8.8.101, flag 0x0002) saying 'hey server i want to talk to you'. The Seq and Ack #s are not used yet. The Total packet is 66 bytes. The ethernet header is always 14, thus the remainder (66-14 = 52) is IP Total Length is 52. Since the IP header is 20 that leaves (52-20 = 32) left for TCP packet. Since the TCP packet only contains a header of 32, that means that there is no tcp payload in this packet (32-32=0) which makes sense since it's the initial SYN.

2.) The server responds with a SYN-ACK (108.60.15.36, flag 0x0012) saying 'hey client i received your syn'. The Seq # is still not used yet, but the Ack # is incremented to 1 because the prior received packet contained a SYN. The Total packet is 60 bytes. There are 14 for ethernet again so 60-14=46 for IP. But notice the IP total header says 44. That means that the remaining 46-44=2 bytes are just 0 padding because the Ethernet frame has a minimum size it must be. Since the IP header is 20 and the we know (44-20=24) is the size of the TCP packet. Since the TCP header takes up all of the tcp packet (24-24=0) we again have no tcp payload.

3.) The client then response with an ACK (flag 0x0010) saying 'hey server i got your syn-ack, lets start talking'. The Seq # is now increased by 1 because of the prior received packet containing a SYN. The Ack # stays untouched at 1 right now. The Total packet is 60 bytes (14 for ethernet, 44 for ip frame). Since the IP header is 20 and the we know (44-20=24) is the size of the TCP packet. Since the TCP header takes up all of the tcp packet (24-24=0) we again have no tcp payload.





The next several packets are the actual application layer HTTP GET request.

4.) You see that application layer traffic starting now that the TCP handshake is complete. This is an HTTP GET request, so the client requesting a web page from the server. It is a PSH/ACK (flag 0x0018), all packets go forward during normal communication with contain an ACK, and the PSH is to indicate that the client is ready for data. The Seq # and Ack # both stay at 1 for this initial request since no data was actually transferred yet. You'll notice the total packet is 408 bytes this time though. The Ethernet Header is 14 and the IP total length is 408-14=394. Then in the IP packet the header is 20 meaning the rest of it (the tcp packet) is 394-20=374. And in the TCP packet the tcp header is 20 meaning the tcp payload (which in this case is an HTTP GET is 374-20=354 bytes). If you were to look in the Packet Bytes in wireshark for this packet you'd see actual HTTP Request Headers like the host host, useragent, etc.

5.) This next packet is the Server simply Acknowledging that it received the HTTP GET request. Notice it's an ACK (0x0010) for acknowledgement. Also notice the total length is small again, only 60 bytes. Take out the 14 byte ethernet header and you get 60-14=46 bytes for rest of IP. But notice again it says the total IP length is only 40 so that means 46-40=6 bytes of zero padding has been added to the end to fill out the Ethernet frame. Take out the 20 byte IP header and you get 40-20=20 bytes for TCP. Take out the TCP header and you get 20-20=0 bytes of actual TCP payload. There is none since this is just the acknowledgement. Notice the Sequence # stayed at 1, but the Ack # actually increased. If you recall from the previous packet we said the TCP total length was 354. Thus the Acknowledgement # because 1+354=355 because it's the server saying 'hi client, i acknowledge I have now received a total of 355 bytes from you'.

6.) Next you'll see the web server continue with it's 2nd packet in a row ... actually responding back to the client's GET request with some data, so it's going to get interesting now. See how the total length is 1514 bytes. Take out the 14 byte ethernet header and you get 1514-14=1500 bytes of IP. Take out the 20 byte IP header and you get 1500-20=1480 bytes of TCP. Take out the 20 bytes of TCP Header and you get 1480-20=1460 bytes of TCP payload (or in this case actual HTML code getting returned by the web server in response to the HTTP GET request for a specific page). If you were to look in the packet bytes of wireshark for this packet you'd see actual HTML code like the HTTP Response headers and perhaps an HTML or BODY tag eventually here soon. Now notice that the Ack # stayed at 355 because the Server has not received any more data from the client and the Seq # stays at 1 because no data has actually been received by the client prior to this packet yet.

7.) Next it's a kinda interesting normal occurence in TCP. The Server (108.60.15.36) had received the HTTP GET request prior and now is ready to start firing off packets back to the client in small chunks in order to send back the entire large HTTP response. The server isn't necessarily going to wait for the client to Acknowledge every packet, but instead the Server is going to start firing off a bunch of packets. Thus in the case we are going to see the server send 2 packets of http data before the client even Acknowledges it received some (in packet #8). This thus is similar to packet #6. It's a PSH/ACK with data (0x0018) the ACK because there is data in this payload and the PSH because the Server is saying he's ready to receive data from the client. The total length of the packet is 1308. If you remove the 14 for the ethernet header then 1308-14=1294 for IP. Then the IP header is 20 so 1294-20=1274 bytes for the TCP. Then take away the 20 bytes TCP header then 1274-20=1254 bytes for the TCP payload (which is more HTML code in the HTTP response). So you can see that the Ack # stays at 355 because the data received by the server has not changed, but the SEq # has increased to 1+1460=1461 bytes as the server is saying 'hey client i've now sent you 1461 bytes of data'.

8.) So this is the client finally sending an ACK (0x0010) back to the server saying 'hello server i acknowledge i received your first 2 packets of data'. You'll notice the total length is small at 60 bytes again because this is just an ACK. The Ethernet header is 14 so 60-14=46 again for IP. But since it says the IP total length is only 40, then we get 46-40=6 bytes of zero padding for the Ethernet header minimum size. Then again the ip header is 20 so 40-20=20 bytes remaining for TCP. And the TCP header is 20 so 20-20=0 bytes for the actual tcp payload which makes sense again since this is just the tiny quick Acknowledgment packet. The Seq # is set to 355 because the client is saying 'hi server just so you know I have sent 355 bytes if tcp payload to you so far'. The Ack # is now pretty large at 1+1460+1254=2715 bytes of TCP payload, saying 'hi server i have so far receiving 2715 bytes of tcp payload from you.'

9-360.) Packets 9 thru 360 are a repeat of 6 thru 8 over and over again. The server sends 1 or 2 packets of data. The client Acknowledges the data it received. Each time the client's Ack # keeps increasing by the # of TCP payload bytes it received so that it's telling the server 'hey i have so far received X # of bytes from you successfully.' And the server's Seq # keeps increasing by the # of TCP payload bytes it sent so that it's telling the client 'he i have so far sent Y # of bytes to you.'





361.) Now in Wireshark packet #361 looks different because it says HTTP/1.1 200 OK. But you'll notice from the wireshark snippet above that Wireshark is just being smart and "re-assembling" all the TCP (HTTP Response) payloads together to give you an easy to read understanding of the HTTP Response which in this case was a 200 success meaning everybody was happy. This particular packet is actually otherwise essentially the same as packet #7 for example as it's just more TCP payload data (HTTP Response) with a PSH/ACK flag. The only difference is that this is the "last one" in the sequence. Note in this packet that it's 1001 total bytes. If we take out the 14 byte ethernet header there's 1001-14=987 bytes for IP. Take out the 20 bytes IP header and we have 987-20=967 bytes for TCP . Take out the 20 byte tcp header and we have 967-20=947 bytes of tcp payload (the final portion of the HTTP Response). You'll notice the ack # is still 355 because the server is saying 'hey client just so you know i've still only received 355 bytes from you' but you'll notice the Seq # is now huge at 280900 because the server is saying 'hey client i have now sent you a total of 280900 bytes.'

362.) This next packet is nearly identical to what we described in packet #8. It's the client's Acknowledgement of the Server sending data again. Notice the Seq # is still 355 saying 'hey server i have sent you 355 bytes so far' and the Ack # is 280900 saying 'hey server i have received 280900 bytes from you so far successfully'. This is actually the acknowlegement of packet #360 (not #361).

363.) This packet is the acknowledgment of the final server packet #361. You can tell because the Ack # has jumped to 280900+947=281847 bytes of total TCP payloads thus the client saying 'hey server i have received successfully now 281847 bytes of tcp payload from you.'

364.) Finally we get to a graceful teardown. The server sends a FIN/PSH/ACK (0x0019) basically telling the client, I have nothing more to send to you (FIN), I'm ready for data back from you now (PSH). Notice the server has a Seq # of 281847 because it's saying 'hey client i have sent you 281847 bytes of tcp payload data now' and the ack # is still 355 because it's saying 'hey client i have still only received 355 bytes of tcp payload data from you'. The packet is a small one again because it's just a teardown. 60 bytes total, take away 14 for the ethernet header leaves 60-14=46 for IP. But since the IP total length only says 40 then 46-40=6 bytes of zero padding in the ethernet header again. Then 20 bytes for the ip header leaves us with 40-20=20 bytes for the tcp packet. And 20 bytes of tcp header means there are 20-20=0 bytes of tcp payload in this.

365.) The client now acknolwedges (ACK 0x0010) that the FIN teardown request was received. Since the prior packet contained a FIN the ack # increases by 1 to 1+281847=281848.

398.) Now notice the gap in wireshark # (365 to 398) , this is because there is a larger time delay between the last packet and this one. This is basically the client finishing up whatever it was doing and saying ok I have nothing more to send you (FIN) either.

399.) Finally the server Acknolwedges the client's request to teardown (FIN). Notice since the prior packet request contained a FIN then the Ack # increases to 1+355=356. The conversation is done.

More about neonprimetime


Top Blogs of all-time
  1. pagerank botnet sql injection walk-thru
  2. DOM XSS 101 Walk-Through
  3. An Invoice email and a Hot mess of Java


Top Github Contributions
  1. Qualys Scantronitor 2.0


Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.

Thursday, May 26, 2016

Analyzing Some UDP Packets

I thought it'd be interesting to just walk through the analysis of a set of harmless UDP packets, to get a feel for basic 101 packet inspections, OSI layer analysis, and to see how a tool like Wireshark works behind the scenes. Here is what the packets look like in WireShark.





So to start, there was this string of UDP packets going outbound to an ip address on port 111. If you were to google search port 111 you'd see that one possibility is Sun Remote Procedure Calls. Let's take a bit of a deeper dive into these packets.



You can see above that WireShark has actually used the Ethernet Frame (layer 2) to determine the MAC addresses of the source & destination. MAC Addresses are unique identifiers for devices, and are useful because you can do a google search and determine based on the MAC address what vendor / company made the device and likely what type of device it may be. So how did Wireshark determine these MAC Addresses? Well below you'll see that HEX interpretation of the first several bytes in the Ethernet Header.



This is Layer 2, so we're talking about devices or usually MAC Addresses. If you were to read about Ethernet Frames you'd see that the 1st 6 octets (2 hex digits) there make up the Destination MAC Address (in this case ending with :41:16) and the 2nd 6 octets make up the Source MAC Address (in this case ending with :48:c3). You'll also notice the next 2 octets (81 00) tell you the Ethernet Type which in this case indicates 802.1Q which is used to define standards for VLAN tagging ( the practice of inserting a ID into a packet header to identify which VLAN the packet belongs to ). The next portion of what Wireshark shows you is the 802.1Q information.



Above you see that Wireshark identified that the VLAN tagging says Priority is default, CFI (format indicator) is canonical, and the ID is 6. You will see it also says that this is IPv4. But how did Wireshark know all that?



Well, above are the HEX values that wireshark analyzed.

0 ==> The first HEX digit (4 bits) is split. The 1st 3 bits indicate Priority and the value 0 in this case is default (Best Effort). The last bit is the format indicator, in this case 0 (Canonical)

0 06 ==> The next 3 HEX digits (1.5 octets) make up the VLAN identifier (for the tagging we said above). In this case converting HEX to decimal is simple 0x16^2+0x16^1+6x16^0 equals 6 as the ID.

08 00 ==> The final 2 octets are for the EtherType, in this case 0x0800 which defines that this is IPv4 (e.g. ip normal addresses such as 171.70.71.72) .
Next Wireshark displays you the IP header information (Layer 3).



Above you can see that wireshark was able to determine that this is IPv4, the protocol is UDP, and determine the source & destination IP address. Again though, how did Wireshark determine that?



Above is the HEX interpretation of the IPv4 Header. This is layer 3 so you'll see below that we're talking about IP addresses communicating.

4 ==> The 1st HEX digit indicates the IP protocol version, in this case simply IPv4.

5 ==> The next HEX digit indicates the length of this IP header we are in (5 * 32 = 160 bits = 20 bytes = 5 words).

00 ==> The next octet used to be type of service, but has been redefined as Differentiated Services Code Point (DSCP) and Explicit Congestion Notification (ECN) for new technologies and doesn't apply here so it's 0.

00 54 ==> The next 2 octets define the total length of the entire packet (including header & data), which in this case 5x16^1+4x16^0=84 bytes.

0e b8 ==> The next 2 octets define an identifier for this packet in case of fragmentation where they have to be re-assembled (3768).

00 00 ==> the next 2 octets define information about a fragment if the packet needed to be broken up. The 1st 3 bits are flags that define if you should fragment or not. The remaining 13 bits define the fragment offset which tells the re-assembler how far from the beginning of the fragment you are away. In this case everything is 0 so this would be the first fragment.

1a ==> The next octet defines the time to live, which is a way to prevent infinite loops when routing packets. Every time a packet is routed to another device this count is decremented. If it hits 0, the packet is discarded (and assumed to be in an infinite loop). You can usually guess what Operating System sent a packet by it's TTL. Linux TTLs start at 64 and count down to zero. Windows TTLs start at 32 and count down to zero. Most of the time packets should reach their destination in very few hops, well before the TTL expires. Thus in this case the TTL is (1x16^1+10x16^0=26). 26 would indicate that this is likely a windows system that sent this packet since 32-26=6 hops which is probably an average acceptable value. If the number was in the 50s or 60s it might indicate it's a Linux device that sent it.

11 ==> The next octet defines the protocol (1x16^1+1x16^0=17). In this case 17 is defined by IP protocol as a UDP packet.

2c 64 ==> The next 2 octets are a header checksum (11364), which can be used by some devices that are routing packets to determine if this packet has been tampered with or modified.

XX XX a1 80 ==> The next 4 octets are probably what you're usually after, the source ip, or who sent this packet! (a1=161,80=128 == XX.XX.161.128)

XX XX 0f 1a ==> The next 4 octets are also extremely useful, destination ip, or who this packet is supposed to go to! (0f=15,1a=26 == XX.XX.15.26)


Next we'll look at the UDP header.



Above is the UDP packet, which is Layer 4, so you'll see information about which ports the 2 devices will use to communicate with eachother. Wireshark above shows you that the source port is 899 and the destination port is 111. It also tells you the length of the udp packet and gives you another checksum for validation. But again how does Wireshark know this?




03 83 ==> The first 2 octets are used to calculate the source port. In this case 3x16^2+8x16^1+3x16^0 equals 899.

00 6f ==> The second 2 octets calculate the destination port. In this case 6x16^1+15x16^0 equals 111.

00 40 ==> The 3rd 2 octets tell you the length of this udp header plus data. In this case 4x16^1+0x16^0 equals 64 bits which is 8 bytes or 2 words.

9c d0 ==> The checksum again is a value that can be used to determine if this packet was modified or tampered with (40144).


Next we'll look at the RPC data for the remote procedure call.



Above Wireshark has determine this UDP packet is a Remote Procedure call which is part of layer 5, the session layer. So it's going to manage the session where the calling system is making a request to the receiving system and getting a response back. Above you can see that Wireshark determined RPC version 2 is being used, a procedure is being called, the program the procedure is in is Portmap, the Portmap version is 2, the procedure requested in that Portmap program is called GETPORT, and no credentials or verification is being performed. But how does Wireshark know all that?




57 47 f6 f2 ==> The first 4 octets give the remote procedure call a unique transaction id for tracking.

00 00 00 00 ==> The next 4 octets define whether is a call CALL or REPLY, in this case 0 = call.

00 00 00 02 ==> The next 4 octets define the version of RPC which in this case is 2.

00 01 86 a0 ==> The next 4 octets define which program contains the procedure being requested. In this case program 100000 is portmap. Other example programs could be things like nfs, status, lock manager, or mount.

00 00 00 02 ==> The next 4 octets define program version , in tihs case it's saying Portmap is version 2.

00 00 00 03 ==> The next 4 octets define which procedure in the program (portmap) is being requested. In this case procedure 3 is GETPORT, so it's requesting a which port is used. Other procedures could be things like SET , UNSET, and DUMP a port.

00 00 00 00 00 00 00 00 ==> The next 8 octets are used to pass Credentials (optional) when making a call to a procedure. If it's all 0s like in this case, then it's null or no authorization is used, essentially a anonymous request.

00 00 00 00 00 00 00 00 ==> The final 8 octets are also used. If this is a call to a procedure that requires credentials, then the credentials and this verifier token are passed. If it's not used it'll be all 0s again.


Finally let's take a look at the Portmap procedure call.



Above wireshark has determined that inside this UDP Remote procedure call, the program being called is Portmap, and it's calling the GETPORT procedure. This procedure is used to find out the port number assigned to a particular program. But how does wireshark know this final layer 7 application layer information?




02 22 22 22 ==> In the first 4 octets, this identifier is used to identify which unique program the requestor is asking for the port number of. So basically the requesting system wants to make a remote call to a program on the receiving system, but the requesting system doesn't know which port to use, so it's first using this portmap program to ask, "hey, which port is program 02 22 22 22 using?" The system will respond either with a port number if the program is running, or with a failure if the program doesn't exist.

00 00 00 01 ==> In the next 4 octets, it's saying that the requestor is requesting a port number for version 1 of the progrma.

00 00 00 06 ==> In the next 4 octets, it's saying that the requestor is requesting the TCP port for the program, the protocol number 6 in this case maps to TCP.

00 00 00 00 ==> The final 4 octets are empty in a call like this, but in a response would be filled with the actual port number the program is using for version 1 tcp.


Hopefully this walk-through was useful in getting a better understanding of how Wireshark works , how the different layers of the OSI model are utilized, and how to do basic packet analysis.

More about neonprimetime


Top Blogs of all-time
  1. pagerank botnet sql injection walk-thru
  2. DOM XSS 101 Walk-Through
  3. php injection ali.txt walk-thru


Top Github Contributions
  1. Qualys Scantronitor 2.0


Copyright © 2016, this post cannot be reproduced or retransmitted in any form without reference to the original post.