Back in 2018, I was interested that MSCHAPv2 and NTLMv1 hashes crack using the same algorithms, and wanting to get onto the WiFi of one of our clients, I naively thought “Surely if you can relay NTLMv1 and it uses the same crypto as MSCHAPv2, you should be able to relay MSCHAPv2!”. The resulted in the creation of wpa_sycophant (and its helper berate_ap) to perform PEAP relay attacks. It was presented in our Defcon talk last year from about 17m in.
In the beginning, I floated this idea as a way to easily get onto client EAP wireless networks and potentially relay from MSCHAPv2 to NTLMv1. (It turns out you can’t do the latter, I didn’t know that yet, but that story is for another blog.) Given some advice from Dominic, I separated my idea into small chunks so as not to get overwhelmed or over complicate it. I modified both hostapd-mana and wpa_supplicant (to create wpa_sycophant). In hostapd-mana I added an option to tell mana that it will have to get most of its information from my modified supplicant. I called my modified supplicant wpa_sycophant. In sycophant I made it retrieve information from mana to create a relay attack from wireless client to wireless access point.
A relay attack is where, as a person-in-the-middle, you mediate an authentication attempt (Usually challenge-response NetNTLM) between two parties. Doing this you may hijack the resulting successful authentication and gain privileged access to something.
However, we’re going to do it with PEAP and WiFi instead of NTLM and TCP/IP.
Stage 1 – getting a victim to connect to you
There are a few preconditions to perform a relay attack; first you need to be able to force a victim to authenticate against you rather than a legitimate server.
In the NTLM world, usually something like Responder is used. What Responder does is reply to Windows LLMNR probes claiming to be the server they are trying to resolve. The victim then uses that resolution attempt to authenticate to what they think is what they were looking for. This deceptive response is the exact same thing that hostapd-mana does except in the WiFi space where victim devices are probing for networks, hostapd-mana takes these probes and tells the device that it is the access point they are looking for, after which they attempt to authenticate. This gives us the Responder part of the relay equation.
Using hostap-mana (which is based on hostapd) as a base I added a new flag
enable_sycophant which instructs mana to take the victim’s authentication attempt and write it to a file. Once written, it will wait for the response to that attempt from a different file, and keep doing this until the authentication is complete.
I chose files, so that the rogue supplicant (sycophant) and rogue access point (mana) can be easily separated to different hosts (i.e. you can relay across the Internet). I realised later that you could just use hostapd’s built in RADIUS server to enable across network relaying more reliably than synchronising files, but at this point I was committed to the file.
Stage 2 – relaying to a legitimate access point
The second stage of a relay attack is the actual relay. This is taking the authentication attempt that is being attempted against your rogue access point and passing it off to the thing you would actually like to authenticate against, in this instance the legitimate access point. To do this, while doing minimal work and reusing what already exists, a modified wpa_supplicant was created to interface with mana. Sycophant does not do any inner authentication calculations itself and instead relies on a victim device, relayed via mana, to authenticate it to the access point.
Sycophant and mana sync state and pass information between them using files. Once sycophant is started, it will wait for a victim to start authenticating against mana. After a victim has associated with mana and passed outer authentication (i.e the TLS part of PEAP) sycophant associates with the legit AP, negotiates outer authentication, then pulls information from mana and passes it verbatim to the AP for inner authentication. If it all works, this results in the legitimate RADIUS server returning a successful authentication and letting sycophant associate with the targeted legitimate access point.
Why did it work
To my surprise I was able to authenticate to wireless networks using this method and a rough PoC.
The reason this attack works is that the step connecting to the access point and the step authenticating via the RADIUS server are disconnected. This is an issue with all tunnelled EAP methods where the authentication happens in a tunnel directly to the RADIUS server and the RADIUS server tells the access point whether the authentication was successful or not. By default, nothing in the MSCHAPv2 authentication attempt passed to the RADIUS server is used to calculate the encryption keys to talk to the access point. Instead, the WPA2 pairwise-master-key (PMK) is derived from the outer TLS’s session keys (if cryptobinding is disabled). Therefore, if you can get the RADIUS server to tell the access point you successfully authenticated, it will let you connect and you will have all you need to be able to talk to it without needing any secrets other than what you and the Access Point have exchanged with each other in the outer tunnel.
If you’re interested in the low level detail of how PEAP and the inner MSCHAPv2 exchange work, you can read our detailed write up about it here.
What is Gained
My initial excitement using this technique is that it allows access to certain access points without having to crack passwords as was done previously. However due to the nature of MSCHAPv2 and it boiling down to three DES keys (one of them gimped) given enough computing power you should be able to crack any MSCHAPv2 hashes captured by hostapd-mana within a week or so. So this technique is good if you’re in a hurry and the password isn’t at the top of your wordlist. What this also gets you is a similar outcome to the “auto crack ‘n add” of the original mana from 2014, where you can person-in-the-middling corporate clients on a corporate network, because you can return valid authentication responses showing that the server you authenticated against also knows your password so it is safe to proceed. This allows you to bettercap away without needing to crack their passwords first and can be done without any powerful hardware.
In addition to this is the realisation that mana, like a wireless version of responder, provides a way to perform relay attacks against EAP authentication methods which are prevalent in many network access controls.
After the high of this success was then the low of discovering that this attack had been theorised in a 2002 paper from Nokia, and defences built into the EAP RFC (circa 2004) called “cryptographic binding” (or “cryptobinding” for short). However, this prevention is not enabled by default on many devices we checked, including Windows, Android and iOS.
In essence we only need to convince the RADIUS server to tell the access point to let us connect. When cryptobinding is enabled it creates a connection between the two tunnels to ensure that the client that is authenticating against the RADIUS server is the same client that created the initial TLS tunnel to the access point. This is done by requiring that some secret information used in the inner authentication is used with the outer tunnel keys in the pairwise-master-key for communicating with the access point. i.e. information is taken from both the inner and outer auth. Without the final piece of the inner authentication you cannot create the key so that you may talk to the access point post authentication.
Additionally, if every client properly validates the leaf certificate presented by the access point during the outer TLS setup, then this and other “in-tunnel PitM” attacks are prevented. However, too many networks still get this wrong.