Saturday, 21 April 2018

Scapy 802.11 Cheat Sheet

I've been taking a look at Scapy as I've been learning more about Python. It's a great Python-based tool for capturing, analyzing and creating network packets. There are some great resources to learn more bout Scapy, and even some cheat sheets out there.

But, as there were quite a few new concepts (for me) and my own interest is in Scapy for 802.11 related activities, I put together my own Scapy for 802.11 cheat sheet. You can grab a copy from here if it may be useful to you.


Friday, 6 April 2018

Randomized MAC addresses in 802.11 Probe Frames

To address perceived privacy issues, some wireless clients adopt a randomized MAC address in probe frames when probing  for wireless networks. In this post  I take a quick look at how you might see clients using randomized MAC addresses. 


When a wireless LAN client needs to find a nearby access point to join a Wi-Fi network, it has two choices:

  • Passive scanning: a client will listen to beacon frames, broadcast by nearby access points, that advertise networks that it makes available. This can be quite a slow process, as a client cycles though channels and waits to hear beacons.
  • Active scanning: a client will cycle through channels and send out probe frames to proactively query nearby APs for a specific wireless network (SSID). This will generally be a faster method of finding networks that the client is configured to join, and may be used by all clients in conjunction with passive scanning.

One (unfortunate) side-effect of active scanning is that a client advertises its presence to anyone listening for probe requests in the vicinity. Even if the client is unsuccessful in finding and joining a network, it advertises its presence by continually probing for networks that it has been configured to join. The MAC address of the probing client’s wireless NIC is present, in the clear, in every probe request. 

The availability of the client MAC address, which is unique to that client, presents some potential privacy issues. Organisations that have wireless networks in multiple locations could, in theory, track the location of the client as it moves between sites. When coupled with other data sources (e.g. a login to a guest wireless portal for instance), it could allow tracking of an individual and gathering of behavioural data.

In order to combat these privacy concerns, some client vendors have taken the decision to randomise the MAC addresses that are used when probing for networks. This ensures that a client cannot easily be tracked as it moves between locations. Clients may use a randomised address to discover networks, but then revert to their “real” MAC address once they choose to join a network.


Although I’ve read about this behaviour, I’d never observed it first-hand. However, I recently spotted it, by accident, while testing some wireless tools. The tool that I was looking at was the ‘airodump-ng’ tool, which is part of the ‘Aircrack’ toolset. Aircrack is a suite of Linux-based pen-testing tools.

Airodump-ng is a wireless scanner that reports wireless networks, detected via beacons, from nearby access points. It also reports clients that can be heard probing in the vicinity. A screen-shot of the tool is shown below -  the top of the display shows the detected networks (discovered via beacons), the lower part of the display shows the clients (also know as stations) that can be heard probing.

Airodump-ng is generally used to scan across multiple channels to gather network and client data. However, it may also be configured to scan on a single channel of interest.

During my testing, I configured to my airodump-ng machine to scan on channel 52, as I knew there was an AP nearby using that channel. However, I noticed that in addition to the network I expected to see, I saw a client probing for a network called “Hidden _SSID”. This is a non-existent network that I had configured on my nearby MacBook Pro while doing some testing earlier in the day. I noticed, however, that the MAC address of the probing client was different to the actual MAC address of my MBP. 

I disabled and re-enabled my MBP wireless adapter several times. Each time I did this, a new MAC address appeared in the airodump-ng client list as the MBP probed with a new, randomised, MAC address. This is Apple MAC address randomization in action. You can see the effect in the screen-shot below:     

This is an interesting demonstration of the randomised client behaviour employed by Apple devices (among others). I thought this post might be useful for others who have not observed this feature, or perhaps aren’t aware that some clients exhibit this behaviour. 

I tried looking up some of the OUIs used in the randomized addresses using the online Wireshark OUI checker, but none of them corresponded with known manufacturer OUIs. The MAC addresses observed didn’t seem to be derived in any obvious way from the true MAC address of the MBP, they appear to be completely randomised.


