Thursday, February 10, 2011

BPF's For Beginners

If you've just started looking at packets, no doubt you've already found the need to pull out packets based on more than just the primitives built into tcpdump and other pcap aware tools (such as src, host, port, net, etc). tcpdump supports the use of the Berkeley Packet Filters expressions, allowing you to search on any field that tcpdump records. The basic syntax is field : operator : operand. For example, if you wished to see all IP packets whose length is greater than 20 (meaning IP options are in use) you would add the filter:
 'ip[0] & 0x0F > 5' This says to look at the first field in the IP header (offset 0, headers begin counting at 0), and using a bitmask, filter out the first nibble (the first four bits, 0), looking at the last four bits, (F) and show any that are greater than 5. We know the IP header length field is expressed as a 32 bit word (four bytes), so a 5 in that field (5 x 4 bytes) equals 20, the length of a normal IP header (also the minimum size). So any size greater than 5 would mean a header more than 20 bytes. This means IP options have been added to the end of the header, such as strict source routing, or loose source routing, rarely used and often a sign of a malicious attempt to route packets through a particular node for sniffing or interception.
   Enclosing your filter in quotes to avoid syntax errors is a good habit to get into. You'll eventually need them as your filters get more complex.
You can search on any field in any of the embedded protocols as well. If you needed to see SYN packets only, you could filter on the TCP header with a filter of 'tcp[13] = 0x02'. Here we would see only packets with a value of 2 in byte 13, which would have only the SYN flag set.
   If we needed to look at just a single bit or combination of bits, instead of a whole byte or a whole nibble as in the first filter, we would go back to our bitmasking. Bitmasking bits here is simply applying a bitwise AND  to filter out any bits we don't wish to look at, and preserving the bits we do. If we AND a zero to a bit, we end up with zero, if we AND a one, we end up with a 1. So if need to see all SYN-ACK packets, we would want to see all packets with byte 13 in the TCP header that have the least most significant bit set in in the first nibble and the second least significant bit set in the second nibble.

                    C E  U A   P R  S  F
                    1  1  1  1    1  1  1  1
Our mask     0  0  0  1    0  0  1  0

So our bitmask for SYN-ACK packets would be 0x12 and we would apply it as this:

'tcp[13] = 0x12' (no other flags should be set here as the SYN-ACK combination is only used in the TCP handshake.)

You can extend this to any field, down to a single bit, and chain them together to get as granular as you need. When you begin writing complex filters and using them over and over again, you can put each one in a file, and use the tcpdump -F parameter to load it, instead of retyping it each time. Very powerful stuff for dissecting packets, and very good to learn. You can't always be sure that you'll have access to Wireshark or some other protocol parser when you do to do network forensics. If you learn the command line way to do things first, you'll hopefully never get stuck.

If you want great training in bits and bytes, protocols and packets, and everything in between (especially if you want to be an intrusion analyst) I'd recommend looking at the SANS 503: Intrusion Detection In-Depth course. Taking it live, in my opinion, is always best, as you'll get the most interaction with the instructor, work with other folks interested in the same knowledge and absorb much more than just the class from the atmosphere of a SANS conference. But take it any way if you can, if you possibly can. And if you CAN go live, use the time you have there to its fullest. Sign up for the free SANS @Night classes, go to the Storm Center presentation, go listen to the keynote speakers in the evening, do the lunch and learns and sit in on a BOF (Bird of a Feather) session. That's why I'd never to go to a SANS conference at Disney World or Virginia Beach. Too many temptations to waste your time doing other things, and the opportunity to learn practically all day long is too valuable. But's that's just the way I roll. =-)


Cezar Spatariu Neagu said...

Hi I did red your paper on "Berkeley Packet Filters – The Basics" and I had a look on the example that use 'and ip[0] & 0xF0 != 4’. I wourld like to point out that is not working as is supposed to work. Should be "ip[0] & 0xf0 != 0x40" as it is pointed out here:
TCPDUMP mailing list. Anyway the paper is really good. Thank you,

JeffSoh said...

Thanks for the correction, Cezar!

Blog Archive