Capture Filters for Ethereal

This is a primer for designing capture filters for Ethereal/Wireshark. Designing capture filters for Ethereal/Wireshark requires some basic knowledge of tcpdump syntax. The tcpdump man page is your source for complete information regarding syntax and supported primitives. Tcpdump syntax will be the first section covered in this primer. We will use what is covered in this first section to build our basic filter set. Finally, we will enter our filter strings into Ethereal/Wireshark. If you do not want to cover Tcpdump syntax, you might want to skip to the basic filter set. Or, you might just need to know how to enter the filter strings into Ethereal/Wireshark.

Designing the Filters Using Tcpdump Syntax

Tcpdump provides several primitives for easy filter design. Think of a primitive as a macro or keyword for a predefined filter.

Host, Port and Network Filtering

The syntax for host filtering:

Syntax Description
host host host is either the ip address or host name
src host host Capture all packets where host is the source
dst host host Capture all packets where host is the destination
Examples
host 10.10.10.10 Capture all packets to and from 10.10.10.10
src host 10.10.10.10 Capture all packets where 10.10.10.10 is the source
dst host 10.10.10.10 Capture all packets where 10.10.10.10 is the destination

Port filtering:

Syntax Description
port port Capture all packets where port is either the source or destination
src port port Capture all packets where port is the source port
dst port port Capture all packets where port is the destination port
Examples
port 80 Capture all packets where 80 is either the source or destination port
src port 80 Capture all packets where 80 is the source port
dst port 80 Capture all packets where 80 is the destination port

Network filtering:

Syntax Description
net net Capture all packets to/from net
src net net Capture all packets where net is the source
dst net net Capture all packets where net is the destination
Examples
net 192.168 Capture all packets where the network is 192.168.0.0
src net 192.168 Capture all packets where the 192.168.0.0 network is the source
dst net 192.168 Capture all packets where the 192.168.0.0 network is the destination

Protocol Based Filters

Ethernet Based:

Syntax
ether proto \[primitive name]
Examples
ether proto \ip or just ip Capture all ip packets

ether proto \arp or just arp |Capture all address resolution protocol packets | ether proto \rarp or just rarp |Capture all reverse arp packets |

IP Based:

Syntax
ip proto \[primitive name]
Examples
ip proto \tcp or just tcp Capture all TCP segments (packets)
ip proto \udp or just udp Capture all UDP packets
ip proto \icmp or just icmp Capture all ICMP packets

Combining Primitive Expressions

You can combine primitive expressions using the following:

Negation:      ! or not
Concatenation: && or and
Alternation:   || or or 
Examples
host 10.10.10.10 && !net 192.168 Capture all packets to/from 10.10.10.10 that are not to/from 192.168.0.0
host 10.10.10.10 && port 80 Capture all packets to/from 10.10.10.10 and are sourced/destined on 80

You can build very sophisticated capture filters by combining primitive expressions. You can also build filters that will not work. Ethereal/Wireshark will error on some really obvious filter errors.

Consider this filter for example:

host 192.168.1.10 && !host 192.168.1.10   /* Capture all packets to/from 192.168.1.10 and not to/from 192.168.1.10 
Ethereal/Wireshark will error on this filter stating that the expression will reject all packets */ 

However Ethereal/Wireshark will parse this filter even though it will not capture any packets:

host 192.168.1.10 && not net 192.168   /* Capture all packets to/from 192.168.1.10 and not to/from the 192.168 network */ 

The point being sanity check your filters!

Byte Offset Notation:

Filters based on byte offset notation are the most powerful but confusing filters to design. However, once you understand it you will be designing filters to capture ANY kind of packet. Filters based on this notation can capture packets based on any value in any location within the packet. Any of the preceeding filters can be designed with byte offset notation by locating its offset in the appropriate header.

Syntax
proto [Offset in bytes from the start of the header:Number of bytes to check]
Examples
ip[8] Go to byte 8 of the ip header and check one byte (TTL field)
tcp[0:2] Go to the start of the tcp header and check 2 bytes (source port)

