2017年11月21日星期二

Reading through google zero over the air series. leave out exploit generation, target for fuzzing to find bug.

Over The Air: Exploiting Broadcom’s Wi-Fi Stack (Part 1)

The mobile phone use fullMAC wifi SoC. So we cannot enter monitor mode (MLME) as softMAC which implement frame handling in application processor driver. Now fullMAC SoC handle all PHY, MAC and MAC SubLayer Management Entity(MLME) on its own. So 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.


MLME is responsible for: 
  • Authenticate
  • Deauthenticate
  • Associate
  • Disassociate
  • Reassociate
  • Beacon
mlme.png


Exploit Platform:

Wifi chip use ARM Cortex R4 core, 640KB of ROM, 768KB of RAM.
where is the data that’s loaded into the ARM core’s RAM? initialisation code in the host’s driver
what about the ROM’s contents? interact with the chip via the bcmdhd driver.



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.

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.

memlayout (2).png

Analysing the Firmware


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.

ramlayout (3).png

identifying at least a few strings containing function names and other hints, helping us get a grasp of the code base

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.
SoftMAC has MLME in application process driver, and MLME driver is open sourced. MLME in FullMAC driver in Wifi SoC reused that open source driver. They share many utility functions with the firmware’s code.

Hunting for Bugs


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.


IE.png

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.

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.
Additionally, we’d need to figure out which devices actually support the aforementioned features.
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”.

Over The Air

we’ll need a testbed that’ll enable us to send crafted frames, triggering the overflows. Recall that wpa_supplicant is an open-source portable supplicant that fully supports TDLS. This makes it a prime candidate for our research platform. We could use wpa_supplicant as a base on top of which we’ll craft our frames. That would save us the need to re-implement all the logic entailed in setting up and maintaining a TDLS connection.

we’ll modify wpa_supplicant to allow us to send TDLS Teardown frames containing an overly-large FTIE. Going over wpa_supplicant’s code, we can quickly identify the function in charge of generating and sending the teardown frame - wpa_tdls_send_teardown. By adding a few small changes to this function (in green) we should be able to trigger the overflow upon reception the teardown frame, causing 25 bytes of 0xAB to be written OOB.

Writing an Exploit

Investigating the Heap State
Creating an Overlapping Chunk
Finding a Controlled Allocation

Putting It All Together

Over The Air: Exploiting Broadcom’s Wi-Fi Stack (Part 2)

In this blog post we'll continue our journey into gaining remote kernel code execution, by means of Wi-Fi communication alone. Having previously developed a remote code execution exploit giving us control over Broadcom’s Wi-Fi SoC, we are now left with the task of exploiting this vantage point in order to further elevate our privileges into the kernel.

two distinct avenues for attacking the host operating system.
first part, exploit vulnerabilities in the communication protocols between the Wi-Fi firmware and the host, resulting in code execution within the kernel.
second part, explore hardware design choices allowing the Wi-Fi SoC in its current configuration to fully control the host without requiring a vulnerability in the first place.

While the vulnerabilities discussed in the first part have been disclosed to Broadcom and are now fixed, the utilisation of hardware components remains as it is, and is currently not mitigated against.

Part 1 - The “Hard” Way

The Communication Channel

interfaces.png



When the firmware wishes to notify the host of an event, it does so by simply encoding a “special” frame and transmitting it to the host. These frames are marked by a “unique” EtherType value of 0x886C. They do not contain actual received data, but rather encapsulate information about firmware events which must be handled by the host’s driver.
ethertype (1).png

Securing the Channel

driver layers.png

This is a crucial question; the internal event channel, as we’ll see shortly, is extremely powerful and provides a huge, mostly unaudited, attack surface. If attackers are able to inject frames over-the-air that can subsequently be processed as event frames by the driver, they may very well be able to achieve code execution within the host’s operating system.

Until (mid 2016), the firmware made no effort to filter these frames. Any frame received as part of the data RX-path, regardless of its ethertype, was simply forwarded blindly to the host.

The patch adds a validation method (is_wlc_event_frame) both to the firmware’s RX path, and to the driver.

On the chip’s  side, the validation method is called immediately before transmitting a received frame to the host.


rxflow (2).png

However… Since we already have code-execution on the Wi-Fi SoC, we can simply “revert” the patch. All it takes is for us to “patch out” the validation method in the firmware, thereby causing any received frame to once again be forwarded blindly to the host.
patchrxflow.png


The Attack Surface

