Tcpdump patterns

From TykWiki
Jump to navigationJump to search

This page contains information on tcpdumps match pattern syntax. When I find or write a nice pattern I may want to use later I will add it to this page.

Matching TCP Flags

On http://danielmiessler.com/study/tcpdump_recipes/ I found this nice list:

Show me all URG packets:
# tcpdump 'tcp[13] & 32 != 0'

Show me all ACK packets:
# tcpdump 'tcp[13] & 16 != 0'

Show me all PSH packets:
# tcpdump 'tcp[13] & 8 != 0'

Show me all RST packets:
# tcpdump 'tcp[13] & 4 != 0'

Show me all SYN packets:
# tcpdump 'tcp[13] & 2 != 0'

Show me all FIN packets:
# tcpdump 'tcp[13] & 1 != 0'

Show me all SYN-ACK packets:
# tcpdump 'tcp[13] = 18'

Matching DNS Traffic

Matching DNS Queries

This section is about matching different kinds of DNS queries with tcpdump.

DNS Dynamic Update Queries

A bit of backgound information on UDP and DNS packets is neccesary for this:

  • The UDP packet header is 8 bytes and tcpdump is counting the bytes from zero when matching, so the DNS packet header begins at "byte number 8" in tcpdump match syntax. See RFC768 for more on UDP packet characteristics.
  • According to rfc1035 (section 4.1.1, page 25), the two first bytes ("number 8 and 9" in tcpdump match syntax) in the DNS header is the transaction ID.
  • The next two bytes ("number 10 and 11" in tcpdump match syntax) make up the flags for the DNS packet. The two bytes contain a lot of information (refer to rfc1035 section 4.1.1, page 26). First I need to match only queries and not responses. That is set in the QR bit which is the first bit of the first byte of the DNS packet flags. Secondly I need to match only ns update queries, the type of query can be found in the Opcode field which is contains in bits 2-5 in the first byte of the DNS flags.
  • According to rfc1035 section 4.1.1, page 26, the QR bit is set to 0 for queries, and 1 for responses.
  • According to rfc2136 (which defines dynamic updates) section 2.2, page 4, the Opcode decimal 5 (with four bits for the Opcode that is binary 0101) means it is an update query.

Putting this together, I need to match DNS packets that has the following bit pattern in bits 1-5 of byte 10: 00101 - the first 0 is the QR bit, the next four is the Opcode.

I will check the individual bits that make up the bytes in a packet with tcpdump by using a bit-by-bit "binary AND" against a bitmask. I put the tcpdump expression together a bit at a time, maching each bit like I want it:

  • I want the first bit in byte 10 to be 0 in matched packets, that bit is decimal 128 or binary 10000000, so I add 'udp[10] & 128 = 0' to the tcpdump pattern.
  • I want the second bit in byte 10 to be 0 in matched packets, that bit is decimal 64 or binary 01000000, so I add 'udp[10] & 64 = 0' to the tcpdump pattern.
  • I want the third bit in byte 10 to be 1 in matched packets, that bit is decimal 32 or binary 00100000, so I add 'udp[10] & 32 = 32' to the tcpdump pattern. Note the difference.
  • I want the fourth bit in byte 10 to be 0 in matched packets, that bit is decimal 16 or binary 00010000, so I add 'udp[10] & 16 = 0' to the tcpdump pattern.
  • I want the fifth bit in byte 10 to be 1 in matched packets, that bit is decimal 8 or binary 00001000, so I add 'udp[10] & 8 = 8' to the tcpdump pattern.

So to show incoming dns dynamic update queries (as defined in rfc2136), run the following:

tcpdump port 53 and 'udp[10] & 128 = 0' and 'udp[10] & 64 = 0' and 'udp[10] & 32 = 32' and 'udp[10] & 16 = 0' and 'udp[10] & 8 = 8'

Summary: The tcpdump pattern to match ns update queries in the example above matches the first five bits of byte 10 of the udp packet, and makes sure they are exactly 00101.

Matching DNS Responses

This section is about matching different kinds of DNS responses with tcpdump.

Matching DNS ServFail Responses

A bit of backgound information on UDP and DNS packets is neccesary for this:

  • The UDP packet header is 8 bytes and tcpdump is counting the bytes from zero when matching, so the DNS packet header begins at "byte number 8" in tcpdump match syntax. See RFC768 for more on UDP packet characteristics.
  • According to rfc1035 (section 4.1.1, page 25), the two first bytes ("number 8 and 9" in tcpdump match syntax) in the DNS header is the transaction ID.
  • The next two bytes ("number 10 and 11" in tcpdump match syntax) make up the flags for the DNS packet. The two bytes contain a lot of information (refer to rfc1035 section 4.1.1, page 26), but for the purpose of matching ServFail responses I only need to check the RCODE field which is contained in the four low bits of the second of the two bytes. Two bytes is 16 bits, so if these two example bytes were the two bytes that make up the DNS flags:
00000000 00001111

I would need to check the four last bits, the 1's in this example.

So to sum up: I need to check the four low bits in byte number 11 of the packet.

According to rfc1035 (section 4.1.1, page 26), an RCODE of decimal 2 (thats binary 0010 in the four low bits of byte 11) means ServFail.

I will check the individual bits that make up the bytes in a packet with tcpdump by using a bit-by-bit "binary AND" against a bitmask. Since the RCODE of the response is only a half-byte, I don't care what the four high bits are, I only care that the four low bits are exactly 0010. This can be checked like so:

  • I want the fifth bit in byte 11 to be 0 in matched packets, that bit is decimal 8 or binary 00001000, so I add 'udp[11] & 8 = 0' to the tcpdump pattern.
  • I want the sixth bit in byte 11 to be 0 in matched packets, that bit is decimal 4 or binary 00000100, so I add 'udp[11] & 4 = 0' to the tcpdump pattern.
  • I want the seventh bit in byte 11 to be 1 in matched packets, that bit is decimal 2 or binary 00000010, so I add 'udp[11] & 2 = 2' to the tcpdump pattern.
  • I want the eigth bit in byte 11 to be 0 in matched packets, that bit is decimal 1 or binary 00000001, so I add 'udp[11] & 1 = 0' to the tcpdump pattern.

So to show only DNS ServFail responses run the following:

tcpdump port 53 and 'udp[11] & 8 = 0' and 'udp[11] & 4 = 0' and 'udp[11] & 2 = 2' and 'udp[11] & 1 = 0'

Summary: The tcpdump pattern to match ServFail responses in the example above matches all four low bits in byte 11 of the UDP packet, and makes sure they are exactly 0010.

Matching other traffic

Spanning Tree

To make tcpdump show only spanning tree packets:

tcpdump ether[14:1] = 0x42

Links

See this page for much more on bit matching with tcpdump.

There is also a bunch of goodies on this page.