SNAPPY: Detecting Rogue and Fake 802.11 Wireless Access Points Through Fingerprinting Beacon Management Frames
Figure 1. Allow me to summarize this blog post with Lego…
I’ve always had a great love of all things wireless/RF for as long as I can remember. The ability to send frames/packets of data out into the world (the airwaves!) for anyone with the right equipment and looking at the right frequency to pluck them out and reconstruct them - amazing! I am still the proud owner of both ORiNOCO Gold and Silver PCMCIA cards, these two bad boys defined wireless hacking back in the early 2000’s.
Now, for probably the first time in nearly two decades, I’ve gone and taken a blue team defence perspective on something. I didn’t intend on it going this way, you know how it is with research, never a straight path. I had a hunch about something, so out came the trusty Alfa cards, with a side order of Wireshark. The next few hours I’d be knee-deep in wireless Management Frames.
The short version of this blog post is that I’ve found a novel technique to detect both rogue and fake 802.11 wireless access points through fingerprinting Beacon Management Frames, and created a tool to do so, called snap.py (Snappy) – the blog post title doesn’t lie! The long version of this blog post is that I didn’t start out that way...
I was actually looking into MAC address randomization, namely in mobile devices.
Just to be inclusive of all audiences here, a quick definition on what a MAC address is, from Wikipedia no less:
“A media access control address (MAC address) is a unique identifier assigned to a network interface controller (NIC) for use as a network address in communications within a network segment. This use is common in most IEEE 802 networking technologies, including Ethernet, Wi-Fi, and Bluetooth. Within the Open Systems Interconnection (OSI) network model, MAC addresses are used in the medium access control protocol sublayer of the data link layer. As typically represented, MAC addresses are recognizable as six groups of two hexadecimal digits, separated by hyphens, colons, or without a separator.
MAC addresses are primarily assigned by device manufacturers, and are therefore often referred to as the burned-in address, or as an Ethernet hardware address, hardware address, or physical address. Each address can be stored in hardware, such as the card's read-only memory, or by a firmware mechanism. Many network interfaces, however, support changing their MAC address. The address typically includes a manufacturer's organizationally unique identifier (OUI). MAC addresses are formed according to the principles of two numbering spaces based on extended unique identifiers (EUIs) managed by the Institute of Electrical and Electronics Engineers (IEEE): EUI-48—which replaces the obsolete term MAC-48—and EUI-64.”
The problem with MAC addresses is that because they are (or were) designed to be permanent like some kind of device tattoo, privacy issues arise. These addresses are unique and therefore could be used to tie them to individuals. In turn, you could then track these devices (the individuals) using 802.11 Probe Requests put out by the devices, which reference their MAC address.
Vendors came up with a MAC randomization feature back in 2014 in an attempt to thwart this kind of tracking of mobile devices. Some vendors/phones vary in how they have been implemented; some will generate new MAC addresses for known networks after 48 hours (Apple), some will generate new ones on every device scan, etc. It wasn’t really until Apple turned this option on by default in iOS 14 (not that long ago in 2020) that it started having an impact. On an iPhone you can find this under ‘Settings’ -> ‘Wi-Fi’ -> select a wireless network -> ‘Private Wi-Fi Address’ option.
My hunch (with my usual red team offensive hat on) was that there is probably a way to use other things in these frames to identify and track users, other than using the MAC address. I started looking at my own Probe Requests on some of my own devices; a selection of iPhone and iPad versions, all with slightly different iOS versions and generations. I was just eyeballing the frames in Wireshark and doing a mental ‘diff’ between them all when I spotted a few things.
The first rule of research club is that surely someone has asked this question or spotted this stuff before, standing on the shoulders of giants and all that. Sure enough, down the rabbit hole I went.
I read a great selection of papers on how MAC address randomization had failed over the years at the hands of security researchers , , , , , , . Researchers had managed to be creative and use a wealth of things in these 802.11 Probe Request Frames to track devices attempting to hide, ranging from timing differences, using and reversing the WPS UUID-E field, to using RF signal strength. Slightly off topic, but I even stumbled upon one crazy paper about using Probe Requests to reveal a person’s trajectory . I was kind of disheartened because it seemed that these researchers had beat me to lots of things I had in mind and was seeing. That was until I stepped back, without the phone that is, no trajectory tracing here…
All these researchers (with the exception of one ) had gone after Probe Requests, focusing on the client, which makes sense, because the problem they have identified and the question they are trying to answer is, can the MAC randomization be circumvented/reversed to track these clients?
No one is looking at the server, perhaps because they don’t think we have a problem in this area.
It is only with my pentester hat on that I’m able to ask a slightly different question, to solve a problem which I know exists in the server realm. Can I switch my initial approach and those research ideas and apply it to the server, aka Beacon Frames, sent out by Access Points? With this, can I then use these things to pick out rogue and fake Access Points?
Let me explain.
The problem users have, especially for those using open wireless networks (coffee shops, supermarkets, etc.) is that it is too easy for an attacker to spin up their own Access Point with the same SSID and to have the users connect to it. The user really doesn’t have any way of knowing they are not on the legitimate one, especially if the attacker is spoofing the legitimate Access Point’s MAC address too. WPA2-PSK networks don’t have the same fate because this attack falls down at the first hurdle because the attacker needs to set the rogue Access Point up with the same passphrase… and if they know that already, then they should probably be at the victim’s house and not at the coffee shop. From a user’s perspective, wouldn’t it be great if we could tell if our local coffee shop’s wireless Access Point is not the same as when we were last in there and is a rogue? Furthermore, wouldn’t it be kind of cool to be able to detect people using airbase-ng, the tool of choice for most fake (software-based) Access Points? Please forgive me, red team gods.
“You have to let it all go, Neo. Fear, doubt, and disbelief. Free your mind.” (Thanks Morpheus)
With a spring in my step, I continued on with my research, Alfa cards at the ready. I pulled a selection of my finest retired/on the bench Access Points out of the hat and captured Beacon Management Frames from each. I was interested in how much they varied. I know a thing or two about 802.11 Management Frames from creating a wireless C2 (called Smuggler) by abusing Information Elements (IE) tags in them back in 2014. See this blog post for more information on that.
Back to the main event. I needed to identify a number of things (elements, parameters, tags, etc.) in the Beacon Frame which were both independently and collectively different between Access Points enough that I could use as some kind of fingerprint to form a signature. It was, however, important that these values remained static to themselves and did not change over time, else having the concept of a signature wouldn’t work.
Figure 2. Tags you’ll likely see inside 802.11 Wireless Beacon Management Frames
Through spending some/a lot of time in Wireshark and scapy, I picked out the following candidates:
Max Transmit Power
I concatenate all the above together and make into a SHA256 hash, not unlike a burrito.
I wanted this to be something useable so I knocked up some code in Python, making use of scapy for the heavy lifting. Below is a snippet of the code.
Figure 3. A snippet of snap.py code
I call the tool snap.py (Snappy) – making use of the word ‘snap’ (as in ‘snapshot’) for the use of this thing and also not at all/only one time heavily influenced by the Python file extension ‘.py’ completing things off perfectly.
The concept of using Snappy is about taking snapshots. You rock up to your local trusted open wireless network you use and you take a ‘snapshot’ of what good looks like. The caveat is you need to make sure when you’re taking this snapshot that you don’t snap what bad looks like, that would be bad. Once you have this snapshot, aka, a SHA256 hash, you store it. You drink your coffee; you get on with your life. A week later, you rock up, repeat the same exercise, check the SHA256 hash matches the one you took before. All good? Connect to it. Bad? Get the latte to go.
Figure 4. Snappy in action, a SHA256 hash created for the wireless access point
Snappy can work either in offline mode (my personal preference) or online/active mode.
In offline mode, you use airodump-ng or whatever your tool of choice is to get your Beacon Frames, save as a .cap/.pcap, and you can load it into Snappy. Snappy will loop through multiple Beacon Frames of different networks if they exist in the capture file and generate hashes, no problemo!
In online mode, Snappy will report (generate a SHA256 hash) in real time on Beacon Frames, again, support for multiple networks.
Notice how I used the term ‘report’ in the last sentence? Well, we set out initially to detect both rogue and fake Access Points. Rogue, ticked. Fake, well that’s usually the result of airbase-ng to create it at a software level. I thought it would be nice (please forgive me once again red team gods!) if we could detect airbase-ng in use.
I reviewed the source code of airbase-ng and also looked at how it in reality presents itself on the wireless side and came up with a few handpicked things to formulate a signature once again.
Figure 5. Airbase-ng uses these hardcoded ‘rates’ and ‘extended rates’
Figure 6. Airbase-ng ‘rates’ and ‘extended rates’, plus short slot time, seen on the wireless side inside the frame
In addition to the normal hash generation, if airbase-ng is detected as responsible for serving the Access Point, you’ll get an additional “******** AIRBASE-NG DETECTED AT THIS ACCESS POINT ********” message attached under the signature. So if you see this message at your first snapshot, maybe think about moving coffee shops going forward.
Figure 7. Snappy running on two wireless access points with airbase-ng being detected on the second
You can download Snappy here
Hopefully you enjoyed my wireless research and find the tool useful.
Thanks for reading!
 Tomas Bravenec, Joaquin Torres-Sospedra, Michael Gould, Tomas Fryza. “Exploration of User Privacy in 802.11 Probe Requests with MAC Address Randomization Using Temporal Pattern Analysis”. June 2022.
 Jeremy Martin and Travis Mayberry and Collin Donahue and Lucas Foppe and Lamont Brown and Chadwick Riggins and Erik C. Rye and Dane Brown. “A Study of MAC Address Randomization in Mobile Devices and When it Fails”. 2017.
 Ivan Vasilevski, Veno Pachovski, Dobre Blaxehevski, Irena Stojmenovska. “Five Years Later: How Effective Is the MAC Randomization in Practice? The No-at-All Attack”. 2019.
 Ellis Fenske, Dane Brown, Jeremy Martin, Travis Mayberry, Peter Ryan and Erik Rye. “Three Years Later: A Study of MAC Address Randomization In Mobile Devices And When It Succeeds”. Proceedings on Privacy Enhancing Technologies; 2021 (3):164-181.
 Vanhoef, Mathy and Matte, Celestin and Cunche, Mathieu and Cardoso, Leonardo S. and Piessens, Frank. "Why MAC Address Randomization is Not Enough: An Analysis of Wi-Fi Network Discovery Mechanisms". Proceedings of the 11th ACM on Asia Conference on Computer and Communications Security. 2016. 413-424 (12).
 Célestin Matte, Mathieu Cunche, Franck Rousseau, Mathy Vanhoef. “Defeating MAC Address Randomization Through Timing Attacks”. ACM WiSec 2016, Jul 2016, Darmstadt, Germany.
 Denton Gentry, Avery Pennarun (Google). “Passive Taxonomy of Wifi Clients using MLME Frame Contents”. 2016.
 Abhishek Kumar Mishra, Aline Carneiro Viana, Nadjib Achir. “Do WiFi Probe-Requests Reveal Your Trajectory?”. HAL Open Science. Dec 2022.
 Bandar Alotaibi, K. Elleithy. “A Passive Fingerprint Technique to Detect Fake Access Points”. 2015.