Tuesday, February 2, 2021

Pcaps and the Tools That Love Them Part 3

 

From here, with header diagram in hand, you should know be able to look at a packet dump and find the value you need, by counting from offset 0 to the correct field. 

Some of the things you'll want to look for (like IPv6 traffic or only ICMP traffic or a particular IP) can be done most efficiently with primitives. 

Others, like, options in the IP header, which are rare and always suspicious can be done by by checking the header length field, but since the first byte in the IP header is broken into two fields of a nibble each, how do see just the header length, and not the IP version?

The answer is bitmasking. Bitmasking is hiding the bits we don't want to see and leaving the ones we do, simply put. For example, let's take the 13th byte (offset from zero, of course) in the TCP header.


Flags     CWR ECE Urg Ack     Push Reset Syn Fin

Binary Values 8    4     2    1          8      4             2    1


We have one byte, eight bits that comprise the TCP flags that can be set. We know from our basic networking that when one host wants to talk to another host, it sends a SYN (synchronize) packet to the IP address of the receiving host on the port the protocol should be listening on. 

If the receiving host is listening on that port and ready to communicate, it sends a SYN-ACK packet back (synchronize acknowledgment). 

The sending host confirms it's received the reply and is ready to start communicating by sending an ACK packet back to the destination. This is commonly known as the TCP three way hand shake.


So in order to see all of the attempts to initiate a connection on the wire or in a packet capture, we would want to see all of the packets that only have the SYN flag set. Looking at our header of byte 13, we see that the SYN flag bit is in the second nibble (4 bits) and the next to last bit. 

The way we write a BPF is to 1. specify the header, 2. the byte, and 3. any bitmasking needed to filter out additional bits.  So to see only SYN packets we would write a BPF like this:

tcp[13] = 2 - Note this shows us packets that ONLY the SYN packet is set. 

We can also write a BPF to show any packets that the SYN flag is set, as well as any another flags. To do this, instead of checking the full value of byte 13, we just check to see if the SYN bit is set. 

We would do this with a BPF like this: tcp[13] & 0x02 != 0. Here we're simply checking to see if the SYN bit is set to 1, or turned on. Any other flags could be active or not, we're not checking for anything other than SYN. 

That would mean the value of the entire byte is 2, meaning no other bits are set, or have any value but zero.

In binary our byte would be 00000010 which equals two.

This short hand way of writing BPFs works, up to a point. Once we have to represent a value greater than 9, this binary shortcut breaks down.

In that case you need to write the BPF in hexadecimal, so lets rewrite our BPF in hex and get used to writing them that way.

In hex our value would be 0x02, so the BPF would be tcp[13] = 0x02. In hex, each digit represents a nibble, or 4 bits, so two digits in hexadecimal equal a byte.

So we see here none of the first four bits are set (0) and in the second nibble the SYN flag is set, which is 2 to the power of 1, or 2. What's with the 0x in front of our numbers? 

0x tells our computer this is a hexadecimal value. Octal numbers are prefaced by just a o, or more recently, 0o so 0o5 would be an octal 5 (octal is base 8 and we don't need to delve into that here).

Just as binary is base2, and decimal is base10, hexadecimal is base16. That means in hex we run out of numbers before we get to 15 and move to the next higher place. So How do we accomplish that?

Hexadecimal uses letters to represent the numbers 10 through 15. A=10, B=11, C=12, D=13, E=14 and F=15. So 0x1A is the hexadecimal number 26. 16 plus 10. 

Blog Archive