Lucene search

K
seebugRootSSV:92894
HistoryApr 05, 2017 - 12:00 a.m.

Broadcom: Heap overflow in TDLS Teardown Request while handling Fast Transition IE (CVE-2017-0561)

2017-04-0500:00:00
Root
www.seebug.org
63

0.201 Low

EPSS

Percentile

95.8%

详细分析:https://googleprojectzero.blogspot.tw/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html

Posted by Gal Beniamini, Project Zero

It’s a well understood fact that platform security is an integral part of the security of complex systems. For mobile devices, this statement rings even truer; modern mobile platforms include multiple processing units, all elaborately communicating with one another. While the code running on the application processor (AP) has been the subject of much research, other components have seldom received the same scrutiny.

Over the years, as a result of the focused attention by security folk, the defenses of code running on the application processor have been reinforced. Taking Android as a case study, this includes hardening the operating system, improving the security of applications, and introducing incremental security enhancements affecting the entire system. All positive improvements, no doubt. However, attackers tend to follow the path of least resistance. Improving the security of one component will inevitably cause some attackers to start looking elsewhere for an easier point of entry.

In this two-part blog series, we’ll explore the exposed attack surface introduced by Broadcom’s Wi-Fi SoC on mobile devices. Specifically, we’ll focus our attention on devices running Android, although a vast amount of this research applies to other systems including the same Wi-Fi SoCs. The first blog post will focus on exploring the Wi-Fi SoC itself; we’ll discover and exploit vulnerabilities which will allow us to remotely gain code execution on the chip. In the second blog post, we’ll further elevate our privileges from the SoC into the the operating system’s kernel. Chaining the two together, we’ll demonstrate full device takeover by Wi-Fi proximity alone, requiring no user interaction.

We’ll focus on Broadcom’s Wi-Fi SoCs since they are the most common Wi-Fi chipset used on mobile devices. A partial list of devices which make use of this platform includes the Nexus 5, 6 and 6P, most Samsung flagship devices, and all iPhones since the iPhone 4. For the purpose of this blog post, we’ll demonstrate a Wi-Fi remote code execution exploit on a fully updated (at the time) Nexus 6P, running Android 7.1.1 version NUF26K.

All the vulnerabilities in the post have been disclosed to Broadcom. Broadcom has been incredibly responsive and helpful, both in fixing the vulnerabilities and making the fixes available to affected vendors. For a complete timeline, see the bug tracker entries. They’ve also been very open to discussions relating to the security of the Wi-Fi SoC.

I would like to thank Thomas Dullien (@halvarflake) for helping boot up the research, for the productive brainstorming, and for helping search the literature for any relevant clues. I’d also like to thank my colleagues in the London office for helping make sense of the exploitation constraints, and for listening to my ramblings. Why-Fi?

In the past decade, the use of Wi-Fi has become commonplace on mobile devices. Gradually, Wi-Fi has evolved into a formidable set of specifications-some detailing the physical layer, others focusing on the MAC layer. In order to deal with this increased complexity, vendors have started producing “FullMAC” Wi-Fi SoCs.

In essence, these are small SoCs that perform all the PHY, MAC and MAC SubLayer Management Entity (MLME) processing on their own, allowing the operating system to abstract itself away from the complex (and sometimes chip-specific) features related to Wi-Fi. The introduction of Wi-Fi FullMAC chips has also improved the power consumption of mobile devices, since much of the processing is done on a low-power SoC instead of the power-hungry application processor. Perhaps most importantly, FullMAC chips are much easier to integrate, as they implement the MLME within their firmware, reducing the complexity on the host’s side.

All that said and done, the introduction of Wi-Fi FullMAC chips does not come without a cost. Introducing these new pieces of hardware, running proprietary and complex code bases, may weaken the overall security of the devices and introduce vulnerabilities which could compromise the entire system.

Exploring the Platform

To start off our research, we’ll need to find some way to explore the Wi-Fi chip. Luckily, Cypress has recently acquired Broadcom’s Wireless IOT business, and have published many of the datasheets related to Broadcom’s Wi-Fi chipsets (albeit for a slightly older SoC, the BCM4339). Reading through the datasheet, we gain some insight into the hardware architecture behind the Wi-Fi chipset.