Now that we know how to find a value within a packet, we have to do something with the value like compare it to another value.

Tcpdump provides the usual comparison operators:

>, <, >=, <=, =, !=
Examples
ip[8] = 1 Capture all IP packets where the TTL is 1
tcp[0:2] = 80 Capture all tcp segments (packets) where 80 is the source port (this is equivalent to the filter: src port 80)

Tips to help you with byte offset notation:

  1. Remember that the headers start with byte zero.
  2. Always keep a layout of the headers of interest handy when designing filters with byte offset notation (for example: ip,udp,tcp and icmp).
  3. If you don't specify the number of bytes to check, one byte will be checked. You can specify 1,2 or 4 bytes to be checked.
  4. Review the RFCs for IP , TCP , UDP and ICMP

Note: Ethereal/Wireshark defaults to decimal notation. You specify hexadecimal notation by adding 0x to your hex value. There are several times when hex is easier to use (like masking then comparing). As long as you know the offset in the packet and its length, you will be able to design a filter to capture it.

I have compiled a Table of some common packet offsets with filters

You can isolate bits within a packet by using bit masking. If you don't understand masking please refer to Masking the Easy Way.

To check the ip header length field:

ip[0] & 0x0f  /* This instructs Ethereal/Wireshark to look at the first byte */
              /*of the ip header and mask the low order nibble (header length field). */ 

Let's look at this in detail: The first byte of the ip header contains the ip version in the high-order nibble and the ip header length in the low-order nibble. Because we are bringing in a byte, we need to be able to isolate the nibble of interest.

0100 0101 Value of byte 0 in the packet

0000 1111 Our mask

0000 0101 Result

0101b = 5 This tells us that there are 5 32-bit words in the header.

If we wanted to find a packet that had ip options, we could design a filter like:

ip[0] & 0x0f > 5 /* Capture all packets where the ip header length is greater than 5 */ 

Why would you want to capture this? RFC 791 requires support of ip options. However, most garden variety ip packets do not have ip options. If a packet does have options, it is generally considered suspicious.

TCP flags:

Building filters based on tcp flag values can alert you to all sorts of bad or odd traffic. Certain combinations of flags are known to crash some systems. Some recon probes employ illegal/unconventional flag combinations to assist in tcp stack fingerprinting.

The base filter for TCP flags is tcp[13].

The flags (from MSB to LSB) are: Reserved Reserved Urgent Ack Push Reset Syn Fin

A normal syn packet would have a value of 0000 0010b or 0×02.

If you just wanted to capture only syn packets the filter would be:

tcp[13] = 2   /* Capture packets where only the syn bit is set */ 

A filter for all syn packets would then be:

tcp[13] & 0x02 = 2   /* This will capture all packets where the syn bit is set.*/
                     /*This includes syn, syn-ack, etc. As long as a syn bit is set, this filter will capture it.*/ 

Payload matching filters:

This section covers filters designed to match tcp payload. Be careful as libpcap can not guarantee that you are offsetting into the payload of the segment. If tcp options are present in the segment, the offset into the payload will also be off. One thing you can do is add an expression like «or tcp[12] & 0xf0 > 0×50« to the filter. This will bring in tcp segments that have options. It is a trade-off but you will still not have to go through as many packets. The SMTP filter from the basic filter page looks for commands and response codes. This filter is designed to look at the standard offset into the tcp header (tcp[20]) and match the payload with your filter string. You will need to know the hex equivalent of the ascii characters.

The rest of the SMTP commands to be converted are:

Command String/Hex
HELO 0x48454C4F
MAIL 0x4D41494C
RCPT 0×52435054
DATA 0×44415441
RSET 0×52534554
SEND 0x53454E44
SOML 0x534F4D4C
SAML 0x53414D4C
VRFY 0×56524659
EXPN 0x4558504E
NOOP 0x4E4F4F50
QUIT 0×51554954
TURN 0x5455524E

Putting all of this together (including packets with tcp options) in a filter string:

port 25 and (tcp[12] & 0xf0>0x50 or tcp[20:4] = 0x48454C4F or tcp[20:4] = 0x4D41494C or tcp[20:4] = 0x52435054 
or tcp[20:4] = 0x44415441 or   tcp[20:4] = 0x52534554 or tcp[20:4] = 0x53454E44 or tcp[20:4] = 0x534F4D4C 
or tcp[20:4] = 0x53414D4C or tcp[20:4] = 0x56524659 or tcp[20:4] = 0x4558504E or tcp[20:4] = 0x4E4F4F50 
or tcp[20:4] = 0x51554954 or tcp [20:4] = 0x5455524E)

Now the reply/response codes:

221 0×32323120
214 0×32313420
220 0×32323020
221 0×32323420
250 0×32353020
251 0×32353120
354 0×33353420
421 0×34323120
450 0×34353020
451 0×34353120
452 0×34353220
500 0×35303020
501 0×35303120
502 0×35303220
503 0×35303320
504 0×35303420
550 0×35353020
551 0×35353120
552 0×35353220
553 0×35353320
554 0×35353420

SMTP reply filter string (with tcp options):

port 25 and (tcp[12] & 0xf0> 0x50 or tcp[20:4] = 0x32323120 or tcp[20:4] = 0x32323420 or tcp[20:4] = 0x32353020 
or tcp[20:4] = 0x32353120 or tcp[20:4] = 0x33353420 or tcp[20:4] = 0x34323120 or tcp[20:4] = 0x34353020 
or tcp[20:4] = 0x34353120 or tcp[20:4] = 0x34353220 or tcp[20:4] =0x35303020 or tcp[20:4] = 0x35303120 
or tcp[20:4] = 0x35303220 or tcp[20:4] = 0x35303320 or tcp[20:4] = 0x35303420 or tcp[20:4] =0x35353020 
or tcp[20:4] = 0x35353120 or tcp[20:4] = 0x35353220 or tcp[20:4] = 0x35353320 or tcp[20:4] = 0x35353420)

By combining the two filter strings above, you will be able to capture SMTP conversations without pulling in the message data. You may also want to capture connection initiation and tear down. This is easy enough by adding an expression for tcp flags to the above strings.

tcp[13] & 0x02 = 0x02 any with the syn flag set
tcp[13] & 0x01 = 0x01 any with the fin flag set
tcp[13] & 0x04 = 0x04 any with the reset flag set

A more efficient alternative to the three flag filters above is to mask-in the three least significant bits and pull in anything not equal to 0. This is expressed as:

(tcp[13] & 0x07 != 0) 

NOTE: Tcpdump does have tcp flag primitives for all but reserved flag bits. I prefer to use the strings above but you could have written the above flag filters using the flag primitives.

Putting all of this together to form a big filter string:

port 25 and (tcp[12] & 0xf0>0x50 or tcp[13] & 0x07 != 0 or tcp[20:4] = 0x48454C4F or tcp[20:4] = 0x4D41494C or tcp[20:4] = 0x52435054
or tcp[20:4] =0x44415441 or tcp[20:4] = 0x52534554 or tcp[20:4] = 0x53454E44 or tcp[20:4] = 0x534F4D4C or tcp[20:4] = 0x53414D4C 
or tcp[20:4] =0x56524659 or tcp[20:4] = 0x4558504E or tcp[20:4] = 0x4E4F4F50 or tcp[20:4] = 0x51554954 or tcp [20:4] = 0x5455524E 
or tcp[20:4] =0x32323120 or tcp[20:4] = 0x32323420 or tcp[20:4] = 0x32353020 or tcp[20:4] = 0x32353120 or tcp[20:4] = 0x33353420 
or tcp[20:4] =0x34323120 or tcp[20:4] = 0x34353020 or tcp[20:4] = 0x34353120 or tcp[20:4] = 0x34353220 or tcp[20:4] = 0x35303020
or tcp[20:4] =0x35303120 or tcp[20:4] = 0x35303220 or tcp[20:4] = 0x35303320 or tcp[20:4] = 0x35303420 or tcp[20:4] = 0x35353020 
or tcp[20:4] =0x35353120 or tcp[20:4] = 0x35353220 or tcp[20:4] = 0x35353320 or tcp[20:4] = 0x35353420) 