** Update 7th Apr 2018

I received a Tweet from Arsen Bandurian about the randomized MAC addresses used by the Apple devices:

As he correctly states, the randomized MAC addresses being used are locally administered MAC addresses.  You can recognize a locally administered address by inspecting the 2nd least significant bit of the 2nd byte of the MAC address. This explains why I would never have seen any hits in the OUI lookup tool.   Thanks Arsen!

(If you got to the end of this article without falling to sleep, you did jolly well...)

Sunday, 1 April 2018

Wireshark Capture Filters for 802.11

Generally, when performing over the air captures of WLAN traffic with Wireshark, the workflow adopted is as follows:

  • pick a specific channel where target traffic resides
  • switch the capture adapter to that channel
  • capture all 802.11 traffic over the air on that channel
Once a sample of traffic has been captured, the capture is stopped and analysis of the traffic using Wireshark's built-in display filters can begin.

In most situations, this is the best workflow to adopt. It ensures that all required frames are captured. Filtering wireless traffic while capturing frames is very problematic due to the complexity of 802.11 frame exchanges. It is very easy to miss parts of interactions between stations if you filter traffic as it is being captured.

However, there are a few edge cases where it may be useful to filter over-the-air frames at the point of capture. This will mean that only the filtered frames are available to display in Wireshark - all other frames are lost - but in some rare cases, this may be what you want.

Capture filters are added prior to commencing an over the air capture with Wireshark, as shown in the screen-shot below (see green highlighted text):

