Wednesday, October 11, 2017

Over The Air - Vol. 2, Pt. 3: Exploiting The Wi-Fi Stack on Apple Devices

Posted by Gal Beniamini, Project Zero

In this blog post we’ll complete our goal of achieving remote kernel code execution on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7, by means of Wi-Fi communication alone.

After developing a Wi-Fi firmware exploit in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 previous blog post, we are left with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 task of using our newly acquired access to gain control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XNU kernel. To this end, we’ll begin by investigating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 isolation mechanisms present on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone. Next, we’ll explore cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ways in which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host interacts with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, identify several attack surfaces, and assess cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding security properties. Finally, we’ll discover multiple vulnerabilities and proceed to develop a fully-functional reliable exploit for one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, allowing us to gain control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s kernel.


All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerabilities presented in this blog post (#1, #2, #3, #4, #5, #6, #7) were reported to Apple and subsequently fixed in iOS 11. For an analysis of ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r affected devices in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Apple ecosystem, see cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding security bulletins.

Hardware Isolation

PCIe DMA


Broadcom’s Wi-Fi chips are present in a wide range of platforms; including mobile phones, IOT devices and Wi-Fi routers. To accommodate for this variance, each chip must be sufficiently configurable, supporting several different interfaces for vendors wishing to integrate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir platform. Indeed, Cypress’s data sheets include a wide range of supported interfaces, including PCIe, SDIO and USB.


While choosing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interface with which to integrate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip may seem inconsequential, it could have far ranging security implications. Each interface comes with different security guarantees, affecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 degree to which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peripheral may be “isolated” from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. As we’ve already demonstrated how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip’s security can be subverted by remote attackers, it’s clear that providing isolation is crucial in sufficiently safeguarding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

From a security perspective, both SDIO and USB (up to 3.1) inherently offer some degree of isolation. SDIO solely enables cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 serial transfer of information between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target device. Similarly, USB allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transfer of “packets” between peripherals and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Broadly speaking, both interfaces can be thought of as facilitating an explicit communication channel between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peripheral. All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data transported through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se interfaces must be explicitly handled by eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r peer, by inspecting incoming requests and responding accordingly.

PCIe operates using a different paradigm. Instead of communicating with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host using a communication protocol, PCIe allows peripherals to gain Direct Memory Access (DMA) to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory. Using DMA, peripherals may autonomously prepare data structures within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory, only signalling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host (via a Message Signalled Interrupt) once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s processing to be done. Operating in this manner allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to conserve computing resources, as opposed to protocols that require processing to transfer data between endpoints or to handle each individual request.

Efficient as this approach may be, it also raises some challenges with regards to isolation. First and foremost, how can we be guaranteed that malicious peripherals won’t abuse this access in order to attack cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host? After all, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of full control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory, subverting any program running on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host is trivial (for example, peripherals may freely modify a program’s stack, alter function pointers, overwrite code -- all unbeknownst to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host itself).

Luckily, this issue has not gone unaddressed. Sufficient isolation for DMA-capable components can be achieved by partitioning cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 visible memory space available to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peripheral using a dedicated hardware component - an I/O Memory Management Unit (IOMMU).


IOMMUs facilitate a memory translation service for peripherals, converting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir addressable memory ranges (referred to as “IO-Space”) into ranges within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s Physical Address Space (PAS). Configuring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IOMMU’s translation tables allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to selectively control which portions of its memory are exposed to each peripheral, while safeguarding ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r ranges against potentially malicious access. Consequently, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bulk of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 responsibility for providing sufficient isolation lays with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

Returning to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue at hand, as we are focusing on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi stack present within Apple’s ecosystem, an immediate question springs to mind -- which interfaces does Apple leverage to connect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host? Inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware images present in several generations of Apple devices reveals that since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 6 (included), Apple has opted for PCIe to connect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Older models, such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 5c and 5s, relied on a USB interface instead.


Due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 risks highlighted above, it is crucial that recent iPhones utilise an IOMMU to isolate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves from potentially malicious PCIe-connected Wi-Fi chips. Indeed, during our previous research into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 isolation mechanisms on Android devices, we discovered that no isolation was enforced in two of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 most prominent SoCs; Qualcomm’s Snapdragon 810 and Samsung’s Exynos 8890, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip to freely access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory (leading to complete compromise of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device).

Inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA Engine


To gain some visibility into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 isolation capabilities present on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7, we’ll begin by exploring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware itself. If a form of isolation is present, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory ranges used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi SoC to perform DMA operations and those utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host would be disparate. Conversely, if we happen to find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same ranges of physical addresses, that would hint that no         isolation is taking place.

Luckily, much of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 complexity involved in reverse-engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s DMA functionality can be forgone, as Broadcom’s SoftMAC drivers (brcm80211) contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 majority of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code used to interface with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SoC’s DMA engine.

Each DMA engine facilitates transfers in a single direction between two endpoints; one representing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware, and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r denoting eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r an internal core within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi SoC (such as when interacting with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RX or TX FIFOs) or cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host itself. As we are interested in inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory ranges used for transfers originating in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip and terminating at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, we must locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA engine responsible for “dongle-to-host” memory transfers.

As it happens, this task is racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r straightforward. Each “dma_info” structure in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware (representing a DMA engine) is prefixed by a pointer to a block of DMA-related function pointers stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s RAM. Since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 block is placed at a fixed address, we can locate all instances of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 structure by searching for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s RAM. For each instance we come across, inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “name” field encoded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 structure should allow us to deduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 identity of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA engine in question.


Combining cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se two tidbits, we can quickly locate each DMA engine in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s RAM:


The first few instances clearly relate to internal DMA engines. The last instance, labeled “H2D”, indicates “host-to-dongle” memory transfers. Therefore, by elimination, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 single entry left must correspond to transfers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dongle to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host (sneakily left unnamed!).

Having located cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 engine, all that remains is to dump cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RX descriptor ring and extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 addresses to which DMA transfers are performed. Unfortunately, descriptors are rapidly consumed after being inserted into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding rings, replacing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir contents with generic placeholder values. Therefore, observing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of a non-consumed descriptor from a single memory snapshot is tricky. Instead, to extract “fresh” descriptors, we’ll insert a hook on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA transfer function, allowing us to dump descriptor addresses before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are inserted into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding rings.

After inserting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hook, we are presented with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following output:


All of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptor addresses appear to be 32-bits wide...

How do cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above addresses relate to our knowledge of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address space on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7? The DRAM’s base address in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical address space is denoted by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “gPhysBase” variable (stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s BSS). Reading this value from our research platform will allow us to determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA descriptor addresses correspond to host-side physical ranges:


Ah-ha! The iPhone 7’s DRAM is based at 0x800000000 -- an address beyond a 32-bit range.

Therefore, some form of conversion is taking place between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ranges visible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip (IO-Space) and those corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical address space. To locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 root cause of this conversion, let’s shift our attention back towards cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

DART


The host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip communicate with one anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r using a protocol designed by Broadcom, dubbed “MSGBUF”. Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol, both endpoints are able to transmit and receive control messages, as well as traffic, through a set of “message rings”. Each ring is stored within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory, but is also made accessible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware through DMA.

Since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rings must be accessible through DMA to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-FI chip, locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code responsible for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir initialisation might shed some light on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process through which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir physical addresses are converted to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA-accessible addresses we encountered in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s DMA descriptors.

Reverse-engineering AppleBCMWLANBusInterfacePCIe, we quickly arrive at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function responsible for initialising cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IPC structures utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned rings:

1.  void* init_ring(void* this, uint64_t alignment, IOMapper* mapper, ...) {
2.      ...
3.      IOOptionBits options = kIOMemoryTypeVirtual | kIODirectionOutIn;
4.      IOBufferMemoryDescriptor* desc =
5.          IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task,
6.                                                      options,
7.                                                      capacity,
8.                                                      alignment);                                    
9.      ...
10.     IODMACommand* cmd = IODMACommand::withSpecification(
11.         IODMACommand::OutputLittle64,  //outSegFunc
11.         0,                             //numAddressBits
12.         0,                             //maxSegmentSize
13.         0,                             //mappingOptions
14.         0,                             //maxTransferSize
15.         1,                             //alignment
16.         mapper,                        //mapper
17.         0);                            //refCon
18      ...
19.     cmd->setMemoryDescriptor(desc, true);
20.     ...
21. }
function 0xFFFFFFF006D1C074

