> Beniamin Jablonski, 2025-01-03 > [!attention] > This article has an educational purpose only. > [!note] > A lot of information in this text comes from the following documentation: **Wi-Fi Protected Setup Specification Version 2.0.9**, Wi-Fi Alliance, 2024, https://www.wi-fi.org/discover-wi-fi/wi-fi-protected-setup. # INTRODUCTION I had the opportunity to describe an example of a practical **Pixie Dust** attack in this article: [[WPS Pixie Dust Attack (1) - Hacking TP-Link Router]], which I encourage you to read first. When carrying out well-known attacks like this, I often feel slightly unsatisfied. Running one or two commands, even when the attack is successful, doesn’t bring as much satisfaction if there’s no understanding of what’s happening under the hood. In this article, I attempt to dive a bit deeper into the WPS protocol specification. # REGISTRATION PROTOCOL First, let's define some terms regarding the **WPS** standard: - **Registration Protocol** - a protocol to assign a network credential to an Enrollee device. It facilitates the exchange of WLAN settings and configuration between a Registrar and an Enrollee. - **Enrollee** - a device seeking to join a WLAN. It communicates with a Registrar during the Registration Protocol to obtain credentials. An Enrollee discovers available Registrars through scanning and probe requests. Once it successfully completes the enrollment process and receives a credential, the Enrollee becomes a network member. - **Registrar** - an entity with the authority to issue and manage network credentials for devices (Enrollees) in a WLAN. It may be integrated into an Access Point (AP) or exist as an external device. Registrars use the Registration Protocol to securely transmit WLAN settings to Enrollees. > [!info] > Let's make it simpler: the **Enrollee** is the client device. The **Registrar** is often an access point (like a wireless router) that offers a WPS feature. This is the case described in [[WPS Pixie Dust Attack (1) - Hacking TP-Link Router]] where we have `TP-Link` router (access point, Registar) and ALFA card (client, Enrollee). The Registration Protocol is based on **8 Messages** ($M_1$-$M_8$), which are exchanged between the access point and the client during the authentication process. Because we describe the theoretical background in the context of the **Pixie Dust** attack, we will focus on the authentication process, where 8-Digit Pin is used (but this is not the only case because registration protocol can also be used in other scenarios, e.g. with Push-Button Configuration). In the following table, the selected parameters that are sent in each message are listed. This is not a complete list but it will be clear in a moment why these values are important from the attack perspective. | **Message** | **Direction** | **Selected Parameters** | | ----------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | | $M_1$ | **Enrollee → Registrar** | $N_1$, $PK_E$ | | $M_2$ | **Enrollee ← Registrar** | $N_1$, $N_2$, $PK_R$, $HMAC_{\text{AuthKey}}(M_1 \parallel M_2^*)$ | | $M_3$ | **Enrollee → Registrar** | $N_2$, $E\text{-}Hash1$, $E\text{-}Hash2$, $HMAC_{\text{AuthKey}}(M_2 \parallel M_3^*)$ | | $M_4$ | **Enrollee ← Registrar** | $N_1$, $R\text{-}Hash1$, $R\text{-}Hash2$, $ENC_{\text{KeyWrapKey}}(R\text{-S}1)$, $HMAC_{\text{AuthKey}}(M_3 \parallel M_4^*)$ | | $M_5$ | **Enrollee → Registrar** | $N_2$, $ENC_{\text{KeyWrapKey}}(E\text{-S}1)$, $HMAC_{\text{AuthKey}}(M_4 \parallel M_5^*)$ | | $M_6$ | **Enrollee ← Registrar** | $N_1$, $ENC_{\text{KeyWrapKey}}(R\text{-S}2)$, $HMAC_{\text{AuthKey}}(M_5 \parallel M_6^*)$ | | $M_7$ | **Enrollee → Registrar** | $N_2$, $ENC_{\text{KeyWrapKey}}(E\text{-S}2)$, $HMAC_{\text{AuthKey}}(M_6 \parallel M_7^*)$ | | $M_8$ | **Enrollee ← Registrar** | $N_1$, $HMAC_{\text{AuthKey}}(M_7 \parallel M_8^*)$ | > For details: **Wi-Fi Protected Setup Specification Version 2.0.9**, page 48 Let's explain the symbols: - **$N_1$, $N_2$**: 128-bit nonces (random numbers) generated by the Enrollee ($N_1$) and Registrar ($N_2$). - **$PK_E$, $PK_R$**: Diffie-Hellman public keys of the Enrollee ($PK_E$) and Registrar ($PK_R$). - $HMAC_{AuthKey}$() - an `authenticator` attribute that contains a HMAC-SHA-256 keyed hash using the `AuthKey` key. - $AuthKey$ is 256 bits and $KeyWrapKey$ is 128 bits. To derive it, we need to know: $PK_E$, $PK_R$, $N_1$, $N_2$, Enrolee MAC Address. - $M_n^*$ is message excluding the HMAC-SHA-256 value. - $ENC_{KeyWrapKey}()$ - symmetric encryption using $KeyWrapKey$. - $E\text{-}Hash1$, $E\text{-}Hash2$ - pre-commitments made by the Enrollee to prove knowledge of the two halves of its own device password. - $R\text{-}Hash1$, $R\text{-}Hash2$ - pre-commitments made by the Registrar to prove knowledge of the two halves of the Enrollee’s device password. - $R\text{-}S1$, $R\text{-}S2$ - secret 128-bit nonces that, together with $R\text{-}Hash1$ and $R\text{-}Hash2$ can be used by the Enrollee to confirm the Registrar’s knowledge of the first and second half of the Enrollee’s device password, respectively. - $E\text{-}S1$, $E\text{-}S2$ - secret 128-bit nonces that, together with $E\text{-}Hash1$ and $E\text{-}Hash2$, can be used by the Registrar to confirm the Enrollee’s knowledge of thefirst and second half of the Enrollee’s device password, respectively. > For details: **Wi-Fi Protected Setup Specification Version 2.0.9**, page 51 $E\text{-}Hash1$ and $E\text{-}Hash2$ are derived from the session parameters and the device password (PIN). First, the device password (PIN) is converted to two 128-bit $PSK$ values as follows: $PSK_1 = first\space 128 \space bits \space of \space HMAC_{AuthKey}(1st \space half \space of \space DevicePassword)$ $PSK_2 = first\space 128 \space bits \space of \space HMAC_{AuthKey}(2st \space half \space of \space DevicePassword)$ For example, if PIN value is `12345678`, $PSK_1$ is derived from `1234` and $PSK_2$ is derived from `5678`. Second, we can determine the $E\text{-}Hash1$ and $E\text{-}Hash2$: $E\text{-}Hash1 = HMAC_{AuthKey}(E\text{-}S1 || PSK1 || PK_E || PK_R)$ $E\text{-}Hash2 = HMAC_{AuthKey}(E\text{-}S2 || PSK2 || PK_E || PK_R)$ Analogous equations can be determined for $R\text{-}Hash1$ and $R\text{-}Hash1$. Now let's make a crucial observation: > [!important] > When we don't know the PIN we can still make an attempt to authenticate. In that case 4 out of 8 messages will be exchanged. Note that we can obtain the following values: > - $N1$ - we obtain this value from $M_1$ > - $PK_E$ - we obtain this value from $M_1$ > - $PK_R$ - we obtain this value from $M_2$ > - $AuthKey$ - this parameter must be derived from $PK_E$, $PK_R$, $N_1$, $N_2$, Enrolee MAC Address > - $E\text{-}Hash1$ - we obtain this value from $M_3$ > - $E\text{-}Hash2$ - we obtain this value from $M_3$ Now, look again at the above equations, which shows how to determine $E\text{-}Hash1$ and $E\text{-}Hash2$. The only parameters we don't know are $PSK1$, $PSK2$, $E\text{-}S1$, and $E\text{-}S2$. The possible values for $PSK1$ are limited—only $10,000$ ($10^4$). For $PSK2$, there are even fewer possibilities - just $1,000$ ($10^3$), because the last digit of the PIN is a checksum. What about $E\text{-}S1$ and $E\text{-}S2$? These are 128-bit nonces (random values), so their keyspace is enormous: $2^{128}$ for each nonce. However, what if there were a way to avoid brute-forcing these values and instead reverse-engineer them? **This is where the Pixie Dust attack comes into play.** It turns out that for certain wireless chipsets, it is possible to reproduce $E\text{-}S1$ and $E\text{-}S2$ due to flaws in the algorithms responsible for generating these pseudo-random values. Once these values are known, the brute-forcing procedure becomes trivial. # WIRESHARK ANALYSIS One of the best tools for protocol analysis is Wireshark, which provides a deep understanding of what is happening in a protocol in practice. For the following considerations, we will use a filter to focus on the authentication process. The target of our attack is a device with the BSSID `f0:a7:31:d7:a6:0e`: ``` wlan.sa == f0:a7:31:d7:a6:0e or wlan.ra == f0:a7:31:d7:a6:0e and eap ``` At this point, it's worth clarifying one thing. I previously mentioned that when we don't know the correct PIN, only 4 messages are exchanged ($M_1$-$M_4$), and the access point rejects the authentication process after the fourth message. This happens because the client provides an incorrect value for $R\text{-}Hash1$. This value is related to the **first half of the PIN** (it is calculated similarly to $E\text{-}Hash1$). But what happens if the first half of the PIN we provide is correct? To be precise, in this case, the exchange will continue until message 6 ($M_6$), where we provide an incorrect value for $R\text{-}Hash2$, and at this stage, we will be rejected. Let's demonstrate this using an example of a vulnerable `TP-Link` router for which the correct PIN is `01576672`. If we provide an incorrect PIN, 4 messages will be exchanged: ```bash sudo reaver -i wlan0 -b F0:A7:31:D7:A6:0E -c 10 -v -p 12345678 ``` ![[Pasted image 20241230090832.png]] ![[Pasted image 20241230090707.png]] If we provide the correct first half of the PIN, 6 messages will be exchanged: ```bash sudo reaver -i wlan0 -b F0:A7:31:D7:A6:0E -c 10 -v -p 01570000 ``` ![[Pasted image 20241230090756.png]] ![[Pasted image 20241230090630.png]] We also mentioned earlier what values are needed for the Pixie Dust attack. Now, let's show where these values can be found in the first 3 messages. - Message 1: (1) Message type: $M_1$, (2) $N1$ - Enrollee Nonce, (3) $PK_E$ - Enrollee Public Key. ![[Pasted image 20241229222134.png]] - Message 2: (1) Message type: $M_2$, (2) $PK_R$ - Registrar Public Key. ![[Pasted image 20241229222604.png]] - Message 3: (1) Message type: $M_3$, (2) $E\text{-}Hash1$ - Enrollee Hash 1, (3) $E\text{-}Hash2$ - Enrollee Hash 2. ![[Pasted image 20241229222759.png]] Now, the command used with the `pixiewps` tool is likely more understandable since it's clear that the values mentioned above are utilized within it. It's important to note that the $authkey$ parameter does not explicitly appear as a parameter in the protocol - it must be derived. Therefore, it is convenient to use the `reaver` tool, which automatically calculates this value and supplies all the appropriate inputs to `pixiewps` (see [[WPS Pixie Dust Attack (1) - Hacking TP-Link Router]]). However, the `pixiewps` tool can still be used independently, as shown below. In this case, I modified the tool's source code and recompiled it to enable `DEBUG` mode (but you don't have to this at all; I just wanted to show that this tool indeed determines specific $E\text{-}S1$ and $E\text{-}S2$ parameters). ```bash # Copy the repository: git clone https://github.com/wiire-a/pixiewps # Make changes (if you want to do any) and compile: make # Launch the command. To generate a ready-to-execute command, use reaver tool: ./pixiewps -e <Enrollee public key PKE> -s <Enrollee hash 1 E-Hash1> -z <Enrollee hash 2 E-Hash2> -a <authkey> -n <Enrollee nonce N1> -r <Registrar public key PKR> ``` ![[Pasted image 20241229212210.png]] > [!info] > I added the `#define DEBUG 1` line to the `pixiewps.h` because I observed in the source code that it activates additional output. I also made a little mistake in the string value - there was E-S1 twice instead of E-S1 and E-S2. > > ![[Pasted image 20241229214235.png]] # REFERENCES 1. **Wi-Fi Protected Setup Specification Version 2.0.9**, Wi-Fi Alliance, 2024, [Link](https://www.wi-fi.org/discover-wi-fi/wi-fi-protected-setup) 2. [pixiewps](https://github.com/wiire-a/pixiewps)