Building a Basic Filter Set

This section will assist you with building your basic filter set.

The basic filter set should include filters to capture packets on well known service ports.

The table below should get you started.

Filter Name Filter String
HTTP_80 port 80
DNS_53 port 53
SMTP_25 port 25
FTP_CMD_21 port 21
TELNET_23 port 23
POP3_110 port 110
IMAP_143 port 143
NNTP_119 port 119
LDAP_389 port 389
NCP_524 port 524
SNMP_161_162 port 161 or port 162
Netbios_SMB_137_138_139 port 137 or port 138 or port 139
Host based filtering host Enter the ip address or hostname after host
Port based filtering port Enter the port number after port
IP Fragmentation ip[6:2] & 0×2000 = 0×2000 or ip[6:2] & 0x1fff !=0×0000
IP_All ip
TCP_All tcp
UDP_All udp
ARP_Ether arp
ICMP_ALL icmp
ICMP_ping icmp[0]= 0 or icmp[0]= 8
ICMP_noPing icmp[0]!= 0 and icmp[0]!= 8
IGMP ip[9] = 2
EGP ip[9] = 8
Multicast net 224.0.0
Multicast ip multicast
Multicast ether multicast

Advanced Filters

SMTP

SMTP Commands - HELO, MAIL,RCPT,DATA,RSET,SEND,SOML,SAML,VRFY,EXPN,NOOP,QUIT AND TURN

port 25 and (tcp[12] & 0xf0 > 0x50 or tcp[20:4] = 0x48454C4F or tcp[20:4] = 0x4D41494C or tcp[20:4] = 0x52435054 
or tcp[20:4] = 0x44415441 or tcp[20:4] = 0x52534554 or tcp[20:4] = 0x53454E44 or tcp[20:4] = 0x534F4D4C
or tcp[20:4] = 0x53414D4C or tcp[20:4] = 0x56524659 or tcp[20:4] = 0x4558504E or tcp[20:4] = 0x4E4F4F50
or tcp[20:4] = 0x51554954 or tcp [20:4] = 0x5455524E) 

SMTP Reply/response codes - 221,214,220,221,250,251,354,421,450,451,452,500,501,502,503,504,550,551,552,553 and 554

port 25 and (tcp[12] & 0xf0 > 0x50 or tcp[20:4] = 0x32323120 or tcp[20:4] = 0x32323420 or tcp[20:4] = 0x32353020
or tcp[20:4] = 0x32353120 or tcp[20:4] = 0x33353420 or tcp[20:4] = 0x34323120 or tcp[20:4] = 0x34353020
or tcp[20:4] = 0x34353120 or tcp[20:4] = 0x34353220 or tcp[20:4] = 0x35303020 or tcp[20:4] = 0x35303120
or tcp[20:4] = 0x35303220 or tcp[20:4] = 0x35303320 or tcp[20:4] = 0x35303420 or tcp[20:4] = 0x35353020
or tcp[20:4] = 0x35353120 or tcp[20:4] = 0x35353220 or tcp[20:4] = 0x35353320 or tcp[20:4] = 0x35353420) 

SMTP Commands and reply (combination of the two above with tcp options, syn, fin, or reset flag set)