As we can see above, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function utilises I/O Kit APIs to manage and map DMA-capable descriptors.

Upon closer inspection, we can see that IODMACommand defers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual mapping operations to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 provided IOMapper instance (“mapper” in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 snippet above). However, as luck would have it, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same “mapper” object is stored within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “PCIe object” we identified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first part of our research. Therefore, we can proceed to extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IOMapper instance and begin tracing through its associated code paths.

While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source code for IOMapper is available in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 open-sourced portions of XNU, it does not perform any actual mapping operations, but racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r delegates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “System Mapper” - a globally registered IOMapper instance. Since no concrete subclasses of IOMapper are present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 open-sourced portions of XNU, we can assume that a specialised subclass, performing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual mapping implementation, exists in one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 proprietary KEXTs.

Indeed, following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 extracted IOMapper’s virtual table, we arrive at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IODARTMapper class, under com.apple.driver.IODARTFamily -- it seems a specialised IOMapper is used after all!

Before we continue down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rabbit hole, let’s take a step back and assess cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 situation. According to Apple’s documentation, DART stands for “Device Address Resolution Table” -- a hardware component integrated into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory controller, whose purpose it is to provide a separate address space mapping for 32-bit PCI peripherals. DART allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system to map physical addresses beyond cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 32-bit range to peripherals, and to provide fine-grained control over exposed memory ranges to each device. In short, this is non ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than a proprietary IOMMU designed by Apple!

Digging deeper into IODARTMapper, we find iovmInsert; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entry point for inserting new IO-Space translations through a mapper. Passing through several more layers of indirection, we finally arrive at an instance of AppleS5L8960XDART.


The latter object originates in a different driver; com.apple.driver.AppleS5L8960XDART. It appears we’re getting closer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bare-metal DART implementation for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SoC! Oddly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 driver references “S5L8960X”; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 product code for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Apple A7 SoC (used in older iPhones, such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 5s). Perhaps this artefact suggests that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same DART implementation has been used in prior SoC revisions.

Taking a closer look at AppleS5L8960XDART, we quickly come across a function of particular interest. This function performs many bit shifts and masks, much like we’d expect from translation-table management code. After spending some time familiarising ourselves with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code, we come to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 realisation that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function is responsible for populating DART’s translation tables! Here is a high-level representation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 relevant code:

1.  void* create_descriptors(void* this, uint64_t table_index,
2.                           uint32_t start_pfn, uint32_t map_size, ...) {
3.
4.      ... //Validate input arguments, acquire mutex
5.      void** dart_table = ((void***)(this + 312))[table_index];
6.      uint32_t end_pfn  = start_pfn + map_size;
7.
8.      //Populating each L0 descriptor in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range
9.      uint32_t l0_start_idx = (start_pfn >> 18) & 0x3;
10.     uint32_t l0_end_idx   = (end_pfn   >> 18) & 0x3;
11.      
12.     for (uint32_t l0_idx = l0_start_idx; l0_idx <= l0_end_idx; l0_idx++) {
13.      
14.         //Creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L1 table if it doesn’t already exist
15.         struct l1_table_t* l1_table = (struct l1_table_t*)(dart_table[l0_idx]);
16.         if (!l1_table) {
17.             l1_table = allocate_l1_table(this);
18.             dart_table[l0_idx] = l1_table;
19.             uint64_t table_phys = l1_table->desc->getPhysicalSegment(...);
20.             uint64_t l0_desc = ((table_phys >> 12) & 0xFFFFFF) | 0x80000000;
21.             OSSynchronizeIO();
22.             set_l0_desc(this, table_index, l0_idx, l0_desc);
23.         }
24.   
25.         //Calculating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range of L1 descriptors to populate
26.         uint32_t l1_start_idx = (l0_idx == l0_start_idx) ?
27.                                      (start_pfn >> 9) & 0x1FF : 0;
28.         uint32_t l1_end_idx   = (l0_idx == l0_end_idx) ?
29.                                      (end_pfn   >> 9) & 0x1FF : 511;
30.
31.         //Populating each L1 descriptor in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 range
32.         for (uint32_t l1_idx = l1_start_idx; l1_idx <= l1_end_idx; l1_idx++) {
33.
34.             //Creating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L2 table if it doesn’t already exist
35.             struct l2_table_t* l2_table;
36.             l2_table = (struct l2_table_t*)l1_table->l2_tables[l1_idx];
37.             if (!l2_table) {
38.                 l2_table = allocate_l1_desc(this);
39.                 l1_table->l2_tables[l1_idx] = l2_table;
40.                 uint64_t table_phys = l2_table->desc->getPhysicalSegment(...);
41.                 l1_table->descriptors[l1_idx] = (table_phys & 0xFFFFFF000) | 3;
42.                 OSSynchronizeIO();
43.                 ...
44.             }
45.         }
46.     }
47.     ... //Release mutex
48.  }
49.
50. struct l1_table_t {
51.    IOBufferMemoryDescriptor* desc;      //Descriptor holding L1 table
52.    uint64_t* descriptors;               //Kernel VA ptr to L1 descs
53.    struct l2_table_t* l2_tables[512];   //L2 descriptors within this table
54. };
55.
56. struct l2_table_t {
57.     IOBufferMemoryDescriptor* desc;     //Descriptor holding L2 table
58.     uint64_t* descriptors;              //Kernel VA ptr to L2 descs
59.     uint64_t unknown;
60. };
function 0xFFFFFFF0065978F0

Alright! Let’s take a moment to unpack cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above function.

For starters, it appears that DART utilises a 3-level translation regime. The first level is capable of holding up to four descriptors, while each subsequent level holds 512 descriptors. Since DART uses a 4KB translation granule, we can deduce that, in ascending order, L2 table maps 0x200000 bytes into IO-Space, while L1 tables map up to 0x40000000 bytes.

In addition to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 3-level regime specified above, DART holds four “base descriptors”. Unlike regular descriptors, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se are not indexed by bits in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space address, but are instead referenced explicitly using a parameter provided by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 caller.

Drawing on our knowledge of PCIe, we can speculate on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 nature of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se “base descriptors”. Perhaps each DART can facilitate mappings for several different PCI peripherals on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same bus, where each “base descriptor” corresponds to one such device (based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “Requester-ID” encoded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 incoming TLP)? Whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r or not this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case, dumping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “base descriptors” in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART instance corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip reveals that only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first descriptor is populated in our case.