Specifically, we can see that there’s an ARM Cortex R4 core, which runs all the logic for handling and processing frames. Moreover, the datasheet reveals that the ARM core has 640KB of ROM used to hold the firmware’s code, and 768KB of RAM which is used for data processing (e.g., heap) and to store patches to firmware code.

To start analysing the code running on the ARM core, we’ll need to extract the contents of the ROM, and to locate the data that is loaded into RAM.

Let’s start by tackling the second problem first - where is the data that’s loaded into the ARM core’s RAM? Since this data is not present in ROM, it must be loaded externally when the chip first powers on. Therefore, by reading through the initialisation code in the host’s driver, we should be able to locate the file containing the RAM’s contents. Indeed, going over the driver’s code, we find the BCMDHD_FW_PATH config, which is used to denote the location of the file whose contents are uploaded to RAM by the driver.

So what about the ROM’s contents? One way to extract the ROM would be to use the host driver’s chip memory access capabilities (via PIO over SDIO or PCIe) to read the ROM’s contents directly. However, doing so would require modifying the driver to enable us to issue the commands needed to dump the ROM. Another way to retrieve the ROM would be to load our own modified firmware file into RAM, into which we’ll insert a small stub that can be used to dump the ROM’s memory range. Luckily, none of these approaches is actually needed in this case; Broadcom provides an extremely powerful command-line utility called dhdutil, which can be used to interact with the chip via the bcmdhd driver.

Among the various capabilities this utility supports, it also allows us to directly read and write memory on the dongle by issuing a special command - “membytes”. Since we already know the size of the ROM (from the datasheet), we can just use the membytes command to read the ROM’s contents directly. However, there’s one last question we need to answer first - where is the ROM located? According to the great research done by the folks behind NexMon, the ROM is loaded at address 0x0, and the RAM is loaded at address 0x180000 (while NexMon focused on BCM4339, this fact remains true for newer chips as well, such as the BCM4358).

Finally, putting all this together, we can acquire the RAM’s contents from the firmware file, dump the ROM using dhdutil, and combine the two into a single file which we can then start analysing in IDA.

Analysing the Firmware

Due to the relatively small size of the available memory (both ROM and RAM), Broadcom went to extreme efforts in order to conserve memory. For starters, they’ve stripped the symbols and most of the strings from the binary. This has the added bonus of making it slightly more cumbersome to reverse-engineer the firmware’s code. They’ve also opted for using the Thumb-2 instruction set exclusively, which allows for better code density. As a result, the ROM image on the BCM4358 is so tightly packed that it contains less than 300 unused bytes.

However, this is still not quite enough… Remember that the RAM has to accommodate the heap, stack and global data structures, as well as all the patches or modifications to ROM functions. Quite a tall order for a measly 768KB. To get around this, Broadcom has decided to place all the functions that are only used during the firmware’s initialisation in two special regions. Once the initialisation is completed, these regions are “reclaimed”, and are thereafter converted into heap chunks.

What’s more, heap chunks are interspersed between code and data structures in RAM - since the latter sometimes have alignment requirements (or are referenced directly from ROM, so they cannot be moved). The end result is that RAM is a jumbled mess of heap chunks, code and data structures.

After spending some time analysing the firmware, we can begin identifying at least a few strings containing function names and other hints, helping us get a grasp of the code base. Additionally, the NexMon researchers have released their gathered symbols corresponding to firmware on the BCM4339. We can apply the same symbols to the BCM4339’s firmware, and then use bindiff to correlate the symbol names in newer firmware versions for more recent chips.

Lastly, there’s one more trick in our hat - Broadcom produces SoftMAC chips in addition to the FullMAC SoCs we’re analysing. Since these SoftMAC chips don’t handle the MLME layer, their corresponding driver must perform that processing. As a result, much of Broadcom’s MLME processing code is included in the open-source SoftMAC driver - brcmsmac. While this won’t help us out with any of the chip-specific features or the more internal processing code, it does seem to share many utility functions with the firmware’s code. Hunting for Bugs

