Recently in a discussion relating to BPF filters a colleague (thanks Jamie) sent me the link (http://www.tcpdump.org/papers/bpf-usenix93.pdf). However, I figured I would get around to reading it eventually. While addressing some other issues, Brian Dyson on the SANS mailing list suggested I look at the debug option of tcpdump (tcpdump -d) to verify the filter is working. He also provided an example so I can get started. I must admit, I was shocked to see the debug option. I mean, I use tcpdump on a regular basis. I even go through the man pages if I need to verify something. However, for whatever reason, I never noticed and or used the debug option. So I decided to dig (sorry debug) a little deeper.
So without further ado, let's walk through 2 examples
Example 1
let's try a filter that only shows traffic for host 10.0.0.1
root@securitynik:~# tcpdump -d host 10.0.0.1
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 6
(002) ld [26]
(003) jeq #0xa000001 jt 12 jf 4
(004) ld [30]
(005) jeq #0xa000001 jt 12 jf 13
(006) jeq #0x806 jt 8 jf 7
(007) jeq #0x8035 jt 8 jf 13
(008) ld [28]
(009) jeq #0xa000001 jt 12 jf 10
(010) ld [38]
(011) jeq #0xa000001 jt 12 jf 13
(012) ret #65535
(013) ret #0
Let's break this down
(000) ldh [12]
This says to load a half word (2 bytes) for the EtherType at offset 12.
(001) jeq #0x800 jt 2 jf 6
If an EtherType of 0x0800 (IP) is detected, then jump to 2 else jump 6
Let's assume Ethertype 0x0800 is detected, so let's jump to 2.
(002) ld [26]
At offset 26, we will load a word (4 bytes) for our source IP.
(003) jeq #0xa000001 jt 12 jf 4
If the 4 bytes allocated in (002) equals source IP 0xa000001 (10.0.0.1) then jump to 12 if not jump to 4.
When we jump to 12 we see - (012) ret #65535. This basically says to capture all traffic.
If the packet contains a source IP of 10.0.0.1, we should be seeing traffic on the screen or being written to a file.
However, if (003) was false, we would then need to move to 4. Let's do that.
(004) ld [30]
At offset 30, we will load a word (4 bytes) for our destination IP
(005) jeq #0xa000001 jt 12 jf 13
If the 4 bytes allocated in 4 equals destination IP 0xa000001 (10.0.0.1) then jump to 12 if not jump to 13.
When we jump to 12 we see - (012) ret #65535. This basically says to capture all traffic.
This time, if the destination has IP 10.0.0.1, we should be seeing traffic on the screen or being written to a file.
So if (005) was false, we would then need to move to 13 - (013) ret #0. At this point there is no data to return as the return pointer is 0
(006) jeq #0x806 jt 8 jf 7
If the half word (2 bytes) allocated in (000) eq 0x0806 - ARP - then jump to 8 if this is not so, then jump to 7
(007) jeq #0x8035 jt 8 jf 13
if the half word (2 bytes) allocated in (000) eq 0x8035 - RARP - then jump to 8 if this is not so, then jump to 13
(008) ld [28]
At offset 28, we will load a word (4 bytes) for checking the source ARP/RARP value
(009) jeq #0xa000001 jt 12 jf 10
If the 4 bytes allocated for ARP/RARP source address in (008) equals 0xa000001 then jump to 12 if not jump to 10
(010) ld [38]
At offset 38, we will load a word (4 bytes) for checking the destination ARP/RARP value
(011) jeq #0xa000001 jt 12 jf 13
If the 4 bytes allocated for ARP/RARP destination address in (008) equals 0xa000001 then jump to 12 if not jump to 10
(012) ret #65535
This says to return 65535 Bytes, virtually all traffic
(013) ret #0
This says return 0 bytes as this would be false
example 2
What does it look like when we would not like to see traffic from host 10.0.0.1
root@securitynik:~# tcpdump -d not host 10.0.0.1
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 6
(002) ld [26]
(003) jeq #0xa000001 jt 12 jf 4
(004) ld [30]
(005) jeq #0xa000001 jt 12 jf 13
(006) jeq #0x806 jt 8 jf 7
(007) jeq #0x8035 jt 8 jf 13
(008) ld [28]
(009) jeq #0xa000001 jt 12 jf 10
(010) ld [38]
(011) jeq #0xa000001 jt 12 jf 13
(012) ret #0
(013) ret #65535
Basically this seems to go through the same process. However, the differences can be seen at (012) and (013). In the case of not, (012) returns 0 bytes while (013) returns all other traffic.
The above definitely gave me a new perspective on tcpdump. As the title of the blog states, "Learning By Practising" so if someone reading this blog thinks I missed something, please feel free to drop me a comment so I can make any necessary corrections.
Additional Readings:
http://www.tcpdump.org/manpages/tcpdump.1.html
https://www.kernel.org/doc/Documentation/networking/filter.txt
http://en.wikipedia.org/wiki/EtherType
http://docs.oracle.com/cd/E19455-01/806-3773/806-3773.pdf
http://www.linuxalgorithm.com/1607463/
No comments:
Post a Comment