In order to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART mappings, two distinct sets of data structures are utilised in tandem; a set of “convenience” structures which map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation hierarchy into high-level objects within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s virtual address space, and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r set holding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptors cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves, which are linked togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r based on physical addresses. The former set is used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel to conveniently locate and modify DART’s mappings, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latter is used by DART’s hardware to perform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual IO-Space translations.



Looking more closely at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptors, it appears that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation format utilised by DART is proprietary, and does not match cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 formats present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARM VMSA (including those utilised by SMMUs). Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, we can deduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptors’ composition by inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code above, which constructs and populates descriptors across cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation hierarchy.

L0 descriptors encode cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical frame number (using a 4KB translation granule) corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next level table in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower bits, and set cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 31st bit to indicate a valid entry. L1 and L2 descriptors, on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hand, use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bottom two bits to indicate validity (setting both bits denotes a valid entry, ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r combinations result in translation faults), while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 top bits store cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address of eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next translation table or of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 4KB region mapped into IO-Space.


Lastly, we must deduce IO-Space’s base address to complete our analysis of DART’s translation format. Drawing on our previous encounter with IO-Space addresses stored in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA descriptors within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware, all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 addresses appeared to be based at address 0x80000000. As such, it seems like a fair assumption that IO-Space mappings for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip begin at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned address.

Combining all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 information above, let’s build a module in our research platform to interact with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART instance. The module will analyse DART’s translation tables, following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hierarchy described above. By analysing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation tables, we can subsequently hold a mapping between IO-Space addresses and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding physical ranges within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s PAS. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, we can invert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tables in order to produce a PAS to IO-Space mapping. Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se two mappings we can subsequently convert IO-Space addresses to physical addresses, and vice versa.

Finally, in addition to inspecting IO-Space, our DART module also allows us to manipulate IO-Space, by introducing new mappings into IO-Space containing whichever physical address we desire.

At long last, we can test whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r our deductions regarding DART’s structure are indeed valid. First, let’s extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART instance corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip. Then, using this object, we can proceed to dump cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire mapping between IO-Space addresses and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding physical ranges by following DART’s translation hierarchy:


Great! The first few mappings appear sane -- each IO-Space address is translated into a corresponding physical range well within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s PAS. Moreover, we can see that our assumption regarding DART’s translation granule holds, as some mapped physical addresses are within a 4KB range from one anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.

To be absolutely certain that our assessment is valid, let’s perform anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r short experiment. We’ll map-in an unused IO-Space address, pointing it at a physical address corresponding to “spare” data within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s BSS. Next, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA hook we inserted previously, we’ll direct unconsumed DMA descriptors at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 newly mapped IO-Space address. By doing so, subsequent DMA transfers should arrive at our chosen BSS address.

After inserting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hook and monitoring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapped BSS range (by reading it through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS), we are presented with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following result:


Awesome! We managed to DMA into an arbitrary physical address within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s BSS, thus confirming that our understanding of DART is correct.

Exploring DART


Using our newly acquired control over IO-Space, we can proceed to conduct a few experiments.

For starters, it would be interesting to see whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel integrity mechanisms present on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7 (“KTRR”, previously referred to as “AMCC”), still hold in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of malicious DMA attempts from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip. To find out, we’ll map each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protected physical ranges (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s code segments, read-only segments, etc.) into IO-Space, insert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA hook, and observe cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir contents to see whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were successfully modified.

Unsurprisingly, each attempt to DMA into a protected region results in a fault being raised, subsequently triggering a kernel panic and crashing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. Attempting to DMA into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR’s hardware registers storing protected region ranges similarly fails -- once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lockdown occurs, no modification of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers is permitted.


Continuing our analysis of DART, let’s consider anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r edge-case scenario: assume two subsequent IO-Space mappings correspond to non-contiguous ranges of physical memory. In such a case, should DMA operations crossing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 boundary between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two IO-Space ranges be permitted? If so, should cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data be split across cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding physical ranges? Or should cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transfer instead only utilise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first physical range?

To find out, we’ll conduct anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r experiment. First, we’ll create two IO-Space mappings pointing at disparate regions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Kernel’s BSS. Then, using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA engine, we’ll initiate a transfer crossing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 boundary between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two IO-Space addresses.


Running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above experiment and monitoring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resulting addresses through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS, we are presented with a positive result -- DART correctly splits cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transaction into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two corresponding physical ranges, thus never exceeding any of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapped-in regions’ bounds.

So far, so good.

PCIe Configuration Space


Continuing our investigation of DART, we arrive at anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r query -- how does DART perform context determination? Namely, how does DART differentiate between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 components issuing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory access requests?

Depending on DART’s architecture, several solutions to this question exist. If each DART is assigned to a single component or a single PCIe bus, no identification is needed, as it can simply funnel all operations from that origin through its translation mechanism. Alternately, if several PCIe components exist on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bus to which DART is assigned, it could utilise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “Requester ID” (RID) field in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe TLP to identify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 originating component.

Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RID for context determination is not risk-free, as malicious PCIe components may attempt to “spoof” cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir TLPs. To deal with such scenarios, PCIe introduced Access Control Services (ACS), allowing PCIe switches to perform routing decisions, including disallowing transfer of certain TLPs based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir encompassed IDs. As we are not aware of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe topology on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone, it remains unknown whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r such a configuration is needed (or used).

With regards to control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe TLPs, Broadcom’s Wi-Fi chips expose much of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe Core’s functionality to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware by mapping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core’s registers through a fixed backplane address. Previous Broadcom SoC revisions, which incorporated PCIe Gen 1 cores, allowed access to several “diagnostic” registers (via pcieindaddr / pcieinddata), which govern over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical (PLP), data link (DLLP) and transport (TLP) layers of PCIe. Regardless, it is unknown whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 this mechanism allows modification of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RID, or indeed whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r this form of access is still present in current-gen Broadcom hardware.

Nevercá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, standardised PCIe mechanisms exist which may also affect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RID’s composition. For instance, PCIe 3.0 introduced Alternate Routing-ID Interpretation (ARI), which modifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 encoding of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 RID, eliminating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “device” field while expanding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “function” field to 8 bits.


While normally cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe Configuration Space is accessed through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, Broadcom’s Wi-Fi SoC exposes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration space within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi SoC, through a pair of backplane registers corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe Core (configaddr / configdata). Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se registers, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware can not only read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe Configuration Space, but also modify values within it. Like many advanced PCIe features, ARI is exposed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration space through an “extended capability” blob; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365refore, if ARI is supported by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe core, we could utilise our access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration space to enable cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 feature from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware.

To determine whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r such capabilities are present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe core, we’ll produce a dump of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration space (using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned register pair). After doing so, we can simply reorganise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents in a format legible to lspci, and instruct it to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given data, producing a human-readable representation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 features supported by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe core:


Scanning through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above capabilities, it appears that none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “advanced” PCIe features (such as ARI) are supported by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe core.

Exploring IO-Space


While we’ve already determined how DART facilitates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapping for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, we have yet to investigate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory exposed through this mechanism. In order to investigate IO-Space’s contents, we’ll use a two-stage translation process; first, we’ll use our DART module to produce a mapping between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space addresses and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding physical ranges. Once we obtain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapped physical ranges, all that remains is to map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se ranges into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS, allowing us to subsequently dump cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir contents using our research platform.