(Note that if the capture filter text is highlighted in red (rather than the green shown above), then there is an issue with your filter that needs fixing. You can access the screen display shown above via the Wireshark menu items: Capture > Options

The filter language used for capture filters is different from the built-in filter language with which most people are familiar. Capture filters in Wireshark use Berkeley Packet Filter (BPF) syntax. You can find out more about the syntax here:

I thought it might be useful to provide some examples of capture filters for 802.11 (Wi-Fi) traffic, as I didn't find many examples when Googling around.

Here are a few example filters:
  • wlan type mgt - capture only management frames
  • wlan type ctl - capture only control frames
  • wlan type data  - capture only data frames
  • wlan type mgt subtype beacon - capture only beacon frames
  • wlan type mgt subtype deauth - capture only deauth frames
  • wlan type mgt subtype prob-req - capture only probe requests
  • not wlan mgt - do not capture management frame (i.e. capture data & control frames)
  • not wlan mgt subtype beacon - capture all frames except beacon frames
  • wlan type mgt and (subtype beacon or subtype prob-req) - capture only beacon  and probe request frames 
  • wlan type mgt and (subtype deauth or subtype disassoc) - capture on deauthentication and disassocation frames
  • (wlan type data) or (wlan type ctl and (subtype rts or subtype cts)) - capture only data frames and RTS/CTS control frames

By studying the examples above,you will likely be able to craft your own capture filters. However, you will need to understand the various types of 802.11 frame available and their roles to be able to construct valid filters (maybe take a look at the CWNA or CWAP certification programs if you are not familiar with these)

The following extract from the PCAP filter manpage provides all of the filter options available to you:

type wlan_type subtype wlan_subtype
True if the IEEE 802.11 frame type matches the specified wlan_type and frame subtype matches the specified wlan_subtype.
If the specified wlan_type is mgt, then valid wlan_subtypes are: assoc-reqassoc-respreassoc-reqreassoc-respprobe-reqprobe-respbeaconatimdisassocauth and deauth.
If the specified wlan_type is ctl, then valid wlan_subtypes are: ps-pollrtsctsackcf-end and cf-end-ack.

If the specified wlan_type is data, then valid wlan_subtypes are: datadata-cf-ackdata-cf-polldata-cf-ack-pollnullcf-ackcf-pollcf-ack-pollqos-dataqos-data-cf-ackqos-data-cf-pollqos-data-cf-ack-pollqosqos-cf-poll and qos-cf-ack-poll.

Again, it is worth stressing that most of the time, capture filters are not what you want. It is very easy to miss some important interactions unless you capture all frames over the air (e.g. it is no good capturing just data frames and not seeing deauth frames that are kicking your client off the network).

Saturday, 10 February 2018

Noise Floor Penalty of Wider Channels in Wi-Fi Networks

I’ve been told a number of times that although wider channels in a Wi-Fi network generally provide a higher connection speed (and hopefully a higher throughout), it comes at the cost of increasing the perceived noise floor of the client device. I thought it would be interesting to test this out for myself.

With the advent of 802.11n, it became possible to bond together the 20MHz wide channels of earlier standards in to 40MHz channels (though in reality, this was only practically feasible on the 5GHz band).

Several years later, 802.11ac enabled us to bond together even larger chunks of contiguous channels and achieve 80MHz and 160MHz wide channels on the 5GHz band. Though 80MHz channels are not feasible in many environments and 160MHz is limited to very niche scenarios, they nonetheless are options.

Theoretically, each time we double our channel width, we are going to double our connection speed and our throughput (there are some protocol efficiencies achieved which mean we may slightly more than double our throughput, but lets keep it simple).

However, each time we double our channel width, so the theory goes, we also double the amount of noise our Wi-Fi station is exposed to. I guess this is (kind of) intuitive…

So here’s a quick check using my trusty Macbook Pro:

First of all, I connected to an SSID that is configured for a 20MHz channel width and took a look at the noise floor. In this instance, the noise is reported as –98dBm:

Screen Shot 2018-02-04 at 15.11.35

Fig 1 – 20MHz channel width

Next, I reconfigured the same SSID for a 40MHz channel width. Now, the noise floor was reported as –95dBm. Our noise floor had gone up by 3dB. (Sidenote: an increase of 3dB indicates a doubling of power).

Screen Shot 2018-02-04 at 14.57.30

Fig 2 – 40MHz channel width

Then, I reconfigured the SSID to double the channel width of the same SSID to achieve an 80MHz channel width. The noise floor increased by another 3dB (i.e. doubled again), changing from –95dBm to –92dBm:

Screen Shot 2018-02-04 at 15.17.31

Fig 3 – 40MHz channel width

The observed effect fits the theory. There, that’s 10 minutes of your life you’ll never get back….but never mind, at least you didn’t choose accountancy as a profession.

OK, so why are we really interested in this anyway? Well, the other aspect to this is that if you look back at the results again,  you can see that the received signal level has remained the same in each instance, but our noise floor has crept up. Our signal to noise ratio (SNR) has gone down by 6dB as we moved from 20MHz to 80MHz:

  • Rx_sig_level – Noise_level = SNR
  • 20MHz: –54dBm - -98dBm = 44dB
  • 40MHz: –54dBm - -95dBm = 41dB
  • 80MHz: –54dBm - -92dBm = 38dB

Our SNR values are  still very good in this example, but in an environment with a higher noise floor, a 6dB difference could make a significant difference. Many higher MCS values for 802.11n and 802.11ac rely on having high SNR values for successful operation. This means that a lower SNR could, in some environments have an impact on the higher speeds that are achievable across a network.

Well, that’s pretty much it. Hope this has been of interest.

(By the way, if you wonder how I got the additional Wi-Fi connection info on the Mac, when you click on the Wi-Fi symbol on the Mac top-bar, press the ‘alt’ key at the same time to see the enhanced connection info).

Monday, 29 January 2018

Ubuntu Wi-Fi Client Information

When troubleshooting Wi-Fi connectivity issues, gathering information from the infrastructure side of the network is only half of the picture. In addition to understanding how your Wi-Fi network is configured and performing, it is critical to understand how the wireless network looks from the wireless client’s point of view. In this article I present a few useful snippets that may help you if you have an Ubuntu client that you need to investigate.


Understanding AP channels plans, their transmit power, the coverage that they provide and a whole host of infrastructure-side parameters is very useful when diagnosing Wi-Fi client issues. However, even when you have (what you consider to be) a well designed, well configured network, there may still be some wireless clients that refuse to play nicely on your network.

I recently had issues with a number of Ubuntu laptops that were having connectivity issues on a network I was investigating. Once you’ve checked the usual issues that may cause connectivity problems, it’s time to try and understand the world from the clients view of the world. To do this, you need to gather data from the client so that you can see the network in the same way as the client sees it.

This can be quite a challenge, depending on the client-type and the tools that you may have available to you. This is particularly true in corporate environments, where locked-down, standard builds may be in-place. This can make it quite tough, so that you may need to get a little creative.

This article shows a few useful commands and code snippets I used to recently investigate issues on Ubuntu laptops. It’s certainly not a comprehensive guide to every command and tool available, but it will save me some hunting around next time I need to do this. :)

MAC Address & Interface Name Information

The first thing you need to know when investigating Wi-Fi client issues is the MAC address of the client. It’s also useful to know the name of the Wi-FI NIC interface to feed in to other commands that we’ll use later.The MAC address of a client in Ubuntu can be determined using the CLI (terminal) command “ifconfig” (see example screenshot below).

Multiple adapters may be listed (e.g. Ethernet, Wi-Fi etc.), depending on the hardware build of the Ubuntu machine. The “ifconfig” shows the MAC address of the adapter in the “HWaddr” field. In the example screenshot below, the ethernet adapter MAC address is 00:1c:42:38:58:e2.

The WLAN adapter name usually starts with a “W” (e.g.wlan0, or wlx687f74807e6f in the example below).

Fig 1 - Find MAC address and interface name using “ifconfig’

Wi-Fi NIC Information

It’s useful to find out a little more about the wireless NIC hardware to anticipate the clients’ capabilities. The CLI command “sudo lshw -C network” provides useful information about the Wi-Fi NIC card including the manufacturer, driver version and supported 802.11 amendments.

The screenshot below shows the output created by this command:

Fig 2 - Find Wi-Fi NIC driver info using “sudo lshw -C network”’

Channel Support

Hopefully, if you have modern wireless hardware and drivers, your client is going to support all of the available channels used on the 2.4 & 5GHz bands. But, it’s always worth checking to ensure that your clients won’t “blackhole” if they enter an area that is served by a channel that the client does not support. The CLI command “iwlist <adapter_name> channel” shows us the list of channel supported by the client. 

Note that the “<adapter_name> field above is the name we obtained for the Wi-Fi NIC using the “ifconfig” command.

Fig 3 - Find Wi-Fi NIC supported channel info using “iwlist <adapter_name> channel”’

Client Capabilities

If you are dealing with a client that is new to you, it is important to understand is capabilities. The command “iw phy” provides a wealth of information about the supported capabilities of the adapter.

I have provided a screenshot below of part of the output of this command, but the actual output is far more extensive and provides very detailed, rich information. This is information is invaluable for both troubleshooting and design activities.

Fig 4 - Find Wi-Fi NIC capabilities using “iw phy”

Client Connection Information

When a client is connected to a network, it is important to see how that connection looks from the client’s perspective. We may be able to see client connection  information by interrogating its information from a wireless controller or access point that the client connects to, but that is only half of the story (i.e. how the clients looks from the infrastructure perspective).

To understand the behaviour of a client, we also need to be able understand the other half of the “conversation” and see how the wireless infrastructure appears from the client’s perspective. The command “iwconfig” provides a useful view of how a client’s connection appears from the client’s view of the world.

The screenshot below shows the output of the “iwconfig” command. From the output, it is possible to see details such as the channel used, received signal level (probably the most important value) and connection speed.

