Capturing WPA handshakes with OS X

Fortunately, the wireless card from Apple’s hardware supports the monitor mode. Unfortunately, the aircrack-ng suite has only partial OS X support. That means: placing the card in monitor mode requires other methods as airmon-ng doesn’t know how to do it, you can’t capture wireless traffic with airodump-ng, most probably the drivers don’t support packet injection. No packet injection means no deauthentication, therefore you need to be patient as this attack is fully passive. However, you can use aircrack-ng to test that a capture has all the needed bits and pieces.

It requires arcane methods, getting out of the comfort zone, and going the extra mile you usually don’t find in courses talking about wireless security. Yes, you need to go MacGyver on this with tcpdump. This article is more about the research done in order to figure out the internals than actually doing pen testing with a Mac. But if the situation requires it and if you need to peek at 802.11ac traffic (the newer models, mid 2013+, have ac enabled hardware), this is valuable knowledge.

The first tool you need is aiport, which is a small utility hidden in Apple80211 private framework. I made a symlink in /usr/local/bin for easier invocation. In 10.9 it can be found here: /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport

While airport itself can sniff traffic, it dumps all of the captured traffic. As I found out, parsing a 100 megs capture takes a while, and this capture size isn’t uncommon for a busy network. Therefore, for the purpose of capturing WPA handshakes its usage is restricted to disassociation from the network and setting an arbitrary channel for the wireless interface. You need to disassociate from the AP as taking en0 out of monitor mode reconnects the network and resets the channel setting.

# disassociate from the AP
sudo airport -z
# set an arbitrary channel, notice the lack of space between the flag and the value
sudo airport -c10
# check the channel
airport -c
channel: 10

You need a tool for capturing traffic. An up to date tcpdump or tshark may fill that role. The tcpdump that comes with OS X is too old to play nice. It is recommended to install tcpdump and mandatory to install wireshark. Both are available as brew recipes.

Either of the above tools have the -I (that’s capital I not l) flag for placing the wireless interface into the monitor mode. The functionality is actually part of libpcap. In order to keep the captures to minimum, you need two runs for gathering the required information.

# capture a beacon frame from the AP
tcpdump "type mgt subtype beacon and ether src $BSSID" -I -c 1 -i en0 -w beacon.cap
# wait for the WPA handshake
tcpdump "ether proto 0x888e and ether host $BSSID" -I -U -vvv -i en0 -w eapol.cap

$BSSID = The MAC address of the AP. tcpdump may be replaced with tshark -f in the above lines if you take out -U -vvv and use -V instead. tcpdump’s -U is tshark’s -l. Read the corresponding manuals for more information.

Usually you have to wait until the 0 from the tcpdump output changes to 4, but you don’t need all the frames of a four-way handshake in order to pass the capture to aircrack-ng. If there are captured packets, you may want to inspect them with Wireshark. Sometimes the frames aren’t captured as they are missed by the wireless interface. For cracking the passphrase you need two frames at minimum: either “Message 1 of 4” and “Message 2 of 4”, or “Message 2 of 4” and “Message 3 of 4”, as shown in the Info column in Wireshark. You may need to export specific packets from Wireshark in another capture. Mark the packets, then File > Export Specified Packets.

If the correct frames are captured, you may terminate the tcpdump process with Ctrl+C.

aircrack-ng needs a management frame containing the ESSID (beacon, probe response, association request, or reassociation request) and two data frames containing the EAPOL messages as mentioned above. The EAPOL messages are encapsulated in qos-data frames (a subtype of the data frames). You need to merge the beacon.cap and the eapol.cap captures.

mergecap -a -F pcap -w handshake.cap beacon.cap eapol.cap
aircrack-ng -w /path/to/wordlist handshake.cap

You need a probe response (subtype proberesp) for the networks that don’t broadcast their ESSID in beacon frames. You may combine this as a single capturing filter for getting both type of frames in a single run when the WPA handshake occurs. This won’t work for AP’s that broadcast their ESSID as the capture will contain a lot of useless packets. Of course, you may use either this method or the beacon method, but the capture parsing is slowed by the sheer size of the capture in this case.

tcpdump "(type mgt subtype proberesp or ether proto 0x888e) and ether host $BSSID" \
-I -U -vvv -i en0 -w hidden-handshake.cap

It may capture more than one probe response when the handshake happens. You may need to investigate with Wireshark or do an aircrack-ng test run against the capture to check that the capture is usable.

Another source for the ESSID value is to listen for association request frames (subtype assocreq) or reassociation request frames (subtype reassocreq) in order to fetch the ESSID. You may wait for a reassociation request if you got the handshake of a network with hidden ESSID, but you’ve missed the relevant mgt frame.

Waiting however for an association request is a method for combining all of the above knowledge in one capturing filter that works for both hidden and non-hidden networks. It also contains the minimum number of captured frames by using a single filter.

tcpdump "(type mgt subtype assocreq or ether proto 0x888e) and ether host $BSSID" \
-U -vvv -i en0 -w handshake.cap

I also tested that the captures work with Hashcat by converting them to the HCCAP format with cap2hccap. Building cap2hccap under OS X requires a small patch for MAX_BUFF. You need to change this:


into this:

#define MAX_BUFF (1024)

2 thoughts on “Capturing WPA handshakes with OS X

  1. SaltwaterC Post author

    type mgt subtype beacon – indicates a dump capturing filter looking for beacon frames. This article explains the 802.11 frame types. You can be really cryptic when writing a capturing filter, but fortunately tcpdump has human readable names.

    ether proto 0x888e – is also a capturing filter. This is bit cryptic as tcpdump doesn’t have a human readable name for the EAPOL frames which contain the WPA/WPA2 handshakes. Targeting by EtherType makes sure tcpdump captures only the needed EAPOL frames with surgical precision.

    The EAPOL frames are a (sub)type of data frame (can’t remember exactly which, you can easily see in Wireshark). By using only the human readable filters provided by tcpdump the capture is too broad even when you target the exact data subtype. aircrack-ng is fairly slow at parsing large captures with lots of junk traffic. This is only an application startup cost, but still enough to annoy when doing a PoC.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.