Monorail Project: project-zero Issues People Development process History Sign in
New issue
Advanced search Search tips
Starred by 4 users
Status: Fixed
Owner:
Closed: Apr 3
Cc:



Sign in to add a comment
Broadcom: Heap overflow in TDLS Teardown Request while handling Fast Transition IE
Project Member Reported by laginimaineb@google.com, Dec 19 2016 Back to list
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.

One of the events handled by the BCM firmware is the processing of TDLS connections (802.11z). TDLS connections allow clients to exchange data between one another without passing it through the AP (thus preventing congestion at the AP).

In order to verify the integrity of TDLS messages, each message exchanged between the TDLS peers includes a message integrity code (MIC). The MIC is calculated using AES-CMAC with a key derived during the setup process (TPK-KCK).

When a TDLS Teardown Request frame is sent by either one of the peers in an established TDLS connection, the receiving client must verify the MIC before processing the request. The MIC for TDLS teardown requests is calculated as follows:

AES-CMAC(TPK-KCK, LinkID-IE || ReasonCode || DialogToken || TransactionSeq || FastTransition-IE)

(see "wpa_tdls_key_mic_teardown" under https://w1.fi/cgit/hostap/plain/src/rsn_supp/tdls.c)

It should be noted that all TDLS connections are accepted automatically from any peer and are handled solely by the BCM firmware (meaning there is no need for user interaction or involvement in any way - once a TDLS Setup Request is received by the firmware, it will proceed with the TDLS handshake and subsequently create a TDLS connection with the requesting peer).

When the BCM firmware receives a TDLS Teardown frame, it first verifies the Link-ID information element in order to make sure it matches the current link information. Then, if the Link ID is valid, it calls the "wlc_tdls_cal_teardown_mic_chk" function in order to verify the MIC of the request. The function starts by extracting the Fast Transition IE information element (FTIE - number 55). Then, if the IE is present, its contents are copied into a heap-allocated buffer of length 256. The copy is performed using the length field present in the IE, and at a fixed offset from the buffer's start address. Since the length of the FTIE is not verified prior to the copy, this allows an attacker to include a large FTIE (e.g., with a length field of 255), causing the memcpy to overflow the heap-allocated buffer.

Here's the high-level logic of the "wlc_tdls_cal_teardown_mic_chk" function:

uint8_t* buffer = malloc(256);
...
uint8_t* linkid_ie = bcm_parse_tlvs(..., 101);
memcpy(buffer, linkid_ie, 0x14);
...
uint8_t* ft_ie = bcm_parse_tlvs(..., 55);
memcpy(buf + 0x18, ft_ie, ft_ie[1] + 2);

(Note that each IE is a TLV; the tag and value fields are each a single byte long. Therefore, ft_ie[1] is the IE's length field).

It should also be noted that the heap implementation used in the BCM firmware does not perform safe unlinking or include heap header cookies, allowing heap overflows such as the one described above to be exploited more reliably.

I'm attaching a patch to wpa_supplicant 2.6 which modifies the TDLS Teardown frame sent by the supplicant in order to trigger the heap overflow. You can reproduce the issue by following these steps:

  1. Download wpa_supplicant 2.6 from https://w1.fi/releases/wpa_supplicant-2.6.tar.gz
  2. Apply the included patch file
  3. Build wpa_supplicant (with TDLS support)
  4. Use wpa_supplicant to connect to a network
  5. Connect to wpa_cli:
    5.1. Setup a TDLS connection to the BCM peer using "TDLS_SETUP <MAC_ADDRESS_OF_PEER>"
    5.2. Teardown the connection using "TDLS_TEARDOWN <MAC_ADDRESS_OF_PEER>"

(Where MAC_ADDRESS_OF_PEER is the MAC address of a peer with a BCM SoC which is associated to the same network).

At this point the heap overflow will be triggered. The code in the patch will corrupt the heap, causing the remote BCM SoC to reset after a while.

I've been able to verify this vulnerability on the BCM4339 chip, running version 6.37.34.40 (as present on the Nexus 5). However, I believe this vulnerability's scope includes a wider range of Broadcom SoCs and versions.

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.

 
patch
1.2 KB View Download
Project Member Comment 1 by laginimaineb@google.com, Feb 14
Attaching exploit - running exploit.py results in arbitrary code-execution on the Wi-Fi dongle.

Here is a high-level overview of the exploit:

  1. Create a TDLS connection to the target device
  2. Teardown the connection using a crafted "TDLS Teardown Request" frame, triggering the overflow
  3. Create a new TDLS connection, using crafted arguments causing a situation where two chunks in
     the freelist overlap one another
  4. Send a TDLS frame with action code 127
    4.1. Craft the size of the TDLS frame s.t. it overlaps the other chunk in the freelist
    4.2. Craft the contents in order to point the free chunk to the location of a periodic timer
         which was created during the firmware's initialization
  5. Send another TDLS frame with action code 127
    5.1. Craft the size of the TDLS frame s.t. it will be placed on top of the timer object
    5.2. Craft the contents in order to replace the timer's data structures, allowing us to point
         the timer's handler function at any arbitrary address. In this case, we point the handler
         function at an address near the heap's end
  6. Send a large TDLS frame with action code 127
    6.1. Craft the frame's contents so that it contains the shellcode we'd like to execute
  7. Since the heap is zero-initialized, and "00 00" is NOP (MOVS R0,R0) in Thumb, this means that
     jumping to a location slightly before our created code chunk is fine, as it won't cause any
     adverse affects until we reach our code blob. Putting all this together, Once the timer
     expires, our code chunk is executed on the firmware

Note that sending crafted "TDLS Teardown Request" frames requires modifications to wpa_supplicant.
Moreover, sending TDLS frames with action code 127 requires modifications to both wpa_supplicant
and to the Linux Kernel (mac80211).

These changes (and instructions on how to apply them) are included in the exploit archive attached
to this comment.
TDLSExploit.tar.gz
5.6 MB Download
Project Member Comment 2 by laginimaineb@google.com, Feb 21
Attaching updated exploits for both the Nexus 5 (MRA58K, BCM4339 6.37.34.40) and the Nexus 6P (NUF26K, BCM4358 version 7.112.201.1).
TDLSExploit.tar.gz
11.2 MB Download
Project Member Comment 3 by laginimaineb@google.com, Mar 3
Broadcom Identifier: V2016121901
Project Member Comment 4 by laginimaineb@google.com, Mar 3
Labels: CVE-2017-0561
Project Member Comment 5 by laginimaineb@google.com, Mar 16
Labels: Deadline-Exceeded Deadline-Grace
Broadcom has requested a grace period extension until the April bulletin.
Project Member Comment 6 by laginimaineb@google.com, Mar 28
Adding firmware heap visualisers.

 -create_dot_graph.py - Creates a "dot" graph containing the heap's free-chunks
 -create_html_main_chunk.py - Creates an HTML visualisation of the heap's main region
 -create_html_total.py - Created an HTML visualisation of the entire heap
 -create_trace_html.py - Creates an HTML visualisation for traces from the malloc/free patches
 -profiles.py - The symbols for each firmware "profile"
 -utils.py - Utilities related to handling a firmware snapshot
BCMHeapVisualisers.tar.gz
3.5 KB Download
Project Member Comment 7 by laginimaineb@google.com, Mar 28
Adding script to dump the timer list from a firmware snapshot.
dump_timers.py
1.5 KB View Download
Project Member Comment 8 by laginimaineb@google.com, Mar 28
Adding script to dump PCI ring information from firmware snapshot.
dump_pci.py
5.5 KB View Download
Project Member Comment 9 by laginimaineb@google.com, Mar 28
Adding inline firmware patcher. 

 -patch.py - The patcher itself.
 -apply_* - Scripts to apply each of the patches using dhdutil
 -<DEV>/BCMFreePatch - Patch for the "free" function in the firmware
 -<DEV>/BCMMallocPatch - Patch for the "malloc" function in the firmware
 -<DEV>/BCMDumpMPU - Patch that dumps the MPU's contents
BCMPatcher.tar.gz
6.6 KB Download
Project Member Comment 10 by laginimaineb@google.com, Apr 3
Status: Fixed
Fixed in the April bulletin.
Project Member Comment 11 by hawkes@google.com, Apr 4
Labels: -Restrict-View-Commit
Sign in to add a comment