Now that we have a grasp of the firmware’s structure and have the means to analyse it, we can finally start hunting for bugs. But… Where should we start?

Even with all the tricks mentioned before, this is a relatively large and opaque binary, and strings or symbols are few and far between. One possibility would be to instrument the firmware in order to trace the code paths taken while a packet is received and processed. The Cortex R4 does, indeed, have debug registers which can be used to place breakpoints and inspect the code flow at various locations. Alternately, we could manually locate a set of functions which are used to parse and retrieve information from a received frame, and work our way backwards from there.

This is where familiarity with Wi-Fi comes in handy; Wi-Fi management frames encode most of their information in small “tagged” chunks of data, called Information Elements (IEs). These tagged chunks of data are structured as TLVs, where the tag and length fields are a single byte long.

Since a large portion of the information transferred in Wi-Fi frames (other than the data itself) is encoded using IEs, they make for good candidates from which we can work our way backwards. Moreover, as “tag” values are unique and standardised, we can use their values to help familiarise ourselves with the currently handled code flow.

Looking at the brcmsmac driver, we can see that there’s a single function which Broadcom uses in order to extract IEs from a frame - bcm_parse_tlvs. After a brief search (by correlating hints from nearby strings), we find the same function in the firmware’s ROM. Great.

Now we can start cross-referencing locations which call this function, and reverse each of these call-sites. While substantially easier than reversing every part of the firmware, this still takes a considerable amount of time (as the function has more than 110 cross-references, some to other wrapper functions which themselves are called from multiple locations).

After reverse engineering all of the call sites, I’ve found a few vulnerabilities related to the handling of information elements embedded in management frames.

Two of the vulnerabilities can be triggered when connecting to networks supporting wireless roaming features; 802.11r Fast BSS Transition (FT), or Cisco’s CCKM roaming. On the one side, these vulnerabilities should be relatively straightforward to exploit - they are simple stack overflows. Moreover, the operating system running on the firmware (HNDRTE) does not use stack cookies, so there’s no additional information leak or bypass required.

However, while these vulnerabilities may be comfortable to exploit, they require some set-up to get working. First, we’d need to broadcast Wi-Fi networks that support these features. 802.11r FT is an open(-ish) standard, and is implemented by hostapd. In contrast, CCKM is a proprietary standard (although some information can be found online). Figuring out how to emulate a CCKM network (or buying a CCKM-capable WLC from Cisco) would be cumbersome (or costly).

Additionally, we’d need to figure out which devices actually support the aforementioned features. Broadcom provides many features which can be licensed by customers – not all features are present on all devices (in fact, their corresponding patches probably wouldn’t even fit in RAM).

Luckily, Broadcom makes it easy to distinguish which features are actually present in each firmware image. The last few bytes in the RAM contents downloaded to the chip contain the firmware’s “version string”. This string contains the date at which the firmware was compiled, the chip’s revision, the firmware’s version and a list of dash-delimited “tags”. Each tag represents a feature that is supported by the firmware image. For example, here’s the version string from the Nexus 6P:

4358a3-roml/pcie-ag-p2p-pno-aoe-pktfilter-keepalive-sr-mchan-pktctx-hostpp-lpc-pwropt-txbf-wl11u-mfp-betdls-amsdutx5g-txpwr-rcc-wepso-sarctrl-btcdyn-xorcsum-proxd-gscan-linkstat-ndoe-hs20sta-oobrev-hchk-logtrace-rmon-apf-d11status Version: 7.112.201.1 (r659325) CRC: 8c7aa795 Date: Tue 2016-09-13 15:05:58 PDT Ucode Ver: 963.317 FWID: 01-ba83502b

The presence of the 802.11r FT feature is indicated by the “fbt” tag. Similarly, support for CCKM is indicated by the “ccx” tag. Unfortunately, it seems that the Nexus 6P supports neither of these features. In fact, running a quick search for the “ccx” feature (CCKM support) on my own repository of Android firmware images revealed that this feature is not supported on any Nexus device, but is supported on a wide variety of Samsung flagship devices, a very partial list of which includes the Galaxy S7 (G930F, G930V), the Galaxy S7 Edge (G935F, G9350), the Galaxy S6 Edge (G925V) and many more.

