September 24, 2024


Episode 14


New Release! FT-Crack: An Open Source Wireless Hacking Tool 


Author: David Underwood

DEFCON has come and gone again. It was another wonderful time spent seeing old friends, making some new ones, and of course participating in one of the CTF events held every year to try my luck at taking home a Black Badge. This year, we put together a crew to take on the Radio Frequency Village CTF and ended up coming back with a solid third place on the scoreboard. While our team was preparing for the event this year, we managed to identify a potential problem: we didn't have a means to crack an FT-PSK handshake, which had the potential to be a challenge during the CTF.

As it turned out, there aren't (at least, as far as we are aware at the time of this writing) any public tools that can calculate the values needed to confirm that a given password (the PSK in FT-PSK) is being used for an access point if it's using fast BSS transition (the FT in FT-PSK). While it wasn't a guarantee that it would be a challenge we would have to face at the competition, it did mean that if we showed up and didn't have an answer for it, we could fall behind the rest of the teams. And if it did end up being a problem that we had to face, we could be better prepared than the rest and net some of those sweet, sweet First Blood points.

With all that being said, I'm happy to say that we did manage to come up with something, and I would like to share with the rest of the world my solution, FT-Crack: a simple Python script that can crack an FT-PSK handshake given a hash and a wordlist. While I am by no means an expert, I thought it might be fun to share some insight into how I went about figuring out what needed to be done to create a usable tool and the process as I went about my research.

As you read further, you can find the FT-Crack repository hosted here: https://github.com/DarkWolf-Labs/ft-crack/tree/main


WPA-PSK, THE CRACKED

"What does all of that even mean?" I hear you ask yourself. Good question! Before diving too deep into the rest of it, here is a snippet shamelessly stolen from Wikipedia (which was shared with me by a colleague) describing fast transition:

"IEEE 802.11r-2008 or fast BSS transition (FT), is an amendment to the IEEE 802.11 standard to permit continuous connectivity aboard wireless devices in motion, with fast and secure client transitions from one Basic Service Set (abbreviated BSS, and also known as a base station or more colloquially, an access point) to another performed in a nearly seamless manner. It was published on July 15, 2008. IEEE 802.11r-2008 was rolled up into 802.11-2012.[1] The terms handoff and roaming are often used, although 802.11 transition is not a true handoff/roaming process in the cellular sense, where the process is coordinated by the base station and is generally uninterrupted."

I won't go into too much detail here, but the gist of it (from my understanding) is that it's a way for a client to be able to roam within an environment without having to do the entire authentication process for each access point. The idea was that if a client could prove that it knew the correct password by knowing keys derived from it, time could be saved. What did that mean for us, though?

Well, the process of cracking a normal WPA handshake is pretty much a solved problem in 2024. For example, here is a page from Hashcat (other popular tools such as Aircrack-ng do this as well, but I'll just focus on Hashcat to keep things simple) on handling hashes for WPA or WPA2:

https://hashcat.net/wiki/doku.php?id=cracking_wpawpa2 

Looking at the "Working with hash files," you can tell that Hashcat wants a hash in the format of:

WPA*02*MIC*MAC_AP*MAC_CLIENT*ESSID*NONCE_AP*EAPOL_CLIENT*MESSAGEPAIR

This is because Hashcat can take the given values (MAC address of the access point, MAC address of the client, the ESSID, a nonce provided from the access point, and the second EAPOL message), add in a password, and calculate a Message Integrity Check (MIC) using a known algorithm. If the provided values calculate out to be the same MIC that is inside the original EAPOL message (which is pulled out and placed in the hash for comparison), Hashcat can determine that the password it used is correct.

As this has been explained many times all over the internet, I'll try to keep this part brief—but normally, the process looks something like this:

PMK = PBKDF2(HMAC−SHA1, PSK, SSID, 4096, 256)

A Pairwise Master Key ("PMK") is calculated using the Pre-Shared Key ("PSK," or "the password") and the SSID for the access point. Then, the PMK is taken and expanded into multiple keys using a specific pseudo-random function (a "PRF"—I know, it's acronym after acronym, just bear with me):

PRF-512(PMK, "Pairwise key expansion", MAC1||MAC2||Nonce1||Nonce2)

The PRF itself uses an HMAC-SHA-1 algorithm to generate keys and concatenate them together:

HMAC-SHA-1(K, A|0|B|i)

Where "A" is the "application-specific text" (or "Pairwise key expansion"), a null byte, "B" is the data (the MAC addresses and nonces, sorted by lowest to highest), and an increasing counter "i". The entire process is detailed fairly well here, for those more curious:

https://etutorials.org/Networking/802.11+security.+wi-fi+protected+access+and+802.11i/Part+II+The+Design+of+Wi-Fi+Security/Chapter+10.+WPA+and+RSN+Key+Hierarchy/Computing+the+Temporal+Keys/

The PRF will generate bytes up to the required amount (in our case 512 bits, while throwing out the additional generated bytes per iteration), and then they will be split into various keys. The first 128 bits are known as the "KCK," which is used during the generation of a MIC. Unfortunately, I don't have as nice of an example as the previous ones to explain the MIC generation, but we can use the code for wpa_supplicant to get an idea (as well as the many WPA2 handshake cracking scripts and tools out there):

https://github.com/digsrc/wpa_supplicant/blob/master/src/common/wpa_common.c

The MIC is generated using an HMAC-SHA-1 algorithm (for WPA2), with the KCK as the key and the entire second EAPOL message as the data with its MIC field from the message zeroed out.