Detectpromisc is a python script based on Scapy, that allows to detect if a computer is sniffing the network.
By nature, it is quite difficult to detect if a machine is sniffing, because it operates passively, receiving all packets from the wire but, normaly, answering only to packets destinated to itself.
There are however several methods that make the detection possible.
Some are based on the latency, because in promiscuous mode a machine will take more time to answer (packets have to be processed by the kernel, not the network card only).
Another imply to generate some tricky packets, with a correct IP but a wrong MAC address. The machine should answer only if it is in spoofing mode.
It is also possible to use source-routing with a host on the path that doesn’t route. If an answer comes back anyway, the target is sniffing.
Other methods are implemented by IDS and based on the volume of DNS requests.
Most of these methods are not necessarily reliable, easy to implement. All the ones based on IP routing are quite easy to workaround by the attacker.
Detectpromisc works exclusively at the ARP level.
According to the OS, it sends out some specific ARP packets (multicast, fake broadcast…).
In normal mode, the network card will discard theses illegitimate packets : they call it the hardware filter.
In promiscuous mode, there is no hardware filter : packets reaches directly the kernel (software filter).
Of course, according to the OS, the kernel will behave differently, but some tricked ARP packets generated by Detectpromisc will cause the sniffing machine to send an answer.
It is therefore possible to differenciate a sniffing machine from a normal machine. Plus, as it is quite reliable and OS specific, it is possible to fingerprint the target.
In practice, it has worked very well so far :
% sudo ./detect.py -i eth0 -O 192.168.222.25 Scan right index finger on UPEK TouchStrip WARNING: No route found for IPv6 destination :: (no default route?) 192.168.222.25 : promiscuous mode card detected probably: Linux 2.2/2.4/2.6 % sudo ./detect.py -i eth0 -O 192.168.222.26 WARNING: No route found for IPv6 destination :: (no default route?) 192.168.222.26 : promiscuous mode card detected probably: Windows 2k/NT4
A full paper on how it works is there. Great tool, isn’t it ?