port 25 and (tcp[12] & 0xf0 > 0x50 or tcp[13] & 0x07 != 0 or tcp[20:4] = 0x48454C4F or tcp[20:4] = 0x4D41494C
or tcp[20:4] = 0x52435054 or tcp[20:4] = 0x44415441 or tcp[20:4] = 0x52534554 or tcp[20:4] = 0x53454E44
or tcp[20:4] = 0x534F4D4C or tcp[20:4] = 0x53414D4C or tcp[20:4] = 0x56524659 or tcp[20:4] = 0x4558504E
or tcp[20:4] = 0x4E4F4F50 or tcp[20:4] = 0x51554954 or tcp [20:4] = 0x5455524E or tcp[20:4] = 0x32323120
or tcp[20:4] = 0x32323420 or tcp[20:4] = 0x32353020 or tcp[20:4] = 0x32353120 or tcp[20:4] = 0x33353420
or tcp[20:4] = 0x34323120 or tcp[20:4] = 0x34353020 or tcp[20:4] = 0x34353120 or tcp[20:4] = 0x34353220
or tcp[20:4] = 0x35303020 or tcp[20:4] = 0x35303120 or tcp[20:4] = 0x35303220 or tcp[20:4] = 0x35303320
or tcp[20:4] = 0x35303420 or tcp[20:4] = 0x35353020 or tcp[20:4] = 0x35353120 or tcp[20:4] = 0x35353220
or tcp[20:4] = 0x35353320 or tcp[20:4] = 0x35353420) 

NOTE: These SMTP filters will also capture any packets to/from port 25 with tcp options. If you want to see how to build these filters, please refer to payload filtering.

Links

Appendix

Table of some common packet offsets with filters

Field Length(bits) Tcpdump Filter
IP Header Length 4 ip[0] & 0x0f
IP Packet Length 16 ip[2:2]
IP TTL 8 ip[8]
IP Protocol 8 ip[9]
IP Address Source 32 ip[12:4]
IP Address Destination 32 ip[16:4]
IP Fragmentation flag = 3 and Offset = 13 ip[6:2] & 0×2000 = 0×2000 or ip[6:2] & 0x1fff !=0×0000
TCP Source Port 16 tcp[0:2]
TCP Destination Port 16 tcp[2:2]
TCP Header Length 4 tcp[12] & 0xf0
TCP Flags 8 tcp[13]
TCP Window Size 16 tcp[14:2]
ICMP Type 8 icmp[0]
ICMP Code 8 icmp[1]

Masking the Easy Way

Masking allows us to isolate individual bits within the packet. It is based on an AND operator. The way an AND operator works is very simple so let's start with it. If you are comparing two bits together (A and B) with an AND operator. You can have four possible results or states. Here is the truth table so you can see this:

A B Result Explanation
0 0 0 If A and B are zero the result is zero
0 1 0 If A is zero and B is 1 the result is zero
1 0 0 If A is 1 and B is zero the result is zero
1 1 1 If A is 1 and B is 1 the result is 1

The only result that has a 1 is when both A and B are 1. Masking uses this by comparing a 1 (masking-in) with the bit of interest and comparing the rest of the bits with a zero (masking-out).

Let's look at an example: Say you have a four bit value (nibble) but you only care if the most significant bit (MSB) is 1. You would mask this nibble with 1000 binary (b) so that anything other than the MSB will be zero. Here is a table so you can see this:

The nibble is 1010b and our mask is 1000b

1 0 1 0 Nibble of Interest
1 0 0 0 Our mask
1 0 0 0 Result

What if our nibble was 0110b ?

Nibble 0110b

Mask 10000

1 1 0 0 Nibble of Interest
1 0 0 0 Our mask
0 0 0 0 Result

The result in the above examples depended on the value of the MSB of our nibble of interest. The rest of the bits were «zeroed» or «masked-out» by the mask.

ASCII - HEX Conversion Table

Numbers
0 0×30
1 0×31
2 0×32
3 0×33
4 0×34
5 0×35
6 0×36
7 0×37
8 0×38
9 0×39
Capital Letters
A 0×41
B 0×42
C 0×43
D 0×44
E 0×45
F 0×46
G 0×47
H 0×48
I 0×49
J 0x4A
K 0x4B
L 0x4C
M 0x4D
N 0x4E
O 0x4F
P 0×50
Q 0×51
R 0×52
S 0×53
T 0×54
U 0×55
V 0×56
W 0×57
X 0×58
Y 0×59
Z 0x5A
Space 0×20
 
info/networking/ether-cap-filters.txt · Последние изменения: 2008/09/24 01:34 От dant
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki