Tuesday, December 8, 2009

Simplifying libpcap filter creation

Making a capture filter for tcpdump from wireshark has always been a pain in my mind. Maybe there is a nice tool out there to do it for me --- but I really don't know. So the useful syntax for tcpdump is basically:
(network protocol)[offset] == (decimal value)
For instance:
ether[100] == 123 and ether[102] == 124
I mean sure, some wankers probably want to do more with their packets but I'm not one of them. I simply have a typical packet like this:
 0000  02 00 00 00 45 00 02 8a  db 46 40 00 40 06 b0 6c   ....E... .F@.@..l
0010 43 7f e9 5a 4a 7d 35 64 fa 4c 00 50 a0 b6 33 f4 C..ZJ}5d .L.P..3.
0020 6b 36 b9 97 80 18 20 8a ca 1e 00 00 01 01 08 0a k6.... . ........
0030 5b 11 94 89 ca d6 48 ed 47 45 54 20 2f 20 48 54 [.....H. GET / HT
0040 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 67 6f TP/1.1.. Host: go
0050 6f 67 6c 65 2e 63 6f 6d 0d 0a 55 73 65 72 2d 41 ogle.com ..User-A
0060 67 65 6e 74 3a 20 4c 69 6e 6b 73 20 28 32 2e 31 gent: Li nks (2.1
0070 70 72 65 33 37 3b 20 46 72 65 65 42 53 44 20 37 pre37; F reeBSD 7
0080 2e 30 2d 52 45 4c 45 41 53 45 20 69 33 38 36 3b .0-RELEA SE i386;
0090 20 38 30 78 32 34 29 0d 0a 41 63 63 65 70 74 3a 80x24). .Accept:
00a0 20 2a 2f 2a 0d 0a 41 63 63 65 70 74 2d 45 6e 63 */*..Ac cept-Enc
00b0 6f 64 69 6e 67 3a 20 67 7a 69 70 2c 20 64 65 66 oding: g zip, def
00c0 6c 61 74 65 2c 20 62 7a 69 70 32 0d 0a 41 63 63 late, bz ip2..Acc
00d0 65 70 74 2d 43 68 61 72 73 65 74 3a 20 75 73 2d ept-Char set: us-
00e0 61 73 63 69 69 2c 20 49 53 4f 2d 38 38 35 39 2d ascii, I SO-8859-
00f0 31 2c 20 49 53 4f 2d 38 38 35 39 2d 32 2c 20 49 1, ISO-8 859-2, I
0100 53 4f 2d 38 38 35 39 2d 33 2c 20 49 53 4f 2d 38 SO-8859- 3, ISO-8
0110 38 35 39 2d 34 2c 20 49 53 4f 2d 38 38 35 39 2d 859-4, I SO-8859-
0120 35 2c 20 49 53 4f 2d 38 38 35 39 2d 36 2c 20 49 5, ISO-8 859-6, I
0130 53 4f 2d 38 38 35 39 2d 37 2c 20 49 53 4f 2d 38 SO-8859- 7, ISO-8
0140 38 35 39 2d 38 2c 20 49 53 4f 2d 38 38 35 39 2d 859-8, I SO-8859-
0150 39 2c 20 49 53 4f 2d 38 38 35 39 2d 31 30 2c 20 9, ISO-8 859-10,
0160 49 53 4f 2d 38 38 35 39 2d 31 33 2c 20 49 53 4f ISO-8859 -13, ISO
0170 2d 38 38 35 39 2d 31 34 2c 20 49 53 4f 2d 38 38 -8859-14 , ISO-88
0180 35 39 2d 31 35 2c 20 49 53 4f 2d 38 38 35 39 2d 59-15, I SO-8859-
0190 31 36 2c 20 77 69 6e 64 6f 77 73 2d 31 32 35 30 16, wind ows-1250
01a0 2c 20 77 69 6e 64 6f 77 73 2d 31 32 35 31 2c 20 , window s-1251,
01b0 77 69 6e 64 6f 77 73 2d 31 32 35 32 2c 20 77 69 windows- 1252, wi
01c0 6e 64 6f 77 73 2d 31 32 35 36 2c 20 77 69 6e 64 ndows-12 56, wind
01d0 6f 77 73 2d 31 32 35 37 2c 20 63 70 34 33 37 2c ows-1257 , cp437,
01e0 20 63 70 37 33 37 2c 20 63 70 38 35 30 2c 20 63 cp737, cp850, c
01f0 70 38 35 32 2c 20 63 70 38 36 36 2c 20 78 2d 63 p852, cp 866, x-c
0200 70 38 36 36 2d 75 2c 20 78 2d 6d 61 63 2c 20 78 p866-u, x-mac, x
0210 2d 6d 61 63 2d 63 65 2c 20 78 2d 6b 61 6d 2d 63 -mac-ce, x-kam-c
0220 73 2c 20 6b 6f 69 38 2d 72 2c 20 6b 6f 69 38 2d s, koi8- r, koi8-
0230 75 2c 20 6b 6f 69 38 2d 72 75 2c 20 54 43 56 4e u, koi8- ru, TCVN
0240 2d 35 37 31 32 2c 20 56 49 53 43 49 49 2c 20 75 -5712, V ISCII, u
0250 74 66 2d 38 0d 0a 41 63 63 65 70 74 2d 4c 61 6e tf-8..Ac cept-Lan
0260 67 75 61 67 65 3a 20 65 6e 2c 20 2a 3b 71 3d 30 guage: e n, *;q=0
0270 2e 31 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 .1..Conn ection:
0280 4b 65 65 70 2d 41 6c 69 76 65 0d 0a 0d 0a Keep-Ali ve....

And now I want to like, create a libpcap filter on the "GET" to detect whether it's a GET request.

Now I know what the wankers are saying:
"Well, what if this was some crazy ass packet over here with the boundary of one layer of the network stack just happening to translate into the ASCII character 'G' and then say, the signature or magic number of the next layer down translating into 'ET'. THEN WHAT? Then what?"

Um, then, I get those packets too; all zero of them. Really. I mean, get a life. That shit doesn't happen.

So let's go back to the real problem. I want to use wireshark and figure out how to write this ...

So I fire up wireshark and then go to the three pane view. I expand the "Hypertext Transfer Protocol" node, then the "GET" node and right click on "Request Method: GET". I go up to apply as filter then click "selected":

This seems quite reasonable. After clicking on it I do indeed get something in the filter syntax:

Absolutely stunning. I get this:
http.request.method == "GET"
That's not libpcap. Totally not it. You totally lose. I cannot pass that string to tcpdump. Luckily, the wireshark people have a command line capture form of wireshark, called tshark. Fantastic, let's see how to use it! :-)

$ tshark -h
TShark 1.0.3
Dump and analyze network traffic.
See http://www.wireshark.org for more information.

Copyright 1998-2008 Gerald Combs (email withheld by me) and contributors.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Usage: tshark [options] ...

Capture interface:
-i <interface> name or idx of interface (def: first non-loopback)
-f <capture filter> packet filter in libpcap filter syntax
-s <snaplen> packet snapshot length (def: 65535)
-p don't capture in promiscuous mode
-y <link type> link layer type (def: first appropriate)
-D print list of interfaces and exit
-L print list of link-layer types of iface and exit


Great, just great. You can't even accept your own syntax as a capture filter, just as a display one. I'm trying to reduce file size here...

What's the point?


So anyway, to make life easy I did a nice javascript app, as I love to do sooooo much and you can use it here.

So we go back to my initial packet and copy and paste it in the gargantuan textarea and click the only button there 'process'.

After you click on the obvious blue links, something magical starts to happen:


The filter syntax shows up for you. You don't have to play CSI Miami and count the bytes with VB by hand or something any more. Welcome to the 1980s ... you can use a mouse and construct a filter with ease. Enjoy.

It's worth mentioning that there is actually no protocol level analysis being done. If you have a radiotap header, the silly javascript app won't know. If you are listening on a device without an ethernet layer, such as tun0 or tun1, it will also not know. You basically need to be listening on wired ethernet. But that isn't hard now, is it!

No comments:

Post a Comment

Followers