Wireshark-users: Re: [Wireshark-users] capture filter

From: Sake Blok <sake@xxxxxxxxxx>
Date: Tue, 7 Feb 2012 13:19:16 +0100
On 7 feb 2012, at 12:48, julius wrote:

To answer yur second question first:

> and why is it that capture filters do differ from display filters?

Capture filters need to take as little (CPU) time as possible to be able to capture on high speed networks without having to discard packets. That's why they use the BPF engine which runs in the kernel. The BPF engine is limited in its possibilities in favor of being very fast.

Display filters are very powerful as they take advantage of the full dissection of packets. Including re-assembly and decompression for instance.

> i found this ftp filter on the wireshark mailing list:
> 
> tshark -r ftp.pcap -R "(ftp.response.code == 230 || ftp.request.command
> == "PASS") || (ftp.request.command == "USER")"
> 
> in combination with this:
> tshark -w ftp.capture -f "host SOMEIP"
> 
> it works, but how do you combine these two to only capture the ftp login attempts?

Assuming the FTP requests and responses are always at the beginning of the TCP payload, you can create a capture filter to check for the strings "230", "PASS" and "USER" at the beginning of the TCP payload.

Since the TCP header can be of variable length, we first need to find the offset at which the TCP payload begins. This can be done with the following:

tcp[12:1] & 0xf0) >> 2

Which means, take the value at offset 12 in the TCP header (tcp[12:1]) and only use the higher 4 bits (& 0xf0). Normally this value should be devided by 16 to get the proper value, but since the resulting value is the TCP header length in words (32 bits), we need to multiply the result by 4. So, we can just divide the result by 4 to get the offset in octets.

Now all we need to do is take 4 octets and compare them with "USER" (hex  0x55534552) or "PASS" (hex 0x50415353) like this:

tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x55534552 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x50415353

For the "230" part it gets a little more complicated as BPF can only read 1 octet, 2 octets or 4 octets, not 3. So we can use the following:

tcp[((tcp[12:1] & 0xf0) >> 2):4] & 0xffffff00 = 0x32333000

So in total:

tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x55534552 or tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x50415353 or tcp[((tcp[12:1] & 0xf0) >> 2):4] & 0xffffff00 = 0x32333000

Hope this helps,
Cheers,

Sake