As we know, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping from virtual to physical addresses is governed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU’s translation tables. On ARMv8-A platforms (such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARM Virtual Memory System Architecture (VMSA) specifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 format of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation tables utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARM MMU. Like any XNU task, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s translation tables are accessible through its task_t structure (exported through its data segment). Following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entries in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 task structure, we arrive at its pmap, holding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation tables.

Putting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, we can write some code in our research framework to locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s task, extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 internal translation tables, and encapsulate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rein in a module representing an ARMv8 translation table.

Using our new module, we can now perform translations between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual addresses in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS and physical ones. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, we can invert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation table, producing a (one-to-many) mapping from physical to virtual addresses. In tandem with our DART module, this allows us to take each IO-Space address, convert it to a physical address, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n use our inverted translation table to convert it back to a virtual address in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS.

Consequently, we can now iterate over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire IO-Space exposed to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, extracting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of every mapped region:



After producing a copy of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire contents of IO-Space, we can now comb through it, searching for any “accidental” mappings that might be beneficial for a would-be attacker present on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip.

For starters, recall that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel protects itself against remote attackers by utilising KASLR. This mitigation introduces a randomised “slide” value, which is added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s base loading address (both virtual and physical). Since many exploits rely on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to pre-calculate addresses within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS, such a mitigation may slow down attackers, or hinder cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reliability of exploits targeting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel.

However, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same “slide” value is applied globally, it is often cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 case that a single “leaked” kernel VAS address results in a KASLR bypass (allowing attackers to deduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 slide’s value). Therefore, if any kernel virtual address is accidentally leaked in an IO-Space mapped page, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip may be able to similarly subvert KASLR.

Apart from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 potential implications regarding KASLR, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of any kernel VAS pointer in IO-Space would be worrisome, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 pointer might be utilised by kernel code. Allowing a malicious Wi-Fi chip to corrupt its value may subsequently affect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s behaviour (perhaps even resulting in code execution).

To find out whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r any kernel pointers are exposed through IO-Space, let’s scan through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 extracted IO-Space pages, searching for 64-bit words corresponding to addresses within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS. After going through every single page, we are greeted with a negative result; we can find no kernel VAS pointers in any IO-Space mapped page!

With a cursory investigation of IO-Space out of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way, we can now dig deeper, attempting to gain a better understanding of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-mapped contents. To this end, we’ll combine several approaches:
  1. Inspect each page’s contents to look for hints regarding its role
  2. Locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel code responsible for interacting with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same IO-Space range
  3. Check cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space address against posted addresses in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware
  4. Use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android driver as reference for any “strange” unidentified constructs

After performing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above steps, we are finally able to piece togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r a complete mapping of IO-Space (thus also concluding that no “accidental” mappings are present). It is important to note that since IO-Space is not subject to randomisation, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO addresses are constant, and are not affected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KASLR slide.

Searching For Vulnerabilities


Having explored cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aspects relating to DART, IO-Space mappings, and low-level components, let’s proceed to inspect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 more traditional attack surfaces exposed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

Recall that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host communicate with one anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r through a series of “rings”, mapped into IO-Space. Each ring facilitates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transfer of information in a single direction; eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host (D2H), or vice versa (H2D).

Among cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages transferred through message rings, “Control Messages” represent a racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r abundant attack surface. These message are used to instruct cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware to perform complex state-changing operations, such as creating additional message rings, deleting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, and even transporting high-level requests (ioctls) to be processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware.

Due to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir complexity, control messages rely on a bidirectional communication channel; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “Control Submit” ring (H2D) allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to submit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requests to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “Control Complete” ring (D2H) is used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device to return cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

After committing messages to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 D2H rings, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware signals cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host by writing to a “MailBox” register and triggering an MSI interrupt. This interrupt is subsequently handled by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, which inspects cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MailBox register, and notifies cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding (D2H) rings that data may be available for processing.



Tracing through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above flow, we reach cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 handler function for processing incoming control messages within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. To assist in reverse-engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se messages, we’ll utilise Broadcom’s Android driver (bcmdhd), which contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 definitions for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 control structures, as well as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message codes corresponding to each request.

AppleBCMWLANBusPCIeInterface::drainControlCompleteRing

The encapsulating handler simply reads cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “message type” field, and proceeds to delegate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message’s processing to a dedicated handler -- one per message type. Going over each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 handlers, we stumble across a memory corruption bug triggerable by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware. Incidentally, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug was present in a handler for a message type which isn’t available in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android driver.

Moving on, let’s set our sights on slightly higher targets in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 protocol stack. Recall that control rings are also used to carry high-level control requests from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, dubbed “ioctls”. Each ioctl allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r set a firmware-specific configuration value, or to retrieve its current value. As this channel is quite versatile, much of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 high-level interaction between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware is enacted through this channel, including retrieving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current channel, setting network configurations, and more.

However, like any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r signal originating from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device, it is important to remember that “ioctls” can be co-opted by malicious Wi-Fi firmware. After all, an attacker controlling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware can simply hook cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “ioctl” handling function, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby allowing full control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents transmitted back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host.

Reverse-engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 high-level driver, AppleBCMWLANCore, we quickly identify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entry point responsible for issuing ioctl requests from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware. Cross referencing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function, we find nearly 500 call sites, several of which act as wrappers for common functionality, thus revealing even more originating call sites. After going over each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned sites, we discover several memory corruptions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding handlers.

Lastly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s one more communication channel to consider -- Broadcom allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 in-band transmission of “event packets” from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. These frames, denoted by a unique Ecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rType (0x886C), carry unsolicited events from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, requiring special handling by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Tracing through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s RX path brings us to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entry point for handling such frames:


AppleBCMWLANCore::handleEventPacket

Once again, going over each handler in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above function (while using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android driver to assist our understanding of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding event codes and data structures), we discover two more vulnerabilities.

Better Vulnerabilities

Data Races?


While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerabilities we just discovered allow us to trigger several forms of memory corruptions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host (OOB writes, heap overflows), and even to leak constrained data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, reliably exploiting any of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m remains racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r challenging.

For starters, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip has no visibility into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s memory (apart from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapped regions), and relatively little control over objects allocated within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel. Therefore, grooming cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s memory in order to successfully launch a heap memory corruption attack would require significant effort. What’s more, this challenge is compounded by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 presence of KASLR, preventing us from accurately locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s data structures (barring any information disclosure).

Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, perhaps we can identify better primitives by digging deeper!

So far, we’ve only considered cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data transferred between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware. Effectively, we were thinking of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host as two distinct entities, communicating with one anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r through an isolated communication channel. In fact, nothing can be furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 truth -- cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two endpoints share a PCIe interface, allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware to perform DMA accesses at will to any IO-Space address.

One of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 major risks when using a shared memory interface is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 matter of timing. While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and firmware normally synchronise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir operations to ensure that no data races occur, attackers controlling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi firmware are bound by no such agreement. Using our control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, we can intentionally modify data structures within IO-Space as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are being accessed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Doing so might allow us to introduce race conditions, such as TOCTTOUs, creating vulnerable conditions in ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise safe code (under normal assumptions).

The first target for such modification are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 control messages we inspected earlier on. Inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 control ring handler in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, it appears that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages are read directly from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapped buffer, raising cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 possibility for data races in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir processing. Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, going over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 relevant code paths, we find no security-relevant races.

What about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second control channel we reviewed -- event packets? Perhaps we could modify a packet’s contents while it is being processed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby affecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s behaviour? Once again, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 answer is negative; each transferred packet is first copied from its IO-Space mapped buffer to a kernel-resident mbuf before subsequently passing it on for processing, thus eliminating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 possibility of firmware-induced races.

Message Rings, Revisited


So far, we’ve inspected cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 high-level functionality provided by message rings, namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 control messages transported cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rein. However, we’ve neglected several aspects of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir operation. One implementation detail of particular note is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method through which rings allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 endpoints to synchronise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir accesses to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring.

To allow concurrent accesses by both cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s consumer and its corresponding producer, each ring is assigned a pair of indices: a read index specifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location up to which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 consumer has read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages, and a write index specifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next message will be submitted by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 producer. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir name implies, each ring forms a circular buffer -- upon arriving at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 last ring index, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices simply wrap around, returning back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s base.


Since both endpoints must be aware of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices to successfully coordinate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir access, a mechanism must exist through which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices may be shared between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two. In Apple’s case, this is achieved by mapping all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices into IO-Space mapped buffers.


While mapping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices into IO-Space is a convenient way to share cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir values, it is not risk-free. For starters, if all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above indices are mapped into IO-Space, a malicious Wi-Fi chip may not only utilise DMA access to read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, but may also be able to modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

This form of access is excessive -- after all, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device need only update cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read indices for H2D rings, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 write indices for D2H rings. The remaining indices should, at most, be read by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. However, as DART’s implementation is proprietary, it is unknown whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it can facilitate read-only mappings. Consequently, all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above indices are mapped into IO-Space as both readable and writable, thus allowing a malicious Wi-Fi chip to freely alter cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir values.

This IO-Space-based index sharing mechanism raises an important question; what if a Wi-Fi chip were to maliciously modify a ring’s indices while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring is being processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host? Would doing so introduce a race condition? To find out, let’s take a look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function through which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host submits messages into H2D rings:

1.  void* AppleBCMWLANPCIeSubmissionRing::workloopSubmitTx(uint32_t* p_read_index,
2.                                                         uint32_t* p_write_index) {
3.
4.      //Getting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 write index from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapped buffer (!)
5.      uint32_t write_index = *(this->write_index_ptr);
6.      
7.      //Iterating until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no more events to process
8.      while (this->getRemainingEvents(p_read_index, p_write_index)) {
9.
10.         //Calculate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next insertion address based on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 write index
11.         void* ring_addr = this->ring_base + this->item_size * write_index;
12.         uint32_t max_events = this->calculateRemainingWriteSpace();
13.
14          //Writing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current events to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring
15.         uint32_t num_written = this->submit_func(..., ring_addr, max_events);
16.         if (!num_written)
17.             break; //No more events to process
18.
19.         //Update cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 write index
20.         write_index += num_written;
21.         if (write_index >= this->max_index) {
22.             write_index = 0; //Wrap around
23.
24.         //Commit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new index to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapped buffer (!)
25.         *(this->write_index_ptr) = write_index;
26.     }
27.     ...
28. }
29.
30. class AppleBCMWLANPCIeSubmissionRing {
31.     ...
32.     uint32    max_index;          //The maximal ring index               (off 88)
33.     uint32    item_size;          //The size of each item                (off 92)
33.     uint32_t* read_index_ptr;     //IO-Space mapped read index pointer   (off 174)
34.     uint32_t* write_index_ptr;    //IO-Space mapped write index pointer  (off 184)
35.     void*     ring_base;          //IO-Space mapped ring base address    (off 248)
36. }
function 0xFFFFFFF006D36D04

Alright! Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above function immediately raises some red flags…

The function appears to read values from IO-Space mapped buffers in several different locations, seemingly making no effort to coordinate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 read values. This kind of pattern opens cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 door to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 possibility of race conditions induced by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware.

Let’s focus on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “write index” utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function. At first, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 index is fetched by reading its value directly from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mapped buffer (line 5). This same value is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n used to derive cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location to which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next ring item will be written (line 11). Crucially, however, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value is not used in any shape or form by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 surrounding verifications utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function to decide whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current ring indices are valid (lines 8, 12).

Therefore, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 verification methods must re-fetch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices’ values, introducing a possible discrepancy between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value used during verification, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one used to place cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next item.

To exploit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above issue, an attacker controlling cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip can DMA into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices in order to introduce one value for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring address calculation (line 5), while quickly switching cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 index to a different, valid value, for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining validations (lines 8, 12). If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above race is executed successfully, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following H2D item will be submitted by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host at an arbitrary attacker-controller offset from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s base, triggering an out-of-bounds write!

Removing The Race Condition


While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above primitive is no doubt useful, it has one inherent downside -- performing a data race from an external vantage point may be a difficult feat, especially considering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 platform we’re executing on (an ARM Cortex R) is significantly slower than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 targeted one (a full-blown application processor).

Perhaps by gaining a better understanding of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive, we can deal with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se limitations. To this end, let’s take a closer look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 validation performed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 submission function:

1.  uint32_t AppleBCMWLANPCIeSubmissionRing::calculateRemainingWriteSpace() {
2.
3.      uint32_t read_index, write_index;
4.      this->getIndices(&read_index, &write_index);
5.
6.      //Did cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring wrap around?
7.      if (read_index > write_index)
8.          return read_index - (write_index + 1);
9.      else
10.         return this->max_index - write_index + (read_index ? 0 : -1);
11. }
12.
13. void AppleBCMWLANPCIeSubmissionRing::getIndices(uint32_t* rindex,
14.                                                 uint32_t* windex) {
15.     uint32_t read_index = *(this->read_index_ptr);
16.     uint32_t write_index = *(this->write_index_ptr);
17.     if (read_index >= 0x10000 || write_index >= 0x10000)
18.         panic(...);
19.     *rindex = read_index;
20.     *windex = write_index;
21. }
Ah-ha! Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code above, we can identify yet anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r fault.

When fetching cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 getIndices function attempts to validate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir values to ensure that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y do not exceed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allowed ranges. This is undoubtedly a good idea, as it prevents corrupted values from being utilised (which may result in memory corruption).

However, instead of comparing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 indices against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current ring’s capacity, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are compared against a fixed maximal value: 0x10000. While this value is certainly an upper bound on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rings’ capacities, it is far from a tight bound (in fact, most rings only hold several hundred items at-most).

Therefore, observing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code above we reach two immediate conclusions. First, if we were to attempt a race condition whereby cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring index is modified to a value larger than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fixed bound (0x10000), we run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 risk of triggering a kernel panic should cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 race attempt fail (line 18). More importantly, however, modifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 write index to any value below cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fixed bound (but still above cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 actual ring’s bounds), will allow us to pass cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 validations above, resulting in an out-of-bounds write with no race-condition required.

Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above primitive, we can target any H2D ring, causing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next element to be reliably inserted at an out-of-bounds address within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS! While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 affected range is limited to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s item size multiplied by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned fixed bound, as we’ll see later on, that’s more than enough.

Triggering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Primitive


Before pressing on, it’s important that we prove that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 scenario above is indeed feasible. After all, many components within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel might utilise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 modified ring indices, which, in turn, may enforce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir own validations.

To do so, we’ll perform a short experiment using our research platform. First, we’ll select an H2D ring, and fetch its corresponding object within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel. Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned object, we can cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s base address, allowing us to inspect its contents. Now, we’ll modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices by utilising cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s DMA engine, while concurrently monitoring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel virtual address at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 targeted offset for modification. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive is triggered successfully, we should expect an item to be inserted at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target offset from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s base address.

However, running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above experiment results in a resounding failure! Every attempt to trigger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 out-of-bounds write results in a kernel panic, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby crashing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. Inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 panic logs reveals cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source of this crash:


It appears that when executing our attack, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware attempts to perform a DMA read operation from an address beyond its IO-Space mapped ranges! Taking a moment to reflect on this, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 error is immediately apparent: since both cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host share cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices through IO-Space, modifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned values affects not only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, but also cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s implementation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MSGBUF protocol.

Namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware attempts to read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s contents using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corrupted indices, resulting in an out-of-bounds access to IO-Space, triggering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above panic.

As we have control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, we could simply try to intercept cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding code paths in its MSGBUF implementation, thus preventing it from issuing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 malformed DMA request. Unfortunately, this approach is easier said than done - cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware’s implementation of MSGBUF is woven into many code-paths in both cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ROM and RAM; attempting to patch-out each part results in eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r breakage of a different component, or in undesired side-effects.

Instead of addressing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sources of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA transfers, we’ll go straight to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 target -- cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 engine itself. Recall that each DMA engine on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware is accessible through an instance of a single structure (dma_info). Changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA engine’s backplane register pointers within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dma_info structure would mean that while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 calling code-paths are able to continue issuing malformed DMA requests, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 requests cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves are never actually received by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DMA engine, thus preventing us from triggering a fault.


Indeed, incorporating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above patch into our vulnerability trigger, we can now freely modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring indices without inducing a crash. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding kernel virtual at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 targeted index, we can see that our overwrite is finally successful!

Devising An Exploit Plan


Having concluded that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive is usable, we can now proceed to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next stage -- devising an exploit plan. Namely, we must decide on a data structure to target using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit primitive, which may allow us to eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s behaviour, or ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rwise gain a useful primitive bringing us closer to that goal.

So which data structure should we target? As we do not have any visibility into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s address space, reliably locating structures within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel presents quite a challenge. What’s more, our primitive only allows limited control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 written content (namely, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data written by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host is an H2D ring item). On top of that, each OOB element can only be written at offsets which are multiples of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring’s item size, thus introducing alignment constraints.

The above limitations make reliable exploitation racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r difficult. Alas, if only cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re were a data structure whose internal composition were relatively flexible, and to which a single modification would grant us complete control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host…

...But of course, we’ve already come across cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 perfect target -- DART’s translation tables!

Recall that DART’s translation tables govern over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping between IO-Space and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical address space. If we were able to use our primitive in order to modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tables, we might be able to introduce new mappings into IO-Space, pointing at arbitrary physical ranges within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s PAS. Mapping in arbitrary physical memory into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip is a nearly ideal primitive, as it would allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip to modify any data structure used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, leading to trivial code execution.

In order to successfully carry out such an attack, we must first figure out whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r DART’s translation tables indeed constitute valid targets for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vulnerability primitive. Namely, we must figure out whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y reside within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive’s scope of influence.

However, scanning through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory ranges within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive’s scope, we quickly come to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 realisation that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 placement of objects following cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message rings is highly variable. Indeed, each device reboot yield an entirely different layout, thus preventing us from relying on any particular object being placed at any given offset from a message ring.

Perhaps we’re out of luck…?

Shaping IO-Space


...Instead of relying of lucky placement of nearby objects, let’s take matters into our own hands.

In order to place a DART translation table within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive’s scope, we’d need to eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r move a translation table into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive’s scope, or to move one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message rings, thus shifting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 primitive’s scope across different regions of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s memory.

The former approach seems infeasible; DART’s translation tables are only allocated when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space mappings are first populated (namely, when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip is first initialised). Once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping is complete, all of DART’s translation tables remain in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir fixed positions within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS.

But what about moving cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rings? While control rings are immovable, a second set of ring exists -- “flow rings”. Flow rings are H2D rings used to facilitate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transfer of outgoing (TX) traffic. They do not carry cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 traffic itself, but racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r notify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transmitted frame’s metadata (including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space address at which its actual content is stored).

Unlike control rings, flow rings are far more “flexible”. Individual flows are dynamically added and removed as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 need arises, by sending a corresponding control message from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device. Each flow is identified by its endpoints (source and destination MAC), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir encompassed protocol (i.e., Ecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rType), and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir “priority”.

Perhaps we can use this dynamic nature of flow rings to our advantage. For example, if we were to delete a flow ring, it might subsequently get re-allocated at a different location in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s memory, thus shifting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 scope of our OOB primitive to a possibly more “interesting” patch of objects.

Normally, deleting a flow ring is a two way process; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host sends a deletion request, which is subsequently met by a corresponding message from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device, signalling a successful deletion. However, inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s implementation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above messages, it appears we can just as well skip cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exchange, and send an unsolicited deletion response from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device:

1.  uint32_t AppleBCMWLANBusPCIeInterface::completeFlowRingDeleteResponseMsg(
2.                uint64_t unused, struct tx_flowring_delete_response_t* msg) {
3.   
4.      //Is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring ID within bounds?
5.      if (msg->flow_ring_id < this->min_flow ||
6.          msg->flow_ring_id >= this->max_flow) {
7.          ...
8.      }
9.      //Does a flow ring exist at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 given index?
10.     else if (this->flow_rings[msg->flow_ring_id]) {
11.         this->deleteFlowCallback(msg->status, msg->flow_ring_id);
12.         ...
13.         return 0;
14.     }
15.     else {
16.         ...
17.         return 0xE00002BC;
18.     }
19. }
function 0xFFFFFFF006D2FD44

Doing so causes an interesting side-effect to occur: instead of completely deleting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host decrements a single reference count on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ring object, which is insufficient to bring down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 total count to zero (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 missing release was meant to be performed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code responsible for sending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 deletion request in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first place).

Consequently, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 flow ring is left mapped into IO-Space, but is unusable by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. As such, newly allocated flow rings cannot inhabit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same IO-Space range (as it remains occupied by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unusable ring), and must instead be carved from higher IO-Space addresses.

This primitive has several interesting side-effects.

For starters, it allows us to re-allocate flow rings, thus moving around cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir base addresses within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS, recasting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 net over potentially interesting objects within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel.

More importantly, however, this primitive allows us to force cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 allocation of a brand new DART L2 translation table. Since each L2 translation table can only map a fixed range into IO-Space, by continuously leaking flow rings we are able to exhaust cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 available space in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L2 table, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby forcing DART to allocate a new table from which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next IO-Space addresses are carved.

Lastly, as luck would have it, since both cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rings cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365mselves and DART’s translation tables are carved using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same allocator (IOMalloc), and have similar sizes, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are both carved from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same “zone” of memory. Therefore, by continuously leaking IO-Space addresses and creating new flow rings until a new DART L2 translation table is formed, we can guarantee that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new table will be placed in close proximity to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following flow ring, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby placing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L2 translation table within our primitive’s scope!


Putting it all togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, we can finally reach a reliable placement of DART translation tables in close proximity to a flow ring, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby allowing us to overwrite entries in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation tables with flow ring items.

Flow Ring Items vs. DART Descriptors


To understand whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r flow ring items make good candidates to overwrite DART descriptors, let’s take a moment to inspect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir structure. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se items are present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same form in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Android driver, we are spared cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 need to reverse-engineer cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m:

So how does cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above structure relate to a DART descriptor?

As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above structure has a 64-bit aligned size, and ring items are always placed in increments of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same size, we can deduce that each quadword in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above structure will reside in a 64-bit aligned address. Similarly, DART descriptors are 64-bits wide, and are placed in 64-bit aligned addresses. Therefore, each aligned quadword in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above structure serves as a potential candidate for replacing a DART descriptor.

However, going over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above quadwords, it is quickly apparent that no fully-controlled word exists within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 structure. Indeed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first and last word are composed of mostly constant values, whereas cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 third and fourth contain IO-Space addresses (whose forms are incompatible with DART descriptors). Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, taking a closer look, it appears that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second word is at least somewhat malleable. Its lower six bytes are governed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination MAC address to which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 frame is being transmitted, while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two upper bytes contain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 beginning of our source MAC.

Assuming we could cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to send frames to a MAC address of our choosing, that would grant us control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower six bytes. However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 remaining two bytes are populated using our device’s MAC address, a much harder target for modification...

Spoofing The Source MAC?


To understand whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r we can indeed modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device’s MAC address, let’s take a closer look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mechanisms through which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address may be programmable on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip.

Like many production devices, Broadcom’s Wi-Fi chips allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 storage of chip-specific configuration using one of two mechanisms; eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r by using a block of Serial Programmable ROM (SPROM) or by utilising a set of One Time Programmable (OTP) fuses. The Wi-Fi chip present on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7 uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latter mechanism.

As for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, it stores cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip’s MAC address in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “device tree” (among many ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r device-specific properties). The “device tree” is a simple hierarchical representation of hardware components utilised by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 platform (much like its Linux counterpart, bearing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same name), allowing consumers within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel to easily access (and populate) its nodes.

During cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip’s initialisation, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AppleBCMWLANCore driver retrieves cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip’s OTP fuses (using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCIe BARs), and proceeds to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m according to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PCMCIA Card Information Structure (CIS) format. Reverse-engineering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parsing functions in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, it is quickly apparent that one tag in particular bears significance with regards to our pursuits.

If a “Function Extension” tag is encountered in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CIS data embedded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OTP, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel will extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address encapsulated within it, and insert it into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “local-mac-address” node in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree, representing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi MAC address!


Extracting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 stored OTP contents from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, we can see that no such element is present in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OTP contents to begin with, thus allowing us to insert our own tag without fear of causing a collision:

Wi-Fi Chip OTP

Therefore, to change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address, all we’d need to do is fuse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding bits into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OTP, thus inserting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 new CIS tag. However, this is easier said than done. For starters, writing to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OTP is a risky operation, and may result in permanent damage to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip if done incorrectly. Moreover, as it’s name implies, writing to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OTP is a one-time operation, leaving no room for error. Perhaps we could avoid changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC after all?

After discussing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above situation, my colleague Ian Beer suggested an alternative!

Why not, instead, check if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 high-order bits in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART descriptor are actually being used for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation process? To test this suggestion, we’ll use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 research platform to insert a valid L2 descriptor into DART, with one small caveat -- we’ll change cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two upper bytes in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 64-bit descriptor to “corrupted” values. After inserting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mapping, we can simply insert a DMA hook into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, performing a DMA access to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned address.


Running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 experiment above we are greeted with a positive result! Indeed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 upper bytes of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART descriptor are ignored by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation process, thus sparing us cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 need to modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC.

Spoofing The Destination MAC


Having confirmed that modifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source MAC is no longer a barrier, all that remains is to cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to send a frame to a crafted MAC address, thus allowing us to control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 six significant bytes within our 64-bit word.

Naturally, one way to solicit a response from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host is to transmit an ICMP Echo Request (ping) to it, subsequently triggering a corresponding ICMP Echo Response to be sent in response. While this approach can easily trigger cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 transmission of frames from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, it only allows frames to be transmitted to known destinations, but does not offer control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 destination MAC.

To trigger communications to our target MAC, we’ll first launch an ARP Spoofing attack; sending a crafted ping from an arbitrary (unused) IP address, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365reby causing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to send an “ARP Request” querying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 crafted IP, to which we’ll respond a response encoding our own MAC address, thus associating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IP address with a crafted MAC value.

However, several problems arise when using this method. First, recall that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address is meant to masquerade as a valid DART L2 Descriptor. As we’ve seen in our analysis of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptor formats, every valid L2 descriptor must have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two least-significant bits set. This poses somewhat of a problem for MAC addresses, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir bottom bits bear special significance:


Setting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bottom two bits in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MAC address would indicate that it is a broadcast / multicast address. As we are sending unicast traffic (and are expecting a unicast response), it might be difficult to solicit such responses from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, any network-resident security devices might inspect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 traffic and flag it as suspicious (especially as we are executing a classical ARP spoofing attack). What’s more, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 router or access point may refuse to route unicast traffic to a broadcast MAC.

To get around cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above limitations, we’ll simply inject cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 traffic directly from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, without transmitting it over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 air. To achieve this goal, we’ve written a small assembly stub that, when executed on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware, injects cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 encapsulated frames directly into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host, as if it were transmitted over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 network.

This allows us to inject even potentially malformed traffic that would not have been routable (like unicast traffic from a broadcast MAC). Indeed, after running cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARP spoofing vector with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above mechanism, we are able to solicit responses from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to our crafted (broadcast) MAC address (XNU does not object to sending unicast traffic to broadcast MACs). Great!


Inception


Finally, all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ducks are lined up in a row -- we can solicit traffic to MAC addresses of our choosing (even broadcast MACs), without having to modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source MAC. Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, we can shape IO-Space in order to force a new DART translation table to be allocated following a flow ring within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s VAS. Therefore, we can overwrite DART descriptors with our own crafted values, thus introducing new mappings into IO-Space. However, a single question remains -- which physical address should we map into IO-Space?

After all, we still haven’t dealt with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 issue of KASLR. As cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s loading addresses, both physical and virtual, are “slid” using a randomised value, we cannot locate physical addresses within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel until we uncover cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 slide’s value. If we cannot reliably locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s base address, which physical addresses can we find?

To get around this limitation, we’ll use one more trick! While cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical address space houses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DRAM, in which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel and application memory are stored, additional regions of physically addressable content can also be found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PAS. For instance, hardware registers are mapped into fixed physical addresses, allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host to interact with peripherals on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SoC. Among cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se peripherals is DART itself!

As we’ve previously seen, DART’s translation process is initiated using four “L0 descriptors”. These descriptors are fed into DART’s hardware registers, denoting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base addresses of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 translation tables from which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 IO-Space translation process begins. If we were to map in DART’s hardware registers into IO-Space, we could eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 descriptors, thus allowing us to locate DART’s translation tables within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address space!

It should be noted that although DART’s hardware registers are addressable within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical address space, it remains unknown why IO-Space mappings should even be allowed to include ranges beyond cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DRAM’s bounds. Indeed, it stands to reason that such mappings would be prohibited by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware. However, as it happens, no such restriction is enforced - DART freely allows any physical range to be inserted into IO-Space.

Therefore, if we wish to map-in DART’s own hardware registers into IO-Space, all that remains is to locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical ranges corresponding to DART’s hardware registers! To do so, we’ll use a combined approach.

First, we’ll use our research platform to extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART instance, from which we can subsequently retrieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel VAS pointer corresponding to DART’s hardware registers. Then, using our translation table module, we can proceed to convert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel virtual address to its matching physical range. After doing so, we are presented with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following result:


Great! The address is clearly not within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DRAM’s range, hinting that we’re on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right track.

To verify whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r this is indeed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 correct address, we’ll use a second approach. As we already noted, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device hierarchy is stored within a structure called cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “device tree”. Different properties relating to each peripheral, include cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 addresses of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding hardware registers, are stored as nodes within this tree.

The device tree itself is present in a binary format within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 firmware image (encapsulated in an IMG4 container). After extracting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree, we are presented with a blob storing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device hierarchy. Although cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tree’s format is undocumented, inspecting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binary reveals an extremely simple structure; a fixed header denoting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of children and entries contained in each node, followed by a fixed-length name, and a variable-length value. I later discovered that Jonathan Levin has similarly reversed this structure, and has written a tool to parse out its contents (albeit for an IMG3 container) -- you can check out his script here.

Regardless, after writing our own python script to parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree, we are presented with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following result:


Ah-ha! We once again find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same physical address, thus concluding that our analysis of DART’s hardware registers is correct.

Putting it all togecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, we can now utilise our exploit primitive to map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address containing DART’s registers into IO-Space. Once mapped, we can proceed to read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware registers’ values, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L0 descriptors. It should be noted that attempting to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware registers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host requires strict 32-bit load and store operations -- attempting a 64-bit load from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware registers results in a garbled value being returned. Curiously, however, DMA-ing to and from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware registers from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip goes unhindered!



Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 L0 descriptor, we can now extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next translation table in DART’s hierarchy. Then, by repeating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit primitive and mapping-in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 newly discovered physical address into IO-Space, we can repeat cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process, descending down DART’s translation hierarchy until we reach a DART L2 translation table. Thus, using one flow ring, we can bring cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m all, and in IO-Space bind cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

Once an L2 translation table is located within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address space, we can proceed to map it into IO-Space using our exploit primitive one last time, thus inserting DART’s own translation table into IO-Space!

By mapping DART’s translation table into its own IO-Space ranges, we can now utilise DMA access from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip in order to freely introduce new mappings into IO-Space (removing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 need for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit primitive). Thus, gaining full control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical memory!


Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, as DART’s translation entries are never cleared, we are guaranteed that once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 malicious IO-Space entries are inserted, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y remain accessible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device itself reboots. As such, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit process need only occur once in order to introduce a backdoor allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip to freely access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical memory.

One curiosity of note is that DART’s has a racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r large TLB. Therefore, changes in IO-Space may not immediately be reflected until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entries are evicted from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 cache. Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, this is easily dealt with by mapping in IO-Space addresses in a circular pattern, thus allowing stale entries to get cleared.

Finding The KASLR Slide


At long last, we have complete control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire physical address space, directly from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip. Consequently, we can proceed to map and and modify any physical address we desire, even those corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s data structures.

While this form of access is sufficient in order to subvert cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re’s one tiny snag we have yet to deal with: KASLR. Since cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s physical base address is randomised using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KASLR slide, and we have yet to deduce its value, we might have to resort to scanning cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DRAM’s physical address ranges until we locate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel itself.

This approach is racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r inefficient. Instead, we can opt for a more elegant path. Recall that, as we’ve just seen, hardware registers may be freely mapped into IO-Space. As hardware registers are not affected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KASLR slide (indeed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are mapped at fixed physical addresses), cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y can be trivially located regardless of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current “slide” value.

Perhaps one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware registers can be used as an oracle to deduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KASLR slide?

Recall that newer devices, such as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7, enforce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 integrity of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel using a hardware mechanism dubbed “KTRR”. Simply put, this mechanism allows cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device to provide “lockdown” regions, to which subsequent modifications are prohibited. These regions are programmed using a special set of hardware registers.



Amusingly, this very same mechanism can be used to deduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KASLR slide!

By mapping in physical addresses corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned hardware registers, we can proceed to read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir contents directly from IO-Space. This, in turn, reveals cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical ranges encoded in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 “lockdown registers”, which store non ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s base address.

The Exploit


Summing up all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above, we’ve finally written an exploit, allowing full control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device’s physical memory over-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-air, using Wi-Fi communication alone. You can find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit here.

It should be noted that several smaller details have been omitted from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 blog post, in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 interest of (some) brevity. For instance, locating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offset between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 newly allocated DART translation table and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 flow ring requires a process of probing various IO-Space addresses, while also guaranteeing that alignment constraints enforced by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 granularity of ring item sizes are met. We encourage researchers to read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit’s code in order to discover any such omitted parts.

The exploit has been tested against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 7 running iOS 10.2 (14C92). The vulnerabilities are present in versions of iOS up to (and including) iOS 10.3.3. Researchers wishing to utilise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit on different iDevices or different versions, would be required to adjust cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 symbols used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit.


Upon successful execution, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit exposes APIs to read and write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host’s physical memory directly over-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-air, by mapping in any requested address to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 controlled DART L2 translation table, and issuing DMA accesses to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding mapped IO-Space addresses.

For convenience sake, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exploit also locates cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s physical base address using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method we described above (using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR read-only region registers), thus allowing researchers to easily explore cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel’s physical memory ranges.

Afterword


Over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 course of this series of blog posts, we’ve explored cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi stack on Apple devices. Consequently, we constructed a complete exploit chain, allowing attackers to reliably gain control over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS kernel on an iPhone 7 using Wi-Fi communication alone.

During our research, we explored several components, including Broadcom’s Wi-Fi firmware, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DART IOMMU, and Apple’s Wi-Fi drivers. Each of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aforementioned components is proprietary, thus requiring substantial effort to gain visibility into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir operations. We hope that by providing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tools used to conduct our research, additional exploration of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se surfaces will be performed in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 future, allowing for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir corresponding security postures to be enhanced.

We’ve also seen how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone utilises hardware security mechanisms, such as DART, in order to provide isolation between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and potentially malicious components. These mechanisms significantly raise cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bar for launching successful attacks targeting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host. Nonecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365less, additional research into DART is needed in order to explore all facets of its implementation. For instance, while we’ve explored cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 enacted IO-Space through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 prism of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, additional PCIe components exist on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SoC, which are similarly guarded by DARTs. These components remain, as of yet, unexplored.

Apart from fixing individual vulnerabilities in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 security boundaries between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip, several structural enhancements can be applied to make future exploitation harder. This includes introducing read-only mappings to DART (if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are not already present), clearing unused descriptors from DART’s translation tables upon rebooting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 associated component, and preventing IO-Space mappings from exposing physical ranges beyond cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DRAM.

Lastly, while memory isolation goes a long way towards defending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host against a rogue Wi-Fi chip, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 host must still consider all communications originating from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Wi-Fi chip as potentially malicious. To this end, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 numerous communication channels between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two endpoints (including event packets, “ioctls”, and control commands), must be designed to withstand malformed data transmitted by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 chip.