Archive for the Wireless Category

Tweaking EAP’s weak link – sucking WiFi PMKs out of RADIUS with pmkXtract

Posted in Crypto, Networking, Wireless on 23 January, 2011 by Alec Waters

When faced with a WiFi network using WPA2/EAP-TLS, options for a direct attack are limited. You can’t feasibly attack the encryption (most likely CCMP), and if the client devices are configured properly attacking the authentication mechanism directly isn’t likely to bear fruit either.

One of the advantages of the “enterprise” variants of WPA is that the Pairwise Master Keys are specific to a client device and to a single association (WPA Personal has the same PMK shared amongst all devices). To oversimplify somewhat, with WPA Enterprise the PMK for a given device is negotiated between the device and the RADIUS server as part of the EAP process. The PMK is subsequently delivered to the access point via RADIUS. Once both the client device and the AP have the PMK the normal WPA four-way handshake can complete, the output of which is a Pairwise Transient Key which is used to encrypt the session. There’s a nice diagram of the process here.

However, there is a weak link in the chain. Hacking Exposed Wireless, 2nd edition describes a possible attack against the delivery of the PMK from the RADIUS server to the access point. The theory of operation is as follows:

  1. Start capturing the wireless traffic of interest.
  2. Start capturing the RADIUS traffic between the RADIUS server and the access point.
  3. Using an obtained RADIUS shared secret, decrypt the RADIUS traffic that contains the PMKs.
  4. Use the extracted PMKs and the captured four-way handshakes to derive each device’s PTK.
  5. Decrypt every single data frame you’ve captured from the wireless network 🙂

The book didn’t cite any tools capable of extracting the PMKs from the RADIUS conversation, so I thought I’d have a go at writing one myself. The reason the book didn’t cite any tools is probably that if an attacker is in a position to capture your RADIUS traffic, you probably have bigger things to worry about. Nevertheless, it seemed like a challenge worth attempting.

Of the five points above, 1 and 2 are straightforward (assuming the attacker is well placed). 4 and 5 can be easily carried out with Wireshark. Step 3 breaks down into obtaining the shared secret and decrypting the PMKs.

Obtaining the RADIUS shared secret

As noted in Hacking Exposed Wireless, a brute force attack on the shared secret is quite feasible. Alternatively, one can just poke around the RADIUS server and find the list of secrets. For example:

  • FreeRADIUS stores all of this in clients.conf
  • Internet Authentication Service on Windows 2K3 stores everything in system32\ias\ias.mdb which you can open in MS Access (look in the Objects table)
  • Network Policy Server on Windows 2k8 stores everything in system32\ias\ias.xml in plaintext.

Secrets in hand, we can move on to…

Decrypting the PMKs

We first need to start capturing the WiFi traffic of interest. We can do this with airodump-ng:

airmon-ng start wlan0
airodump-ng –channel 1 –bssid 00:1c:df:8b:50:66 –write pmkXtract mon0

Now we can turn our attention to capturing the PMKs. The PMKs are transmitted in the final RADIUS message of the transaction (the Access-Accept message), and they’re stored encrypted in a vendor-specific attribute, MS-MPPE-Recv-Key:

Given the correct shared secret, Wireshark is apparently capable of decrypting RADIUS traffic but I couldn’t make it work for MS-MPPE-Recv-Key. Shying away from actually writing decryption code from scratch, I invoked the age-old software engineering tradition of “code re-use”, aka pinching someone else’s stuff.

hostapd is a user-space access point daemon, and has full support for EAP-TLS. After nosing around and debugging the code, I found the procedure that does the decryption – decrypt_ms_key() in radius.c.


pmkXtract is a quick and dirty hack that wraps up decrypt_ms_key(); all we need to do is feed it:

  • The RADIUS shared secret
  • The request authenticator from the final Access-Request message
  • The MS-MPPE-Recv-Key from the following Access-Accept message

A neater, future version of pmkXtract would capture the latter two straight off the wire, but for now they are CLI parameters. The most convenient way to get these values is with tshark, supplying the appropriate capture filter:

tshark -T fields -e radius.code -e -e radius.authenticator -e radius.MS_MPPE_Recv_Key -E separator=! ip host access.point.ip.addr

This will produce output like this:


What we’re looking for is a pair of code1/code2 messages with the same ID, as is the case with the last two lines above with ID 12. Code 1 denotes Access-Request, code 2 is Access-Accept. Now we can pass the message authenticator from the access-request and the MS-MPPE-Recv-Key from the access-accept to pmkXtract, along with the shared secret:

C:\>pmkXtract secret 5d:5c:<snip>:69:5d 80:8a:<snip>:7d:79
PMK is:c8cad1f342e431bdf97b3fd1c37bf2fe

Score! We’ve got the PMK.

Decrypting the captured WiFi traffic

The first thing we need to do is look through our airodump capture for the WPA four-way handshake:

Frames 134, 136, 138, and 140 are the four-way handshake

As we might expect, the contents of the capture is unintelligible:

Now we can enter the PMK that pmkXtract gave us, by going Edit->Preferences, and selecting IEEE802.11 under Protocols:

And hey presto, we have decrypted the traffic. Note the “Decrypted CCMP data” sub-tab at the bottom of the window:

As I’ve already said, if an attacker can pull this off, they already have a deep foothold in your infrastructure. Use strong RADIUS secrets, secure the list of secrets on the server (clients.conf, ias.mdb, etc) as well as you can, and if it’s possible, protect the RADIUS exchange with IPSec.

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at