In the network forensics portion of my
Network Security Operations class I cover a variety of reasons to validate that one's tools operate as expected. I encountered another example of this today while capturing network traffic from a wireless adapter.
I explained
several months ago how I use the
ndis0 interface with a Linksys WPC54G adapter. This is a wrapper for the Windows driver packaged with the NIC.
Here I am pinging another wireless host.
$ ping -c 3 192.168.2.31
PING 192.168.2.31 (192.168.2.31): 56 data bytes
64 bytes from 192.168.2.31: icmp_seq=0 ttl=128 time=71.342 ms
64 bytes from 192.168.2.31: icmp_seq=1 ttl=128 time=95.017 ms
64 bytes from 192.168.2.31: icmp_seq=2 ttl=128 time=15.499 ms
--- 192.168.2.31 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
No problems, right? Now I start Tcpdump in another window, and ping again. First, the ping results.
$ ping -c 3 192.168.2.31
PING 192.168.2.31 (192.168.2.31): 56 data bytes
64 bytes from 192.168.2.31: icmp_seq=0 ttl=128 time=44.392 ms
64 bytes from 192.168.2.31: icmp_seq=0 ttl=128 time=45.865 ms (DUP!)
64 bytes from 192.168.2.31: icmp_seq=1 ttl=128 time=66.001 ms
64 bytes from 192.168.2.31: icmp_seq=1 ttl=128 time=66.273 ms (DUP!)
64 bytes from 192.168.2.31: icmp_seq=2 ttl=128 time=88.457 ms
--- 192.168.2.31 ping statistics ---
3 packets transmitted, 3 packets received, +2 duplicates, 0% packet loss
round-trip min/avg/max/stddev = 44.392/62.198/88.457/16.152 ms
What? Why the dupes? Here is what Tcpdump saw:
$ sudo tcpdump -n -i ndis0 -s 1515 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ndis0, link-type EN10MB (Ethernet), capture size 1515 bytes
09:37:26.226020 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 0, length 64
09:37:26.268487 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 0, length 64
09:37:26.270302 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 0, length 64
09:37:26.271772 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 0, length 64
09:37:27.227215 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 1, length 64
09:37:27.292627 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 1, length 64
09:37:27.293116 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 1, length 64
09:37:27.293409 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 1, length 64
09:37:28.228061 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 2, length 64
09:37:28.316227 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 45571, seq 2, length 64
09:37:28.316428 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 2, length 64
09:37:28.316718 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 45571, seq 2, length 64
^C
12 packets captured
38 packets received by filter
0 packets dropped by kernel
I sniffed traffic on 192.168.2.31, and that box did not see nor send duplicates.
I had no idea what was happening. Then I remembered a recent
Undeadly.org story about compromising Windows systems through their wireless drivers. I realized my ndis0 interface is just a wrapper for the potentially lousy Windows driver shipped with the wireless NIC.
I have a second idea. Perhaps Tcpdump should not be in promiscuous mode when capturing wireless traffic? I've encountered issues with this on Windows XP, namely Ethereal/Wireshark recommends disabling promiscuous mode when capturing wireless traffic. Let's see what happens if I ping again while sniffing with -p.
$ ping -c 3 192.168.2.31
PING 192.168.2.31 (192.168.2.31): 56 data bytes
64 bytes from 192.168.2.31: icmp_seq=0 ttl=128 time=447.891 ms
64 bytes from 192.168.2.31: icmp_seq=1 ttl=128 time=105.004 ms
64 bytes from 192.168.2.31: icmp_seq=2 ttl=128 time=22.260 ms
--- 192.168.2.31 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 22.260/191.718/447.891/184.264 ms
Looks good. Here's Tcpdump's view.
$ sudo tcpdump -n -i ndis0 -s 1515 -p icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ndis0, link-type EN10MB (Ethernet), capture size 1515 bytes
09:42:00.415428 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 49411, seq 0, length 64
09:42:00.863206 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 49411, seq 0, length 64
09:42:01.416462 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 49411, seq 1, length 64
09:42:01.521373 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 49411, seq 1, length 64
09:42:02.417306 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 49411, seq 2, length 64
09:42:02.439481 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 49411, seq 2, length 64
^C
6 packets captured
38 packets received by filter
0 packets dropped by kernel
There it is. So, if I don't want to see duplicate traffic, I should disable promiscuous mode.
There's one more wrinkle, though. If I ping a wired host from this wireless host, I don't see duplicates.
$ ping -c 3 192.168.2.12
PING 192.168.2.12 (192.168.2.12): 56 data bytes
64 bytes from 192.168.2.12: icmp_seq=0 ttl=64 time=4.044 ms
64 bytes from 192.168.2.12: icmp_seq=1 ttl=64 time=1.060 ms
64 bytes from 192.168.2.12: icmp_seq=2 ttl=64 time=0.987 ms
--- 192.168.2.12 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.987/2.030/4.044/1.424 ms
Now Tcpdump's view:
$ sudo tcpdump -n -i ndis0 -s 1515 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ndis0, link-type EN10MB (Ethernet), capture size 1515 bytes
09:44:27.934368 IP 192.168.2.5 > 192.168.2.12: ICMP echo request, id 53763, seq 0, length 64
09:44:27.938290 IP 192.168.2.12 > 192.168.2.5: ICMP echo reply, id 53763, seq 0, length 64
09:44:28.934994 IP 192.168.2.5 > 192.168.2.12: ICMP echo request, id 53763, seq 1, length 64
09:44:28.935969 IP 192.168.2.12 > 192.168.2.5: ICMP echo reply, id 53763, seq 1, length 64
09:44:29.935846 IP 192.168.2.5 > 192.168.2.12: ICMP echo request, id 53763, seq 2, length 64
09:44:29.936732 IP 192.168.2.12 > 192.168.2.5: ICMP echo reply, id 53763, seq 2, length 64
^C
6 packets captured
10 packets received by filter
0 packets dropped by kernel
Weird.
For one last idea I tested capture using the native wi0 driver and an older 802.11b SMC NIC. Here I ping while sniffing in promiscuous mode:
$ ping -c 3 192.168.2.31
PING 192.168.2.31 (192.168.2.31): 56 data bytes
64 bytes from 192.168.2.31: icmp_seq=0 ttl=128 time=95.359 ms
64 bytes from 192.168.2.31: icmp_seq=1 ttl=128 time=16.461 ms
64 bytes from 192.168.2.31: icmp_seq=2 ttl=128 time=39.406 ms
--- 192.168.2.31 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 16.461/50.409/95.359/33.136 ms
No problem. Tcpdump's view:
$ sudo tcpdump -n -i wi0 -s 1515 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wi0, link-type EN10MB (Ethernet), capture size 1515 bytes
09:46:57.049509 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 62723, seq 0, length 64
09:46:57.144750 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 62723, seq 0, length 64
09:46:58.050287 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 62723, seq 1, length 64
09:46:58.066660 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 62723, seq 1, length 64
09:46:59.051137 IP 192.168.2.5 > 192.168.2.31: ICMP echo request, id 62723, seq 2, length 64
09:46:59.090452 IP 192.168.2.31 > 192.168.2.5: ICMP echo reply, id 62723, seq 2, length 64
^C
6 packets captured
181 packets received by filter
0 packets dropped by kernel
The issue must be the NIC driver.
This affects the captures I posted when I tested
SinFP. Those duplicates must have been introduced by my NIC driver, Gomor.
The bottom line is you have to know your tools.