In the past month or two, someone has spray painted the brick wall outside my apartment building with graffiti three separate times, after being painted over each time. After the third time I thought it might be worth investing some energy into catching them. The obvious first thought was to set up a camera. But beyond that I started to think how easy it migtht be to refute video evidence, especially at night with a low quality camera. What else could we do to link the person to the crime?
My immediate next thought was capturing people's WiFi MAC addresses. If shopping malls can do it, so can anyone.
I have a desktop linux machine that is very close to the outside wall, so I started by putting my WiFi chip into monitor mode. Something like this:
$ iwconfig wlan0 mode monitor
After this, I used the command line version of wireshark, tshark, to capture WiFi packets and output them. If you do this, you can see that in an area with moderate WiFi usage or number of access points, there are dozens of WiFi packets visible to you every second.
802.11 Probe Request Frame
The most interesting WiFi packet to us in this case is the Probe Request Frame. This packet is sent out by smartphones, laptops, and other devices that are not currently connected to a WiFi network. Most Android and iPhone devices send out this request every 40 to 60 seconds, which makes using these to track the movement of people specifically useful. I should note that there is no location information embedded into these packets. We just know, that if we recieved a probe request from a certain device, it is within a certain distance of the monitoring chip.
Another interesting piece of information embedded in probe requests is an SSID. A device that is not connected to any network will send out a probe request frame to not only the general public, but also targeting specific access points: the remembered devices. For example, when you are at home, let's say you connect to your home WiFi network called "HOME". When you are not connected to HOME, a probe request is broadcasted with the SSID "HOME" embedded in it. So not only can we tell that a certain device is within a certain amount of distance from our WiFi chip, we now also know their devices remembered networks. This is a commonly criticized "vulnerability." In our case, though, it's particiularly useful in uniquely identifying someone.
As you can probably put together, this is how your device knows to connect to a given network automatically once it is in reach.
There are a lot of tools out there that allow you to filter by probe requests and output them, but none of them really met my needs. I was going to specifically need to log all probe requests over a long period of time, days, or even weeks. So I used python and scapy to build a command line tool to record the probe requests. Scapy is probably the easiest way to build your own sniffing tools.
In their own words:
Scapy is a powerful interactive packet manipulation program. It is able to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more.
With the Scapy API, you basically call the
sniff API, which then calls a user-defined callback for every packet recieved.
We simply filter by management frame (probe request is a management frame (0x00), as per the wiki provided earlier), and probe request (subtype 0x04).
if packet.type == 0 && packet.subtype == 0x04: # process packet
From here we look up the MAC address in the EUI database, and log all of the information to a rotating buffer.
The probemon command line call looks like this:
$ python probemon.py -i wlan0 -t unix -o . -f -s
The output in the logs looks something like this:
2015-01-15T00:08:10.277706|60:6c:66:25:##:##|Intel Corporate| 2015-01-15T00:08:11.343672|80:d2:1d:18:##:##|AzureWave Technologies, Inc|2WIRE234
You can find the source code to probemon here. I would have loved to have spent the time to implement this directly in C, but I was worried I would spend too much time and miss the graffiti artist once again.
It's super easy to record sensitive WiFi packets for the people around you. If you need to track someone for any reasons, this isn't a bad way to get the job done. I'll be sure to follow up if I end up catching the spray painting kid.
Update (June 26 2016)
probemon has been updated to support RSSI (signal strength), making the supported fields:
- mac address
- mac address info (manufacturer)
- rssi / signal strength