iPhone7的WiFi远程漏洞公开发布【转】

Broadcom produces Wi-Fi HardMAC SoCs which are used to handle the PHY and MAC layer processing. These chips are present in both mobile devices and Wi-Fi routers, and are capable of handling many Wi-Fi related events without delegating to the host OS.

In order to allow fast roaming between access points in a wireless network, the Broadcom firmware supports the Fast BSS Transition feature (IEEE 802.11r-2008 FT) as well as the Radio Resource Management standard (IEEE 802.11k-2008 RRM). Much of the information related to RRM is transferred by means of Wi-Fi Action Frames, using the RRM category (5).

One such frame which is handled by Broadcom's firmware is the "RRM Neighbor Report Response" frame, which has following general structure:

  -----------------------------------------------------------------------
  | Category (5) | Action (5) | Dialog Token | Neighbor Report Elements |
  -----------------------------------------------------------------------
  0              1            2              3                          X

(See 802.11-2016, 9.6.7.7, 9.4.2.37 for more information).

On the BCM4355C0 SoC with firmware version 9.44.78.27.0.1.56 the RRM Neighbor Report Response frame is handled by RAM function 0x1B0FE8 (which delegates to ROM function 0xABBBC). This function verifies the dialog token (although that is a single byte field, so it can be easily brute-forced by an attacker if they do not know it in advance). Then, the function copies over the contents of the Neighbor Report Response frame into a heap-allocated buffer and subsequently calls an internal ROM function at 0xAC0A8 to store the number of neighbors for each given "Operating Class" (see 9.4.2.37).

Here is the approximate high-level logic for this function:

int function_AC0A8(..., uint8_t* nrrep_buffer, ...) {
  ...
  //Find and increment neighbor in given channel for given OP-Class
  int res = function_AC07C(..., nrrep_buffer, ...);

  //If there's no entry for the given OP-Class, create and populate it
  if (!res) {
    uint8_t* buffer = malloc(456);
    if ( !buffer ) {
      ...
    }
    else {
      buffer[4] = nrrep_buffer[16];              //Operational Class
      uint8_t channel_number = nrrep_buffer[17]; //Channel Number
      uint16_t* chan_neighbor_count_arr = (uint16_t*)(buffer + 6);
      chan_neighbor_count_arr[channel_number]++;      
      ...
    }
  }
  ...
}

As shown in the snippet above, the firmware keeps a linked list of buffers, one per "Operational Class". Each buffer is 456 byte long, and keeps the array holding the number of neighbors per channel. The entries have the following structure:

  -----------------------------------------------------------------------
  | Next Pointer | Operational Channel | Padding | Neighbor Count Array |
  -----------------------------------------------------------------------
  0              4                     5         6                      456

However, since the "Channel Number" field is not validated, an attacker can arbitrarily provide a large value. While the maximal allowed channel number is 0xE0, by providing a larger value (such as 0xFF), the function above will increment a 16-bit word beyond the bounds of the heap-allocated buffer, thereby performing an OOB write. Note that the same insufficient validation is also present in the internal function 0xAC07C.

I've been able to verify that this code path exists on various different firmware versions, including those present on the iPhone 7 and Galaxy S7 Edge.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.
此条目发表在iOS, 漏洞攻击分类目录。将固定链接加入收藏夹。