Graphically Plotting Wifi Traffic

This is going to be a down and dirty post about about using neo4j to graphically plot and analyze the relationships between Wi-fi nodes using the air around us. This is not anything new or novel. Sensepost released their Snoopy platform back in ~2012 that does largely the same thing using Patvera’s Maltego. This shows some of the powerful insights that you can create by using a few lines of code, and a graphing database.


Technology Stack

We’ll be using Python and Scapy for packet capture along with Mongodb and mongoengine as a backend for correlating results based on events. Unless you have a hefty tower that will be capable of running both the neo4j, and the compute intensive javascript (in browser) interface, then I suggest installing neo4j on a server or cloud environment.

For information on installing neo4j on Ubuntu, the following tutorial has detailed instructions. Instead of exposing ports to the public, I simply open up a few SSH local tunnels. You can learn more about SSH tunnels on the SSH Cheatsheet.

Wi-fi Card - Supports Monitor Mode

I’m not going to get into depth about picking a wireless card. For this, you simply need to be able to enable monitor mode for sniffing capabilities. Feel free to do some research on cards, if you don’t already have one. I’ll personally recommend the following two cards, as I have used them actively in the past.

Packets of Interest

Our Python script works by logging information about the following packet types.

  • Beacons
  • Probes
  • Responses
  • Data

By correlating the MAC addresses, timing, and other data, it’s possible to draw very interesting relationships between devices and surrounding network topologies. While many devices spoof their MAC address while beaconing, there has been a lot of research into defeating the randomization through additional tags, timing attacks, and UUID-e reversals. See the references below for more information on these techniques. None of these attacks are implemented in the following code!


We’ll also need to install Aircrack-ng. If you’re running Debian/Ubuntu, it should be in your repositories.

sudo apt-get install aircrack-ng

Go ahead and create a new directory for this project named wispy. We’ll also setup a virtualenv for installing the required libraries.

mkdir wispy && cd wispy
virtualenv -p python3 ./env
. ./env/bin/activate
git clone
cd wispy
pip install -r requirements.txt

Start Capturing

Use ifconfig or iwconfig to find your wireless device that you wish to place in monitor mode and issue the following command (replacing wlan0 with your wireless device name). This will open up a new interface named mon0, which listens to by default.

sudo airmon-ng start wlan0

Using scapy to live scrap traffic requires root privileges. You can easily execute a command using the appropriate virtualenv without activating it as root. Simply refer to the specific python binary location.

sudo ../env/bin/python ./

Querying the Dataset

Neo4j uses a graph database query language called Cypher. Using simple syntax, it’s possible to generate dynamic images of active devices in our area. The official documentation is the best direct reference for learning how to make the most of our dataset. I’ll leave a few quick queries for you to play with to get you started.

Assuming you tunneled or setup neo4j locally, simply point your browser to

Match devices from specific vendor

MATCH p=(d:Device)-[]-() WHERE d.vendor = 'Raspberry Pi Foundation' RETURN p

Match up to third degree relations (Based on day)

MATCH p=(ssid:Device)-[r*1..3]-() WHERE ssid.last_seen =~ '2018-04-13.*' RETURN p

Match up to third degree relations (Exclude blank SSID probes)

MATCH p=(s:SSID)-[r*1..3]-() WHERE s.ssid <> '' RETURN p LIMIT 2000

Match up to third degree relations (Including blank SSID probes)

MATCH p=(s:SSID)-[r*1..3]-() WHERE s.ssid <> '' RETURN p LIMIT 2000


comments powered by Disqus