As we mentioned earlier, the attack surface exposed by the internal communication channel is huge. Tracing the control flow from the entry point for handling event frames (dhd_wl_host_event), we can see that several events receive “special treatment”, and are processed independently (see wl_host_event and wl_show_host_event). Once the initial treatment is done, the frames are inserted into a queue. Events are then dequeued by a kernel thread whose sole purpose is to read events from the queue and dispatch them to their corresponding handler function. This correlation is done by using the event’s internal “event-type” field as an index into an array of handler functions, called evt_handler.
handler_queue (1).png

The Vulnerability

Reading through the driver’s code, we can see that when this event code is received, an initial handler is triggered in order to deal with the event.
swc.png


Remote Kernel Heap Shaping

Analysing The Constraints

Putting It All Together

Putting this all together, we can now simply send along a SWC event frame in order to reclaim the evt_handler function pointer array, and populate it with our own contents. As there is no KASLR, we can search for a stack pivot gadget in the kernel image that will allow us to gain code execution.

Part 2 - The “Easy” Way

Not only are the Wi-Fi SoC and the host physically proximate to one another, they also share a physical communication interface.

The increased transfer rates caused PCIe to become the most prevalent interface used to connect Wi-Fi SoCs in modern mobile devices.

PCIe, unlike PCI, is based on a point-to-point topology. Every device has it’s own serial link connecting it to the host.

since the Nexus 6, all devices use a PCIe interface instead of SDIO. since the iPhone 6 use PCIe (whereas old iPhones used USB to connect to the Wi-Fi SoC)

Interface Isolation

PCIe is significantly different to SDIO and USB in terms of isolation. Without going into the internals of each of the interfaces, SDIO simply allows the serial transfer of small command “packets” (on the CMD pin), potentially accompanied by data (on the DATA pins).
While SDIO may support DMA (for example, the host can set up a DMA engine to continually read data from the SD bus and transfer it to memory), this feature is not used on mobile devices
Likewise, USB (up to version 3.1) does not include support for DMA.

In contrast to these two interfaces, PCIe allows for DMA by design. This allows PCIe to operate at great speeds without incurring a performance hit on the host. Once data is transferred to the host’s memory, an interrupt is fired to indicate that work needs to be done.

On the transaction layer, PCIe operates by sending small bundles of data, appropriately named “Transaction Layer Packets” (TLPs). Each TLP may be routed by a network of switches, until it reaches the destined peripheral. There, the peripheral decodes the packet and performs the requested memory operation. The TLP’s header encodes whether this is a requested read or write operation, and its body contains any accompanying data related to the request.
Screenshot from 2017-03-24 12:08:51.png
IOU an MMU
While PCIe enables DMA by design, that still doesn’t imply that any PCIe connected peripheral should be able to freely access any memory address on the host. Indeed, modern architectures defend themselves against DMA-capable peripherals by including additional memory mapping units (IOMMUs) on the IO buses connecting the peripherals to main memory.

ARM specifies its own version of an IOMMU, called the “System Memory Mapping Unit” (SMMU).
Screenshot from 2017-03-24 12:30:28.png

Broadcom implements their own proprietary protocol called “MSGBUF” in order to communicate with the Wi-Fi chip over PCIe. The host’s implementation of the protocol and the code for handling PCIe can be found under dhd_msgbuf.c and dhd_pcie.c, respectively.

Going over the driver’s code, it appears that the host and the chip hold a shared structure, pciedev_shared_t, containing all the PCIe-related metadata, including the location of each of the ring buffers. The host holds its own copy of this structure, but where does the Wi-Fi SoC keep its copy? According to the dhdpcie_readshared function, it appears that the Wi-Fi chip stores a pointer to this structure in the last four bytes of its RAM.
rings.png


The Wi-Fi chip managed to DMA into the physical address range containing the host’s kernel, without any interference! This finally confirms our suspicion; either there is no SMMU present, or it isn’t configured to prevent the chip from accessing the host’s RAM.
Not only does this kind of access not require a single vulnerability, but it is also much more reliable to exploit. There’s no need for the exact kernel symbols, or any other preliminary information. The Wi-Fi SoC can simply use its DMA access to scan the physical address ranges in order to locate the kernel. Then, it can identify the kernel’s symbol table in RAM, analyse it to locate the any kernel function it wishes, and proceed to hijack the function by overwriting its code (one such example can be seen in this similar DMA-like attack). All in all, this style of attack is completely portable and 100% reliable -- a significant step-up from the previous exploit we saw.

We managed to DMA arbitrary data into an address of our choosing. Using this primitive, we can finally hijack any kernel function with our own crafted data.
Afterword

The current lack of isolation can also have some surprising side effects. For example, Android contexts which are able to interact with the Wi-Fi firmware, can leverage the Wi-Fi SoC’s DMA capability in order to directly hijack the kernel.




没有评论:

发表评论