So what about the other two vulnerabilities? Both of them relate to the implementation of Tunneled Direct Link Setup (TDLS). TDLS connections allow peers on a Wi-Fi network to exchange data between one another without passing it through the Access Point (AP), thus preventing congestion at the AP.

Support for TDLS in the firmware is indicated by the “betdls” and “tdls” tags. Searching through my firmware repository I can see that the vast majority of devices do, indeed, support TDLS. This includes all recent Nexus devices (Nexus 5, 6, 6P) and most Samsung flagships.

What’s more, TDLS is specified as part of the 802.11z standard (requires IEEE subscription). Since all the information regarding TDLS is available, we could read the standard in order to gain familiarity with the relevant code paths in Broadcom’s implementation. As an open standard, it is also supported by open-source supplicants, such as wpa_supplicant. As a result, we can inspect the implementation of the TDLS features in wpa_supplicant in order to further improve our understanding of the relevant code in the firmware.

Lastly, as we’ll see later on, triggering these two vulnerabilities can be done by any peer on the Wi-Fi network, without requiring any action on the part of the device being attacked (and with no indication that such an attack is taking place). This makes these vulnerabilities all the more interesting to explore.

In any case, it seems like we’ve made our mind up! We’re going to exploit the TDLS vulnerabilities. Before we do so, however, let’s take a second to learn a little bit about TDLS, and the vulnerabilities discovered (skip this part it you’re already familiar with TDLS).

802.11z TDLS 101

There are many use cases where two peers on the same Wi-Fi network wish to transfer large swaths of data between one another. For example, casting a video from your mobile device to your Chromecast would require large amounts of data to be transmitted. In most cases, the Chromecast would be relatively nearby to the caster (after all, you’d probably be watching the screen to which you’re casting). Therefore, it would seem wasteful to pass the entire data stream from the device to the AP, only to then pass it on to the Chromecast.

It’s not just the increased latency of adding an additional hop (the AP) that will degrade the connection’s quality. Passing such large amounts of data to the AP would also put a strain on the AP itself, cause congestion, and would degrade the Wi-Fi connectivity for all peers on the network.

This is where TDLS comes into play. TDLS is meant to provide a means of peer-to-peer communication on a Wi-Fi network that is AP-independant. Over The Air

Let’s start by familiarising ourselves with the structure of TDLS frames. As you may know, 802.11 frames use the “flags” field in order to indicate the “direction” in which a frame is travelling (from the client to the AP, AP to client, etc.). TDLS traffic co-opts the use of the flag values indicating traffic in an Ad-Hoc (IBSS) network (To-DS=0, From-DS=0).

Next, TDLS frames are identified by a special ethertype value - 0x890D. TDLS frames transmitted over Wi-Fi use a constant value in the “payload type” field, indicating that the payload has the following structure:

The category for TDLS frames is also set to a constant value. This leaves us with only one field which distinguishes between different TDLS frame types - the “action code”. This 1-byte field indicates the kind of TDLS frame we’re transmitting. This, in turn, controls the way in which the “payload” in interpreted by the receiving end. High-Level Flow

Before two peers can establish a connection, they must first know about the existence of one another. This is called the “discovery” phase. A Wi-Fi client that wishes to discover TDLS-capable peers on the network, can do so by sending a “TDLS Discovery Request” frame to a peer. A TDLS-capable peer that receives this frame, responds by sending a “TDLS Discovery Response” frame. The request and response are correlated to one another using a 1-byte “dialog token”.

Next, the peers may wish to set up a connection. To do so, they must perform a 3-way handshake. This handshake serves a dual purpose; first, it indicates that a connection is successfully established between the two peers. Second, it’s used to derive the TDLS Peer Key (TPK), which secures the TDLS traffic between the peers.

Finally, once the connection is created, the two peers can exchange peer traffic between one another. When one of the peers wishes to tear-down the connection, they may do so by sending a “TDLS Teardown” frame. Upon reception of such a frame, the TDLS-peer will remove the connection and free up all the related resources.

Now that we know enough about TDLS, let’s take a closer look at the vulnerabilities at hand!