It also provides an interesting field called “Link Quality”. This sounds interesting, but to date, I’ve not been able to determine what this actually means or what factors contribute to its value.

Disappointingly, the output does not report a noise or SNR value :(
Fig 5 - Find connection information using “iwconfig”

It can be very useful to repeatedly run the “iwconfig” command and capture its output (for example when assessing roaming behaviour). I’ve put together a short script to repeatedly run the command and output some of the output fields in a CSV format. The output can be reviewed manually or perhaps opened in a tool such as Excel to assess the data provided.

The script is shown below.

# Set the name of your Wi-FI NIC below (use output from iwconfig)

while [ 1 ]

RFINFO=(`/sbin/iwconfig $WIFINIC  | grep -oP '(?<=Signal level=)(.*)(?= dBm)|(?<=ESSID:")(.*)(?=")|(?<=Access Point: )(..:..:..:..:..:..)|(?<=Frequency:)(.*)(?=GHz)'`)


echo "$BSSID, $FREQ, $RSSI, $SSID"

sleep 0.5


Create this script using your favourite Linux editor and run it as shown below (hit Ctrl-C to stop it). I’ve named the script “” in this instance:

Fig 6 - Scripted output of the “iwconfig” command

(BONUS FEATURE: I did some additional work on this particular script and have put an improved version on GitHub:

Available Networks Information

Understanding which networks and access points a client is able to “see”, together with the information it has about each network, is useful when trying to understand client behaviour when troubleshooting.

Linux provides an incredibly useful command to provide detailed data about networks that can be seen by a client:  “sudo iw dev <interface_name> scan”. Note that the “<interface_name>” field is determined by using the output of the “ifconfig” command.

This command causes the wireless client to scan all channels and report on the Wi-Fi networks it hears. It is worth running the command a number of times, as it may not hear all networks each time a scan is performed - it is dependant on whether nearby networks are sending beacons at the time channels are scanned by our NIC adapter.

This is a command that requires elevated privileges to run, so is executed with the “sudo” command. Your (Ubuntu) user account must be capable of running with the elevated privileges required to run the command (i.e. root privilege).

A snippet of the output produced is shown below, though this represents a tiny fraction of the information provided. Each detected network is shown in significant detail, with data that is invaluable in troubleshooting scenarios:

Fig 7 - Sample output from the  “sudo iw dev <interface_name> scan” command

The output of the command can be quite tricky to wade through is you want a quick snapshot of what the client can see. A condensed version can be seen by applying some filtering with the grep command:

sudo iw dev wlx687f74807e6f scan | grep -o 'BSS ..\:..\:..\:..\:..\:..\|SSID: .*\|signal\: .*\|freq\: .*'

Fig 8 - Using grep to filter output from the  “sudo iw dev <interface_name> scan” command

Although this information is useful, it would be even more useful to have this data output in a CSV format. This is a little more challenging (for me) from a scripting perspective, so I have detailed a script to do this over on github: The really cool thing about the CSV option in this script is that you can save the output as a file to import into WiFi Explorer ( to do a little more analysis of the data (which is pretty dammed cool!).

Fig 9 - Importing CSV data in to WiFi Explorer


Unfortunately, the environment in which I was performing troubleshooting work did not allow me to install any new applications on the Ubuntu machines that I was investigating.

However, if you are able to install an application, I strongly recommend that you take a look at Wavemon. It's launched from a terminal window.  It isn’t necessarily as pretty as a full-blown, GUI-based app, but it’s fast and packs a lot of very useful information about the clients view of the “Wi-Fi world” in to a small space.

Here are a few screenshots showing the types of information you can get out of Wavemon. To install, you just need to enter the following terminal commands:

sudo apt-get update
sudo apt-get install wavemon

Fig 10 - Wavemon Link Information

Fig 11 - Wavemon Network Information

Here are few useful references from items covered in this article: