Broadcom 802.11r Buffer Overflow

Broadcom suffers from a stack buffer overflow vulnerability when handling 802.11r (FT) authentication responses.

MD5 | b34ead8f3ace96632a3dc52a447a75b8

 Broadcom: Stack buffer overflow when handling 802.11r (FT) authentication response 


Broadcom produces Wi-Fi HardMAC SoCs which are used to handle the PHY and MAC layer processing. These chips are present in both mobile devices and Wi-Fi routers, and are capable of handling many Wi-Fi related events without delegating to the host OS.

In order to allow fast roaming between access points in a wireless network, the Broadcom firmware supports the Fast BSS Transition feature (IEEE 802.11r-2008 FT), allowing a client to roam between APs in the same mobility domain.

When a client decides to roam to a different AP in an FT network (in the same mobility domain), they first send an authentication request frame. This frame is either sent to the new AP (in over-the-air FT) or to the original AP (in over-the-DS FT). The authentication request frame includes the Fast BSS Transition Information Element (FT-IE) specifying the <a href="" title="" class="" rel="nofollow">R0</a> key holder ID (R0KH-ID) corresponding to the roam request.

In response, the AP send back an authentication response frame, also containing an FT-IE. This FT-IE contains the regular fields (Anonce, Snonce, etc.) but also includes the R0KH-ID and R1KH-ID. This is done by encoding the additional fields as TLVs immediately after the structure of the FT-IE (but still within the bounds of the IE), like so:

| FT-IE Tag (55) | FT-IE Length | ... FT-IE Contents ... | Additional TLVs |
0 1 2 84 2 + FT-IE Length

On the BCM4339 SoC with firmware version the authentication response frame for FT roaming is handled by ROM function 0x7B6A4. This function first retrieves the FT-IE. Then, it allocates a heap buffer for it, using the size specified in the IE's length field. The FT-IE is then stored in the allocated buffer, which is subsequently used to extract the R0KH-ID and R1KH-ID fields.

Here is the high-level logic for this function:

void function_7B6A4(...) {

//Copying in the FT-IE
char* ft_ie = bcm_parse_tlvs(auth_frame, auth_frame_len, 55);
unsigned short ft_ie_len = ft_ie[1] + 2;
char* ft_ie_buffer = malloc(ft_ie_len);
memcpy(ft_ie_buffer, ft_ie, ft_ie_len);

//Extracting the embedded IEs in the FT-IE. The size of the
//FT-IE's fields without the embedded IEs is 84.
char* ies = ft_ie_buffer + 84;
int ies_length = ft_ie_len - 84;
char* r0kh_id = bcm_parse_tlvs(ies, ies_length, 1);
char* r1kh_id = bcm_parse_tlvs(ies, ies_length, 3);
memcpy(..., ft_ie + 20, 0x20); //Copying the Anonce

First, it should be noted that the function erroneously assumes the size of the FT-IE is at least 84. An attacker could include a shorter FT-IE, causing the function to copy 0x20 bytes from (ft_ie + 20), which are stored as the AP's Anonce.

Second, after extracting the R0KH-ID and R1KH-ID fields, the function proceeds to calculate the PTK. To do so, the value of PMK-<a href="" title="" class="" rel="nofollow">R0</a> must first be derived. According to IEEE 802.11r-2008 -, the PMK-<a href="" title="" class="" rel="nofollow">R0</a> is derived as follows:

<a href="" title="" class="" rel="nofollow">R0</a>-Key-Data = KDF-384(XXKey, "FT-<a href="" title="" class="" rel="nofollow">R0</a>",
SSIDlength || SSID || MDID || R0KHlength || R0KH-ID || S0KH-ID)
PMK-<a href="" title="" class="" rel="nofollow">R0</a> = L(<a href="" title="" class="" rel="nofollow">R0</a>-Key-Data, 0, 256)
PMK-R0Name-Salt = L(<a href="" title="" class="" rel="nofollow">R0</a>-Key-Data, 256, 128)

(see also "wpa_derive_pmk_r0" under <a href="" title="" class="" rel="nofollow"></a>)

This calculation is performed by ROM function 0x13C94, which uses the R0KH-ID that was parsed earlier from the FT-IE in the authentication response frame. The function has approximately the following logic:

void function_13C94(...) {
char buffer[128];
memcpy(buffer, "FT-<a href="" title="" class="" rel="nofollow">R0</a>", strlen("FT-<a href="" title="" class="" rel="nofollow">R0</a>")); buffer += strlen("FT-<a href="" title="" class="" rel="nofollow">R0</a>");
memcpy(buffer, &ssid_length, 1); buffer += 1;
memcpy(buffer, ssid, ssid_length); buffer += ssid_length;
memcpy(buffer, &mdid, 2); buffer += 2;
memcpy(buffer, r0kh_id, r0kh_id_len); buffer += rokh_id_len;

Where "r0kh_id" is the contents of the R0KH-ID field that was extracted from the FT-IE, and "r0kh_id_len" is the length of the extracted field.

Since the R0KH-ID field's length is not validated, an attacker can include an extremely long field within a crafted FT-IE (specifically, the R0KH-ID's length can be at most MAX_IE_SIZE + IE_HEADER_SIZE - FT_IE_SIZE = 255 + 2 - 84 = 173). This would cause the stack-allocated buffer to be overflown, corrupting the stack with attacker-controlled data.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

Found by: laginimaineb

Related Posts