Posted past times Gal Beniamini,
In this spider web log shipping we’ll continue our journey towards over-the-air exploitation of the iPhone, past times agency of Wi-Fi communication alone. This component of the inquiry volition focus on the firmware running on Broadcom’s Wi-Fi SoC nowadays on the iPhone 7.
We’ll laid about past times performing a deep dive into the firmware itself; discovering novel assault surfaces along the way. After auditing these assault surfaces, we’ll uncover several vulnerabilities. Finally, we’ll develop a fully functional exploit against i of the aforementioned vulnerabilities, thereby gaining code execution on the iPhone 7’s Wi-Fi chip. In add-on to gaining code execution, we’ll also develop a covert backdoor, allowing us to remotely command the chip over-the-air.
Along the way, we’ll come upwards across several novel security mechanisms developed past times Broadcom. While these mechanisms bear the potential to brand exploitation harder, they remained rather ineffective inwards this particular case. By exploring the mechanisms themselves, nosotros were able to uncovering methods to bypass their intended protections. Nonetheless, nosotros stay hopeful that the issues highlighted inwards this spider web log shipping volition aid inspire stronger mitigations inwards the future.
All the vulnerabilities presented inwards this spider web log shipping (#1, #2, #3, #4, #5) were reported to Broadcom together with afterwards fixed. I’d similar to give cheers Broadcom for existence highly responsive together with for treatment the issues inwards a timely manner. While nosotros did non perform a total analysis on the breadth of these issues, a minimal analysis is available inwards the introduction to the previous spider web log post.
And now, without farther ado, let’s larn to it!
Exploring The Firmware
Combining the extracted ROM icon nosotros had precisely acquired with the resident RAM image, nosotros tin give the axe finally slice together the consummate firmware image. With that, all that remains is to charge the icon into a disassembler together with laid about exploring.
While the ROM icon on the BCM4355C0 is slightly larger than that of previously analysed Android-resident Wi-Fi chips, it’s still rather minor (spanning only 896KB). Consequently, Broadcom has in i trial once again employed the same tricks inwards gild to conserve every bit much retention every bit possible; including compiling the mass of the code using the Thumb-2 didactics laid together with stripping away most of the symbols.
As for the ROM’s layout, it follows the same basic construction every bit that of its Android counterparts; starting fourth dimension with a code chunk, followed past times a blob of constant information (including strings together with CRC polynomials), together with ending with “trampolines” into detection points inwards the Wi-Fi firmware’s RAM (and some to a greater extent than spare data).
The same cannot live said of the RAM image; spell some similarities be betwixt the electrical flow icon together with the previously analysed ones, their internal layouts are substantially different. Whereas Android-resident firmwares contained interspersed heap chunks betwixt code together with information blobs, this quirk is no longer nowadays inwards the electrical flow RAM image. Instead, the heap chunks are by together with large placed inwards a linear fashion. One exception to this dominion is the initialisation code nowadays inwards the RAM -- in i trial the firmware’s bootup procedure completes, this blob is reclaimed, together with is thereafter converted into an additional heap chunk.
Curiously, the stack is no longer located after the heap, but rather precedes it. This modification has the wages of preventing potential standardised zero-configuration service commonly used inside the Apple ecosystem).
Reverse-engineering the higher upwards fragments, nosotros come upwards to the realisation that it is a stripped-down version of mDNSResponder, by together with large responsible for performing wake on demand via mDNS (for networks that include a Bonjour Sleep Proxy). Consequently, it does non offering all the functionality provided past times a fully-fledged mDNS client. Nonetheless, embedding code from complex libraries such every bit mDNSResponder could bear undesired side effects.
For starters, mDNSResponder itself has been affected past times several security issues inwards the past. More subtly, non-security bugs inwards libraries tin give the axe become security-relevant when migrating betwixt systems whose characteristics differ so widely from i another. Concretely, on the Wi-Fi chip address null points to the firmware’s interrupt vectors -- a mapped, writable address. Being able to modify this address would allow attackers to gain code-execution on the chip, thereby converting a shape of “benign” bugs, such every bit a null-pointer accesses, to RCEs.
Offloading Mechanisms
Since the Wi-Fi SoC’s ARM core is less power-hungry than the application processor, it stands to argue that some network related functionality live relegated to the firmware, when possible. This concept is neither new, nor is it unique to the mobile settings; offloading to the NIC occurs inwards desktop environments every bit well, primarily inwards the shape of TCP offloading (via TOE) .
Regardless, spell the advantages of offloading are clear, it’s of import to live aware of the potential downsides every bit well. For starters, every bit we’ve mentioned before, the to a greater extent than features are added into the Wi-Fi firmware, the less auditable it becomes. Additionally, offloading features oft require parsing of high-level protocols. Since the Wi-Fi firmware does non contain its ain TCP/IP stack, it must resort to parsing all layers inwards the stack manually, upwards to the layer at which the offloading occurs.
Inspecting the firmware reveals at to the lowest degree 2 features which allow offloading of high-level protocols to the Wi-Fi firmware: ICMPv6 offloading together with TCP KeepAlive offloading. Apple’s host-side drivers contain controls for enabling together with disabling these offloading features (see AppleBCMWLANCore), afterwards handing over command over these packets to the Wi-Fi firmware rather than the host.
While beyond the compass of this spider web log post, auditing both of the aforementioned offloading features revealed 2 security bugs allowing attackers to either leak constrained information from the firmware or to crash the firmware running on the Wi-Fi SoC (for to a greater extent than information catch the põrnikas tracker entries linked above).
Generic Attack Surfaces
While the aforementioned assault surfaces may live interesting from an exploratory dot of view, each of the outlined features was rather constrained inwards scope. Perhaps, nosotros could uncovering a to a greater extent than fruitful assault surface inside the Wi-Fi firmware?
...This is where some familiarity with the Wi-Fi standards comes inwards handy!
Wi-Fi frames tin give the axe live split upwards into 3 distinct categories. Each frame is assigned a category past times inspecting the “type” together with “subtype” fields inwards its MAC header:
The categories are every bit follows:
- Data Frames - Carry information (and QoS data) over the Wi-Fi network.
- Control Frames - Body-less frames assisting with the delivery of other frames (using ACKs, RTS/CTS, Block ACKs together with more).
- Management Frames - Perform complex operations, including connecting to a network, modifying the dry reason of private stations (STAs), authenticating together with more.
Let’s accept a 2nd to consider the categories higher upwards from a security PoV.
While information frames contain interesting assault surfaces (such every bit frame aggregation via IEEE 802.11-2016 (9-47), total listing of activity frame categories is quite formidable:
To illustrate the amount of complexity encapsulated past times activity frames, let’s render to the iPhone’s Wi-Fi firmware. Tracing our way through the RX-path, nosotros rapidly attain the business office at which activity frames are handled inside the firmware (referred to every bit “wlc_recv_mgmtact” inwards the ROM):
wlc_recv_mgmtact - 0x1A79F4
As nosotros tin give the axe see, the business office performs some preliminary operations, before handing off processing to i of the numerous handlers inside the firmware. Each activity frame category is delegated to a unmarried handler. Counting the activity frame handlers together with corresponding frame types supported past times the iPhone’s firmware, nosotros uncovering 13 different supported categories, resulting inwards 34 different supported frame types. This is a substantial assault surface to explore!
To assess the handlers’ security, we’ll reverse-engineer each of the higher upwards functions. While this is a ho-hum together with rather tedious process, recollect that each vulnerability constitute inwards the higher upwards handlers implies a triggerable over-the-air vulnerability inwards the Wi-Fi chip.
Before attempting a manual audit, nosotros also “fuzzed” the activity frame handlers. To exercise so, nosotros developed an on-chip Wi-Fi fuzzer, allowing injection of frames straight into the aforementioned handler functions (without transmitting the frames over-the-air). While the fuzzer allowed for high-speed injection of frames (namely, thousands of frames per second), running it using a minor corpus of activity frames together with inducing bit-flips inwards them was unfruitful... One possible explanation for this approach’s failure is due to the strict construction mandated past times many activity frames. Perhaps these results could live improved past times fuzzing based on a grammer derived from the Wi-Fi standard, or enforcing construction constraints on the fuzzed content.
Regardless, nosotros tin give the axe employ some tricks to speed upwards our manual exploration. Recall that Wi-Fi primarily relies on Information Elements (IEs), tagged bundles of data, to convey information. The same regulation applies to activity frames -- their payloads typically consist of multiple IEs, each encapsulating different pieces of information relating to the handled frame. As the IE tags are (mostly) unique inside the Wi-Fi standard, nosotros tin give the axe only lookup the tag value corresponding to each processed IE, allowing us to rapidly familiarise ourselves with the surrounding code.
After going through the handlers outlined above, nosotros identified a number of vulnerabilities.
First, nosotros discovered a vulnerability inwards 802.11v Wireless Network Managements (WNM). WNM is a laid of standards allowing clients to configure themselves inside a wireless network together with to telephone commutation information almost the network’s topology. Within the WNM category, the “WNM Sleep Mode Response” frame serves to update the Group Temporal Key (GTK) when the laid of peers inwards the network changes. As it happens, reverse-engineering the WNM handler revealed that the corresponding business office failed to verify the length of the encapsulated GTK, thereby triggering a controlled heap overflow (see the bug tracker for to a greater extent than information).
By cross-referencing the GTK treatment method, nosotros were able to seat a similar vulnerability inwards 802.11r Fast BSS Transition (FBT). Once again, the firmware failed to verify the GTK’s length, resulting inwards a heap overflow.
While both of the higher upwards vulnerabilities are interesting inwards their ain right, nosotros volition non speak over them whatever farther inwards this spider web log post. Instead, we’ll focus on a different vulnerability altogether; i with a weaker primitive. By demonstrating how fifty-fifty relatively “weak” primitives tin give the axe live exploited on the Wi-Fi firmware, we’ll showcase the demand for stronger exploit mitigations.
To brand matters to a greater extent than interesting, we’ll create our entire exploit using nothing but activity frames. These frames are so feature-rich, that past times leveraging them nosotros volition live able to perform heap shaping, create resources allotment primitives, together with of course, trigger the vulnerability itself.
802.11k Radio Resource Management
802.11k is an amendment to the Wi-Fi criterion aiming to convey Radio Resource Management (RRM) capabilities to Wi-Fi networks. RRM-capable stations inwards the network are able to perform radio measurements (and have them), allowing access points to trim down the congestion together with improve traffic utilisation inwards the network. The concept itself is non novel inwards the mobile sphere; inwards fact, it’s been to a greater extent than or less inwards cellular networks for over 2 centuries.
Within the Wi-Fi ecosystem, RRM is commonly utilised inwards tandem with 802.11r FBT (or the proprietary CCKM) to enable seamless access dot assisted roaming. As stations create upwards one's heed to “handover” to different access points (based on their radio measurements), they tin give the axe consult the access points inside the network inwards gild to obtain a listing of potential neighbours with which they may reassociate.
To implement all of the above, a laid of activity frames (and a novel activity category) have got been added to the Wi-Fi standard. Consequently, clients tin give the axe perform radio together with link measuring requests, have the corresponding reports, together with fifty-fifty procedure reports containing their neighbouring access points (should they create upwards one's heed to roam).
All of the higher upwards functionality is also nowadays inwards the Wi-Fi firmware on the iPhone:
Auditing the handlers above, nosotros come upwards across i business office of particular note; the handler for Neighbor Report Response frames.
The Vulnerability
Neighbor Report Response (NRREP) frames are reports delivered from the access dot to stations inwards the network, informing stations of neighbouring access points inwards their vicinity. Upon roaming, the stations may usage these parameters to reassociate with the aforementioned neighbours. Providing this information spares the stations the demand to perform extensive scans on their ain -- a rather fourth dimension consuming operation. Instead, they may only rely on the report, informing it of the specific channels together with operating classes inhabited past times each neighbour.
Like many activity frames, NRREPs also contain a “dialog token” (9.6.7.7). This 1-byte acre is used to correlate betwixt requests issued past times a client, together with their corresponding responses. As their call implies, Neighbour Report Responses are typically transmitted inwards reply to a corresponding asking made past times the customer before on (commonly every bit a final result of a radio measuring indicating that a roam may live imminent). As we’d expect, upon sending a Neighbor Report Request, the customer generates together with embeds a dialog token, which inwards later verified past times it when processing the corresponding NRREP returned past times the access point.
However, reading to a greater extent than carefully through the specification reveals some other interesting scenario! It appears that NRREPs may also live solely unsolicited. In such a case, the dialog token is only laid to zero, indicating that no matching asking exists.
IEEE 802.11-2016, 9.6.7.7
Consequently, NRREPs may live transmitted over the network to whatever customer at whatever time, so long every bit it supports 802.11k RRM. Upon reception of such a study (with a zeroed dialog token), the customer volition only parse the asking together with take away hold the information therein.
Continuing to read through the standard, nosotros tin give the axe slice together the frame’s overall structure; starting from the activity frame header, all the way the encapsulated IE:
As nosotros tin give the axe catch above, the mass of the information inwards the NRREP frame is conveyed through the “Neighbour Report” IE. NRREPs may contain i or to a greater extent than such IEs, each indicating the presence of a unmarried neighbour.
Now that nosotros have got a theatre agreement of the frame’s structure, let’s accept a seem at the firmware’s implementation of the functionality described above. Following along from the initial NRREP handler, nosotros rapidly come upwards to a ROM business office responsible for treatment the reports. Reverse-engineering the function, nosotros brand it at the next high-level logic:
1. int wlc_rrm_recv_nrrep(void* ctx, ..., uint8_t* body, uint32_t bodylen) {
2.
3. //Ensuring the asking is valid
3. if (bodylen <= 2 || !g_rrm_enabled || body[2] != stored_dialog_token)
4. ... //Handle error
5.
6. //Freeing all the previously stored reports
7. free_previous_nrreps(ctx, ...);
8.
9. //Stripping the activity Header
10 uint8_t* report_ie = body + 3;
11. bodylen -= 3;
12.
13. //Searching for the study IE
14. do {
15. ... //Verify the IE is valid
16. if (report_ie[0] == 52 && report_ie[1] > 0xC) //Tag, Length
17. break; //Found a matching IE!
18. } spell (report_ie = bcm_next_tlv(report_ie, &bodylen));
19. if (!report_ie)
20. ... //Handle error
21.
22. //Handle the report
23. uint8_t* nrrep_data = malloc(28);
24. if (!nrrep_data)
25. ... //Handle error
26.
27. memcpy(nrrep_data + 6, report_ie + 2, 6); //Copying the BSSID
28. ... //Copying other elements...
29. nrrep_data[16] = report_ie[12]; //Operational Class
30. nrrep_data[17] = report_ie[13]; //Channel Number
31.
32. //Processing the report
33. void* elem = wlc_rrm_regclass_neighbor_count(ctx, nrrep_data, ...);
34. ...
35. }
As nosotros tin give the axe catch above, the business office begins past times performing some cursory validation of the received request. Namely, it ensures that RRM is enabled inside the network, that the study is sufficiently long, together with that the received dialog token matches the stored i (if a solicited asking was initiated past times the client, otherwise the stored token is laid to zero).
After performing the necessary validations together with locating the study IE, the business office proceeds to extract the encoded study information together with shop it inside a construction of its own. Finally, the newly created construction is passed on for processing inside wlc_rrm_regclass_neighbor_count. Let’s accept a closer look:
1. void* wlc_rrm_regclass_neighbor_count(void* ctx, uint8_t* nrrep_data, ...) {
2.
3. //Searching for previous stored elements with the same Operational
4. //Class together with Channel Number
5. if (find_nrrep_buffer_and_inc_channel_idx(ctx, nrrep_data, ...))
6. return NULL;
7.
8. //Creating a novel chemical constituent to agree the NRREP data
9. uint8_t* elem = zalloc(456);
10. if (!elem)
11. ... //Handle error
12. elem[4] = nrrep_data[16]; //Operational Class
13. ((uint16_t*)(elem + 6))[nrrep_data[17]]++; //Channel Number
14.
15. //Adding the chemical constituent to the linked listing of stored NRREPs
16. *((uint8_t**)elem) = ctx->previous_elem;
17. ctx->previous_elem = elem;
18. return elem;
19. }
As shown inwards the snippet above, the firmware keeps a linked listing of buffers, i per “Operational Class”. Each buffer is 456 bytes long, together with contains the operational class, an array belongings the number of neighbours per channel, together with a pointer to the next buffer inwards the list.
While non shown above, find_nrrep_buffer_and_inc_channel_idx performs a similar chore - it goes over each chemical constituent inwards the list, looking for an entry matching the electrical flow operational class. Upon finding a matching element, it increments the vecino count at the index corresponding to the given channel number, together with returns 1, indicating success.
So why are these handlers interesting? Consider that valid 802.11 channel numbers attain from 1-14 inwards the 2.4GHz spectrum, all the way upwards to 196 inwards the 5GHz spectrum. Since each vecino count acre inwards the array higher upwards is 16-bits wide, nosotros tin give the axe deduce that the vecino count array tin give the axe live used to reference channel numbers upwards to 224 ((456 - 6)/sizeof(uint16_t) == 224).
However, looking a lilliputian closer it appears that the functions higher upwards make no attempt to validate the Channel Number field! Therefore, malicious attackers tin give the axe encode whatever value they want inwards that acre (up to 255). Encoding a value larger than 224 volition so trigger a 16-bit increase to live performed out-of-bounds (see line 13), thereby corrupting retention after the NRREP buffer!
Understanding The Primitive
Before nosotros motion on, let’s accept a 2nd to empathize the exploit primitive -- every bit mentioned above, nosotros are able to perform 16-bit increments (which are also 16-bit aligned), spanning upwards to threescore bytes beyond our allocated buffer.
Oddly, spell the standards specify that each NRREP may contain several encoded reports (each of which should live handled past times the receiving station), it appears that the handler functions higher upwards only processes a unmarried IE at a time. Therefore, each NRREP nosotros shipping volition live able to trigger a single OOB increment.
9.6.7.7
This lastly fact ties inwards rather annoyingly with some other quirk inwards the firmware’s code -- namely, upon reception of each NRREP, the listing of stored NRREP elements is freed before proceeding to procedure the electrical flow chemical constituent (see line 7, where free_previous_nrreps is invoked). It remains unclear whether this is intended deportment or a bug, but the immediate final result of this oddity is that next each OOB increment, the buffers are afterwards freed, allowing other objects to accept their place.
Lastly, the reception of each NRREP triggers two allocations of distinct sizes; i for the linked listing chemical constituent (456 bytes), together with some other to shop the report’s information (28 bytes). As a result, whatever heap shaping or preparation we’ll perform volition have got to accept both allocations into consideration.
Triggering The Vulnerability
Configuring The Network
To laid about developing our exploit, we’ll usage the same examine network surroundings nosotros described inwards the previous spider web log post, using the next topology:
As we’re going to leverage NRREPs, it’s of import to laid upwards our examine network to back upwards vecino reports. Like many auxiliary Wi-Fi features, back upwards for NRREPs is indicated past times setting the corresponding fighting inwards the capability IEs broadcast inwards the network’s beacon. RRM-related functionality is encoded using the “RM Enabled Capabilities” information element.
Since we’re using hostapd to broadcast our network, we’ll enable the rrm_neighbor_report setting inwards our network’s configuration. Enabling this characteristic should laid the corresponding acre inwards the “RM Enabled Capabilities” IE to dot back upwards for vecino reports. Let’s inspect a beacon frame to brand sure:
Alright, seems similar our network configuration is valid! Next, we’ll want to create an interface allowing us to shipping arbitrary vecino reports to peers inwards the network.
To exercise so, we’ll extend hostapd past times adding novel commands to its command interface. Each novel command volition correspond to a unmarried frame type we’d similar to inject. After adding our code to hostapd, nosotros tin give the axe only connect to the command interface together with number the corresponding commands, thereby triggering the transmission of the requested frames from the access dot to the selected peer. You tin give the axe uncovering our patches to hostapd inwards the exploit package on the põrnikas tracker.
It should live noted that this approach is non infallible. Since we’re utilising a SoftMAC dongle to transmit our internal network, the SoftMAC layer of the Linux Kernel is responsible for some of the MLME processing done on the host. Therefore, it’s possible that processing done past times this layer volition interfere with the frames nosotros wishing to shipping (or receive) during the exploit’s flow. To larn to a greater extent than or less this limitation, we’ve taken attention to create the frames inwards a trend that does non clash with Linux’s SoftMAC stack.
Sending NRREPs
After configuring together with broadcasting our network, nosotros tin give the axe finally endeavour to trigger the vulnerability itself. This brings us to a rather of import question; how volition nosotros know whether the vulnerability was triggered successfully or not? After all, a unmarried 16-bit increase may live insufficient to crusade important corruption of the firmware’s memory. Therefore it’s solely possible that spell the OOB access volition occur, the firmware volition happily chug along without crashing, leaving no observable effects indicating the vulnerability was triggered.
Remembering our Wi-Fi debugger from the previous spider web log post, i course of didactics of activity directly springs to heed -- why non only claw the NRREP processing business office with our ain handler, together with catch whether our handler is invoked upon transmitting a malicious NRREP? This is easier said than done; it turns out most of the NRREP treatment functionality (especially the actual vulnerability trigger, which we’re interested in) is located inside the ROM, preventing us from inserting a hook.
As luck would have got it, a novel characteristic developed past times Broadcom tin give the axe live leveraged to solve this issue. To allow tracing different parts of the firmware’s logic, including the ROM, Broadcom have got introduced a laid of logging functions embedded throughout the firmware. Curiously, this machinery was non nowadays inwards the Android-resident firmwares nosotros had analysed inwards the past.
Reverse-engineering this mechanism, it appears to operate inwards the next manner: each draw is assigned an identifier, ranging from 0x0 to 0x50. When a draw is requested, the firmware inspects an internal array of the same size stored inwards the firmware’s RAM, to gage whether the draw with the given identifier has been enabled or not. Each identifier has a corresponding 8-bit mask representing the types of traces enabled for it. As nosotros are able to access the firmware’s RAM, nosotros tin give the axe only enable whatever draw nosotros similar past times setting the corresponding bits inwards the draw array. Subsequently, traces with the same ID volition live outputted to the firmware’s console, allowing us to handily dump them using our Wi-Fi firmware debugger.
This functionality has also been incorporated into our Wi-Fi debugger, which exposes functions to read together with modify the log condition array every bit good every bit API to read out the firmware’s console.
Using the higher upwards API, nosotros tin give the axe at nowadays enable the traces referenced inwards the NRREP’s ROM handlers. Taking a closer seem at the NRREP treatment business office inwards the firmware, nosotros come upwards across the next traces:
Alright, so we’ll demand to enable log identifier 0x16 to abide by these traces. After enabling the trace, sending an NRREP together with reading out the firmware’s console, nosotros are greeted with the next result:
Great! Our traces are existence hit, indicating that the NRREP is successfully received past times the station. With that, let’s motion on to the next stair - devising an exploit strategy.
An Exploit Strategy
Understanding The Heap
Since the vulnerability inwards query is a heap retention corruption, it’s of import that nosotros accept a 2nd to familiarise ourselves with the allocator’s implementation. In short, it is a “best-fit” allocator, which performs forrard together with backward coalescing, together with keeps a singly linked listing of costless chunks. When chunks are allocated, they are carved from the terminate (highest address) of the best-fitting costless chunk (smallest chunk that is large enough).
Free chunks consist of a 32-bit size acre together with a 32-bit “next” pointer, followed past times the chunk’s contents. In-use chunks contain a unmarried 32-bit size field, of which the top thirty bits announce the chunk’s size, together with the bottom 2 bits dot condition bits. Putting it together, nosotros brand it at the next layout:
Sketching An Exploit Strategy
Before nosotros rush ahead, let’s laid about past times devising a strategy. We already know that our exploit primitive allows us to perform 16-bit increments, spanning upwards to threescore bytes beyond our allocated buffer.
It’s of import to banker's complaint that the heap’s state, perhaps surprisingly, is incredibly stable -- lilliputian to no allocations are performed. What lilliputian allocations are made, are directly freed thereafter. As for frames carrying traffic (received or transmitted); they are non carved from the heap, but rather drawn from a special “pool”. As such, the presence of traffic should non impact the heap’s state.
The heap’s stability is a double-edged sword; on the i hand, nosotros are guaranteed relative convenience when shaping together with modifying the heap’s state, every bit no allocations other than our ain volition interfere with the heap’s structure. On the other hand, the laid of allocations that can live made (and subsequently, targeted past times us using the vulnerability primitive) is limited.
Indeed, going over the activity frame handlers together with searching for objects which may serve every bit feasible targets for modification, nosotros come upwards up empty handed. The only information types that may live allocated either shop their “interesting” information farther than 56 bytes away from their rootage (accounting for the in-use chunk’s header), or only exercise non contain “interesting” information for modification.
Perhaps, instead, nosotros could leverage the heap itself to hijack the command flow? If nosotros were able to hijack the “next” pointer of a costless chunk together with afterwards dot it at a location of our choosing, nosotros could overwrite the target address with a subsequent allocation’s contents. This prospect sounds rather alluring, so let’s assay together with pursue this route.
Writing An Exploit
Hijacking H5N1 Free Chunk
To hijack a costless chunk, we’ll demand to commandeer a chunk’s “next” pointer. Recall that our exploit primitive allows us some aeroplane of command over neighbouring information structures. As such, let’s consider the next placement inwards which a costless chunk is inside attain of the NRREP buffer:
Leveraging our OOB increment, nosotros tin give the axe straight modify the chunk’s “next” pointer past times sending an NRREP asking with the corresponding channel number. Naively, this would allow us to gain command over a costless chunk inwards the heap, past times only directing the “next” at a location of our choosing.
However, this approach turns out to live infeasible.
In gild to direct the “next” pointer at a meaningful address, we’d have got to either know its value inwards advance (in gild to calculate the number of increments required to convert the pointer from its electrical flow value to the target value), or we’d have got to know the relative offset betwixt its electrical flow value together with the desired target.
As nosotros exercise non know the exact addresses of heap chunks (nor would nosotros want to resort to guessing them), the quondam alternative is ruled out. What almost the latter approach? Recall that our primitive allows for 16-bit increments. Therefore, nosotros tin give the axe either increase the pointer’s value past times 1 (by increase the bottom one-half word), or past times 65536 (by incrementing the top one-half word).
Incrementing the pointer past times 1 volition final result inwards an unaligned chunk address inwards the freelist. Recall, however, that our vulnerability primitive triggers deallocations on every invocation. As it happens, the allocator’s “free” business office validates that each chunk inwards the freelist is aligned. When an unaligned block inwards encountered, it generates a fault together with halts the firmware. Thus, an increase on of bottom half-word volition final result inwards the firmware crashing.
Incrementing the top half-word similarly fails; since all the heap’s chunks are less than 65536 away from the RAM’s terminate address, incrementing the top half-word volition final result inwards the “free” business office attempting to access retention beyond the RAM, triggering an access violation together with halting the firmware.
So how tin give the axe nosotros commandeer a costless chunk nevertheless?
To exercise so we’ll demand to usage a to a greater extent than subtle approach - instead of modifying the costless chunk’s contents directly, we’ll aim to attain a layout inwards which 2 costless chunks overlap i another, thereby causing allocations carved from i chunk to overwrite the metadata of the other (leading to command over the latter’s “next” pointer).
Heap Shaping
Achieving a predictable heap layout is cardinal for a reliable exploit. As our electrical flow destination is to create a specific layout (namely, 2 overlapping heap chunks), nosotros require setting upwards the heap inwards a trend which would allow us to attain such a layout.
Classically, heap shaping is performed past times leveraging primitives allowing for command either over an allocation’s lifetime, or optionally over the allocation’s size. Triggering allocations inside the heap without directly freeing them, allows us to create total “holes” inwards the heap, leading to a to a greater extent than predictable layout.
The allocator used inwards the firmware is a “best-fit” allocator which allocates from high addresses to lower ones. Consequently, if all “holes” inwards the heap of a for certain size are filled, subsequent allocations of the same size (or larger) would live carved from the best-fitting chunk, proceeding from top to bottom, thus creating a linear resources allotment pattern.
To empathize the Wi-Fi firmware’s heap layout, let’s accept a snapshot of the heap’s dry reason using our Wi-Fi debugger (repeating the procedure multiple times to occupation concern human relationship for whatever variability inwards the state):
As nosotros tin give the axe see, several minor chunks are strewn across the heap, amongst a unmarried large chunk. From the construction above, nosotros tin give the axe deduce that inwards gild to create a predictable resources allotment designing for our NRREP buffer, we’d only demand a shaping primitive allowing us to create total all the “holes” whose sizes gibe that of the NRREP buffer.
However, this is easier said than done. As we’ve mentioned before, lilliputian allocations occur during routine operations, together with those that exercise are directly freed thereafter. Combing through all the activity frame handlers, nosotros neglect to uncovering fifty-fifty a unmarried instance of a retention leak (i.e., an resources allotment with infinite lifetime), or fifty-fifty an resources allotment that persists beyond the compass of the handlers themselves. Be that every bit it may, nosotros exercise know of i mechanism, governed past times activity frames, which could offering a solution.
Normally, each Wi-Fi frame received past times a station is individually acknowledged past times transmitting a corresponding acknowledgement frame inwards response. However, many use-cases be inwards which multiple frames are expected to live sent at the same time; requiring an acknowledgement for each private frame inwards those cases would live rather inefficient. Instead, the 802.11n criterion (expanding on 802.11e) introduced “Block Acknowledgements” (BA). Under the novel scheme, stations may admit multiple frames at once, past times transmitting a unmarried BA frame.
To utilise BAs, a corresponding session must initiatory of all live constructed. This is done past times transmitting an ADDBA Request (IEEE 802.11-2016, 9.6.5.2) from the originating peer to the responder, resulting inwards an ADDBA Response (9.6.5.3) existence sent inwards the opposite direction, acknowledging a successful setup. Similarly, BAs tin give the axe live torn downward past times sending a DELBA frame, indicating the BA should no longer live active. Each BA is identified past times a unique Traffic Identifier (TID). While the criterion specifies upwards to xvi supported TIDs, the firmware only supports the initiatory of all 8, restricting the number of BAs possible inwards firmware to the same limit.
Since the lifetime of BAs is explicitly controlled past times the construction of the corresponding BA sessions, they may constitute skillful heap shaping candidates. Indeed, going over the corresponding activity frame handler inwards the firmware, it appears that every allocated BA results inwards a 164-byte resources allotment existence made, belongings the BA’s contents. The resources allotment persists until the corresponding DELBA is received, upon which the BA construction corresponding to the given TID is freed.
To usage BAs inwards our network, we’ll add together a novel command to hostapd, allowing injection of both ADDBA together with DELBA requests with crafted TIDs. Furthermore, we’ll accept attention to compile hostapd with back upwards for 802.11n (CONFIG_IEEE80211N) together with to enable it inwards our network (ieee80211n).
Putting the higher upwards together, nosotros brand it at a pretty powerful heap shaping primitive! By sending ADDBA Requests, nosotros tin give the axe trigger the resources allotment of upwards to 8 distinct 164-byte allocations. Better yet, nosotros tin give the axe selectively delete the allocations corresponding to each BA past times sending a DELBA frame with the corresponding TID.
Having said that, 2 immediate downsides also fountain to mind. First, the resources allotment size is fixed, so nosotros cannot usage the primitive to shape the heap for allocations smaller than 164 bytes. Secondly the contents of the BA buffers are uncontrolled past times us (they by together with large contain bit-fields used for reordering frames inwards the BA).
Attempting Overlapping Chunks
Using our shiny novel shaping primitive, nosotros tin give the axe at nowadays proceed to shape the heap inwards a trend allowing the creation of overlapping chunks. To exercise so, let’s laid about past times allocating all the BAs, from 0 through 7. The initiatory of all few allocations volition create total inwards whatever holes tin give the axe accommodate them inside the heap. Subsequently, the remainder of the allocations volition live carved for the principal heap chunk, advancing linearly from high addresses to lower ones.
(Grey blocks dot costless chunks)
Quite conveniently, every bit the resources allotment primitive is much larger than the “small buffer” allocated during the NRREP request, it allows the smaller holes inwards the heap, those large plenty to agree the 28 byte allocation, to persist. Consequently, the “smaller buffer” is only carved from i of the remaining holes, allowing us to safely ignore it.
Getting dorsum to the number at mitt - inwards gild to create an overlapping allocation, all we’d demand to exercise is usage the vulnerability primitive to increase the size acre of i of the BAs. After growing the size past times whichever amount nosotros desire, nosotros tin give the axe proceed to delete the newly expanded BA, along with its neighbouring BAs, causing an overlapping allocation.
Unfortunately, running through the higher upwards scenario results inwards a resounding failure -- the firmware crashes upon whatever endeavour to costless a block causing an overlapping allocation…
To larn downward to the bottom of this strange behaviour, we’ll demand to locate the source of the crash. Inspecting the AppleBCMWLANBusInterfacePCIe driver, it appears that whenever a trap is generated past times the firmware, the driver only collects the aforementioned crash data, together with outputs it to the device’s syslog. Therefore, to inspect the crash report, we’ll only dump the syslog using idevicesyslog. After generating a crash nosotros are presenting with the next output:
Inspecting the source address of the crash inwards the firmware’s image, nosotros come upwards across an unfamiliar block of code inwards the “free” function, which was non nowadays inwards prior firmware versions. In fact, the entire business office seems to have got many of these blocks… To empathize this novel code, let’s dig a lilliputian deeper.
New Mitigations
Going over the allocator’s “free” function, nosotros uncovering that inwards add-on to freeing the blocks themselves, the business office at nowadays performs several additional verifications on the heap’s structure, meant to ensure that it is non corrupted inwards whatever way. If whatever violations are detected, the firmware calls an “abort” function, afterwards causing the firmware to crash.
After reverse-engineering all the higher upwards validations, nosotros brand it at the next listing of mitigations:
- The chunk’s bounds are compared against a pre-populated listing of “allowed” regions.
- The chunk is compared against all other chunks inwards the freelist, searching for overlaps.
- The chunk is checked against a listing of “disallowed” regions.
- The chunk is ensured to live 4-byte aligned.
If whatever violation is detected, the firmware triggers the “abort” function, thereby halting execution.
It appears that Broadcom has done some hardening on the allocator! This is smashing from a security perspective, but rather bleak tidings for our exploit, every bit it appears that whatever endeavour to create an overlapping couple of chunks volition final result inwards a crash. Perhaps we’re out of luck…
Bypassing Mitigation #1
...Or are we?
Instead of initiatory of all increasing a heap block’s size, so freeing it to create overlapping chunks, let’s opt for different approach. We’ll suit for the next layout; first, we’ll create 2 costless chunks, which are non directly side past times side to i some other (to foreclose the allocator from coalescing them). Then we’ll usage the NRREP primitive to tardily increase the size of i block, until it overlaps the other.
However, every bit the NRREP primitive only allows us to modify information extending upwards to threescore bytes after the buffer, together with each BA buffer is much larger inwards size (164 bytes), we’ll initiatory of all demand to devise a programme to larn our NRREP buffer closer to a costless chunk, without it genuinely impeding on the chunk (and thereby coalescing with it).
We’ll exercise so past times leveraging a lilliputian trick. After allocating all the BAs, we’ll proceed to slightly increase the lastly BA’s size using the vulnerability primitive. Once that chunk is freed, a costless chunk is afterwards created inwards its place, spanning the novel expanded size instead of the original allocation’s size. Since the novel costless chunk extends into neighbouring BAs, the next BA resources allotment volition so overlap a previously allocated BA. This allows us to effectively “sink” an resources allotment into neighbouring blocks, advancing the compass of influence of our NRREP buffer to previously unreachable objects!
As the allocator’s “malloc” business office zeroes every chunk upon allocation, next the programme higher upwards volition Pb to BA6’s size existence laid to zero. However, there’s no demand to fret, nosotros tin give the axe only increase it using our NRREP primitive (as we’re at nowadays inside attain of BA6).
Next, we’ll increase BA6’s size slightly until it nearly overlaps with BA5. Then, nosotros tin give the axe costless both BAs, together with proceed to usage the NRREP buffer to increase BA6’s costless chunk until it overlaps with BA5’s. It’s of import to banker's complaint that since both “holes” are much smaller than the NRREP buffer, it won’t live placed inside them, leaving us to utilise them every bit nosotros please.
Bypassing Mitigation #2
Having created a couple of overlapping free-chunks, our initiatory of all instinct is to carve an resources allotment from the encompassing chunk, thereby overwriting the other chunk’s metadata. To exercise so, we’ll demand to uncovering an resources allotment primitive allowing for command over its contents.
Recall that nosotros have got already searched for (and failed to locate) allocations with a controlled lifetime. Therefore, whatever resources allotment primitive nosotros exercise uncovering would live i with a limited lifespan. But alas, freeing an resources allotment carved from whatever of the overlapping chunks volition Pb us in i trial once again to the “free” function’s overlapping chunk mitigation, afterwards halting the firmware (and thwarting our attempt). Let’s accept a closer seem at the mitigation together with catch whether nosotros tin give the axe uncovering a way to a greater extent than or less it.
Going through the code, it appears to have got the next high-level logic:
1. //Calculating the electrical flow chunk’s bounds
2. uint8_t* start = (uint8_t*)cur + sizeof(uint32_t);
3. uint8_t* end = start + (cur->size & 0xFFFFFFFC);
4.
5. //Checking for intersection betwixt the electrical flow chunk together with each free-chunk
6. for (freechunk_t* p = get_freelist_head(); p != NULL; p = p->next) {
7. uint8_t* p_start = (uint8_t*)p;
8. uint8_t* p_end = p_start + (p->size & 0xFFFFFFFC) + 2 * sizeof(uint32_t);
9. if (end > p_start && p_end > start)
10. CRASH();
11. }
As nosotros tin give the axe catch above, the code snippet higher upwards lacks checks for integer overflows! Therefore, past times storing a sufficiently large size inwards a costless chunk, the calculation of p_end volition final result inwards an integer overflow, leading the value stored to larn a depression address. Consequently, the seem at line ix volition e'er evaluate to “false”, allowing us to bypass the mitigation.
Great, so all nosotros demand to exercise is ensure that when overwriting BA5’s costless chunk, nosotros also laid its size to an exorbitantly large value. Moreover, every bit we’re dealing with a “best-fit” allocator, such a chunk volition never live the best plumbing fixtures (as smaller chunks volition e'er exist), so there’s no demand to worry almost the allocator using our malformed chunk inwards the interim.
Creating Overlapping Chunks
To proceed, we’ll demand to locate an resources allotment primitive allowing command over its contents, together with preferably also offering a controlled size. Using such a primitive, we’ll live able to create an resources allotment for which BA6’s costless chunk is the best fitting, afterwards overwriting BA5’s free-chunk header.
Going through the activity frame handlers in i trial again, nosotros uncovering a near-fit; Spectrum Measurement Requests (SPECMEAS). In short, SPECMEAS frames (9.6.2.2) are activity frames belonging to the Spectrum Management category. These requests are used past times access points to learn stations to perform diverse measurements together with study the results dorsum to the network.
Broadcom’s Wi-Fi firmware supports 2 different types of measurements; a “basic” measurement, together with a “Clear Channel Assessment” (CCA) measurement. Upon receiving a SPECMEAS request, the firmware allocates a buffer inwards gild to shop the report’s data. For every “CCA” measuring received, five bytes are added to the buffer’s size. However, for every “CCA” measuring encountered, 17 bytes are added to the buffer, of which many contain attacker-controlled data!
Using this primitive nosotros tin give the axe so trigger allocations of sizes that are linear combinations of five together with 17. For every 17-byte block corresponding to a “basic” measurement, nosotros tin give the axe command several of the embedded bytes (namely, those at indices [5,15], 2).
While non a perfect resources allotment primitive, it’ll have got to do. Since at that spot are to a greater extent than than 8 subsequent controlled bytes for each “basic” measuring request, nosotros tin give the axe usage them inwards gild to overwrite BA5’s costless chunk header (the 32-bit size together with pointer fields). By using a linear combination of the sizes above, we’ll guarantee that the controlled bytes are aligned with BA5’s costless chunk header. Lastly, the size of the resources allotment performed must also live chosen so that BA6’s costless chunk is the best plumbing fixtures (therefore forcing the resources allotment to live carved from it, rather than other costless chunks). Putting it all together, nosotros brand it at the next layout:
Overwrite Candidates
Now that we’re able to commandeer costless chunks, nosotros precisely demand to uncovering some overwrite candidates inwards gild to hijack the command flow.
Whereas inwards the previous firmware versions nosotros researched, in-use chunks contained the same fields every bit a costless chunks (namely, 32-bit size together with next fields), the electrical flow chunks’ formats brand them incompatible with costless chunks. Therefore, in-use chunks normally exercise non constitute valid targets to impersonate costless chunks.
Nonetheless, it is non solely impossible that such objects exists. For example, whatever in-use resources allotment starting with a 32-bit null discussion would live a valid costless chunk. Similarly, chunks could laid about with 32-bit pointers to other information types, which themselves may constitute a valid chain of costless chunks. Even ameliorate yet, whatever information construction inwards the firmware’s RAM (not only heap chunks) could conceivably masquerade every bit a costless chunk, so long every bit it follows the higher upwards format.
To larn to the bottom of this, we’ve written a brusk script that goes over the firmware’s contents, searching for blocks that gibe the aforementioned description. Each block nosotros uncovering constitutes a potential overwrite target past times directing our simulated costless chunk at it. Running the script on a RAM dump of the firmware, nosotros are greeted with the next result:
Great, at that spot appear to live several candidates for overwrite!
In our previous exploration of the Wi-Fi firmware, nosotros identified a for certain shape of objects that made skillful targets for hijacking command flow -- timers. These structures agree business office pointers denoting periodically invoked timer functions. While many such timers be inwards the electrical flow firmware every bit well, they are rather difficult to overwrite using the higher upwards primitive. First, they exercise non start with a 32-bit null acre (but rather with the magic value “MITA”). Second, each timer is a link inwards a doubly-linked list, whose contents are constantly manipulated. To overwrite a timer, we’d demand to insert a valid chemical constituent into the list.
Instead, going over the listing of candidates above, nosotros come upwards across a construction inside the “persist” segment, containing a block of business office pointers. Using our firmware debugger, nosotros tin give the axe indeed verify that several of the business office pointers inside this construction are periodically invoked. Therefore, past times finding a costless chunk candidate inside this block, nosotros should live able to commandeer i of the aforementioned business office pointers, directing it at a location of our choice.
Unfortunately, attempting to exercise so results inwards a resounding failure.
Bypassing Mitigation #3
Each endeavour to allocate information on top of the aforementioned block of business office pointers using SPECMEAS frames, directly causes the firmware to halt. Inspecting the source of the crash leads us dorsum to i of the mitigations nosotros mentioned before on; the “disallowed ranges” list.
Apparently, the entire “persist” block is contained inwards the listing of regions inside which “free” operations must non occur. Consequently, without bypassing this mitigation, nosotros volition non live able to overwrite information inside the aforementioned range.
Thinking almost this mitigation for a moment, nosotros come upwards up with an interesting proposition: perhaps nosotros could usage our commandeered costless chunk inwards gild to overwrite the “disallowed ranges” listing itself?
While the list’s contents lays inside i of the disallowed zones, recollect that this validation is only performed past times the “free” function, whereas “malloc” volition happily carve allocations at whatever address, without consulting the higher upwards list. Therefore, past times pointing our costless chunk to a location overlapping the “disallowed ranges” list, nosotros tin give the axe usage a SPECMEAS frame to overwrite its contents (thereby nullifying its effect). While SPECMEAS frames are directly freed after they are allocated, this is no longer a concern, every bit past times the fourth dimension the “free” occurs, the “disallowed ranges” volition have got already been overwritten!
Putting It All Together
Using the steps above, nosotros tin give the axe disable the “disallowed ranges” list, allowing us to afterwards usage the commandeered costless chunk inwards gild to hijack i of the business office pointers inwards the persist block. Finally, nosotros only require a agency of stashing some shellcode inwards a predictable location inside the firmware’s RAM. By doing so, nosotros volition live able to direct the aforementioned business office pointer at our shellcode, leading to arbitrary code execution.
Since the addresses inside the “persist” block are fixed, they brand for prime number candidates to shop our shellcode. Searching through the block, nosotros come upwards across several potential overwrite candidates, whatever of which tin give the axe live hijacked with our “fake” costless chunk.
However, there’s i to a greater extent than hurdle to overcome -- the code we’re almost to shop must non live overwritten at whatever point. If the code is inadvertently overwritten, the firmware volition endeavour to execute a corrupted chunk of code, peradventure leading it to crash.
To larn to a greater extent than or less this limitation, we’ll usage i to a greater extent than activity frame: Radio Measurement Requests (RMREQ). These frames are component of the 802.11k RRM standard, together with allow for periodic measurements to live performed (and reported) past times the firmware. Similarly to SPECMEAS frames, their handler allocates several bytes of information for each measuring IE encoded inwards the request.
Most importantly, RMREQ frames include a acre denoting the number of repetitions that stations should perform when receiving the scan request. Going through the specification reveals that this acre also has a “special” value, allowing scans to choke along indefinitely:
IEEE 802.11-2016, 9.6.7.3
By encoding this value inwards an RMREQ frame, nosotros tin give the axe guarantee that the corresponding allocated buffer volition non live afterwards freed, so allowing condom storage of our code.
Lastly, nosotros demand to consider the occupation of the shellcode’s internal structure. Unlike SPECMEAS frames which allowed us to command multiple bytes inwards each chunk of the allocated buffer, RMREQ frames only furnish command over iv subsequent bytes out of every 20-bytes allocated. Luckily, every bit Thumb is a dense didactics set, it allows us to cram 2 didactics into each 32-bit controlled word. Therefore, nosotros tin give the axe intermission upwards our shellcode using the next pattern: the initiatory of all 16-bit discussion volition encode an didactics of our choosing, whereas the 2nd discussion volition contain a relative branch to the next controlled chunk. Formatting our shellcode inwards this trend allows us to create arbitrarily large chunks of shellcode:
Building a Backdoor
Combining all the primitives above, nosotros tin give the axe finally stash together with execute a chunk of shellcode on the Wi-Fi firmware!
To allow for easier exploration of the firmware, it’s worth taking a instant to convert this rudimentary shape of access to a to a greater extent than refined toolset. Otherwise, we’d have got to resort to encoding all the post-exploitation logic using segmented chunks of shellcode -- non an alluring prospect.
We’ll laid about past times using the shellcode higher upwards to write a minor “backdoor” into the firmware, which we’ll telephone call upwards the “initial payload”. This payload constitutes the most minimal backdoor imaginable; it only intercepts the NRREP handler, together with reads 2 32-bit words from it, storing the value of i discussion into the address denoted past times the other. The initial payload so allows us to perform arbitrary 32-bit writes to the firmware’s RAM, past times sending crafted NRREP frames over-the-air.
Next, we’ll usage the initial payload inwards gild to write a to a greater extent than sophisticated one, which we’ll refer to every bit the “secondary payload”. This payload also intercepts the NRREP handler (replacing the previous hook), but allows for a far richer laid of commands, namely:
- Reading information from the firmware RAM
- Writing to the firmware’s RAM
- Executing a shellcode stub
- Performing a CRC32 calculation on a block of data
The capabilities higher upwards allow us to fully command the firmware’s over-the-air, from the security of a python script. Indeed, non different our inquiry platform, we’ve implemented the protocols for communicating with the backdoor inwards python, allowing for APIs implementing all of the functionality above.
In fact, the 2 are so similar, that several of the inquiry framework’s modules tin give the axe live straight executed using the secondary payload, past times only supersede the retention access APIs inwards the inquiry framework with those offered past times the secondary payload.
The Exploit
Summing upwards all the piece of work above, we’ve finally written a consummate exploit, allowing code execution on the Wi-Fi chip of the iPhone 7. You tin give the axe uncovering the consummate exploit here.
The exploit has been tested against the Wi-Fi firmware nowadays inwards iOS 10.2 (14C92). The vulnerability is nowadays inwards versions of iOS upwards to (and including) iOS 10.3.3. Researchers wishing to utilise the exploit on different iDevices or different versions, would live required to adjust the necessary symbols used past times the exploit (see “exploit/symbols.py”).
Note that the exploit continuously attempts to install the backdoor into the Wi-Fi firmware, until it is successful. For whatever unsuccessful attempt, the firmware only silently reboots, allowing the exploit to choke along along. Moreover, due to a clever feat of technology scientific discipline past times Apple, rebooting the firmware does non interrupt ongoing connections; instead, they are continued every bit the chip reboots, allowing for a rather stealthy attack.
Wrapping Up
Over the course of didactics of this spider web log shipping nosotros performed a deep dive into the Wi-Fi firmware nowadays on the iPhone 7. Our exploration led us to uncovering novel assault surfaces, several added mitigations, together with multiple vulnerabilities.
By exploiting i of the aforementioned vulnerabilities, nosotros were able to gain command over the Wi-Fi SoC, allowing us to gain a foothold on the device itself, straight over-the-air. In doing so, nosotros also bypassed several of the firmware’s exploit mitigations, demonstrating how they tin give the axe live reinforced inwards time to come versions.
In the next spider web log post, we’ll consummate our journeying towards total command over the target device, past times devising a total exploit chain allowing us to leverage our newly acquired command over the Wi-Fi chip inwards gild to launch an assault against iOS itself. Ultimately, we’ll create an over-the-air exploit allowing consummate command over the iOS kernel.
Komentar
Posting Komentar