<--

Google Nexus 9 SensorHub Firmware Downgrade Vulnerability

Aleph Research Advisory

Identifier

Severity

Moderate

Product

Google Nexus 9

Vulnerable Version

Nexus 9 Android Builds before N4F27B - May 2017, i.e. before bootloader 3.50.0.0143.

Mitigation

Install N4F27B or later (bootloader version 3.50.0.0143).

Technical Details

The Nexus 9 device contains a SoC manufactured by Cywee which implements a “Sensor Hub”. The SoC is an STM32F401B/C ARM Cortext-M4 MCU, managed by a driver available under drivers/i2c/chips/CwMcuSensor.c. The platform communicates with SensorHub via I\(^2\)C bus #0 and via 4 GPIO ports. See the device tree.

The MCU has two modes:

  1. Application mode. This is the normal firmware operation, where the MCU provides the sensors’ data via I\(^2\)C (slave address 0x72).
  2. Bootloader mode. This mode allows for firmware management via various interfaces, including I\(^2\)C (slave address 0x39). The MCU switches to the bootloader mode when the bootloader activation Pattern 1 is detected.

Upon the platform boot, the CwMcuSensor driver queries the firmware’s version (I\(^2\)C register 0x10). If it does not match the one found in the vendor’s partition (/vendor/firmware/sensor_hub.img), it switches to the bootloader mode, and upgrades the firmware (again, via I\(^2\)C). Please note that the firmware is not signed.

By issuing a proprietary fastboot oem command sensorhubflash, a physical attacker / malicious charger / malicious headphones (via the UART interface, exposed by the headphones jack – see our blog post) can downgrade the SensorHub firmware to an old version, saved under the SER partition (/dev/block/mmcblk0p19). This version may contain vulnerabilities which may allow the attacker to compromise the MCU.

One may claim that it is not an issue because the platform would immediately upgrade the firmware upon boot (since its version is different from the one found in the vendor image), however, in Nexus 9, the I\(^2\)C buses could be accessed via the fastboot interface, by using the fastboot oem {i2cr, i2cw, i2crNoAddr, i2cwNoAddr, i2cdetect} commands. (I\(^2\)C could also be accessed via UART, in the HBOOT mode.) Thus, the attacker could interact with the old firmware BEFORE it was replaced by the platform using I\(^2\)C, and thus potentially exploit a security vulnerability which would allow him to return a bogus version identifier, bypassing the platform’s check. Please note that the SoC’s I\(^{2}\)C code runs in privileged mode.

The next figure depicts the attack. The device is already in the fastboot mode. We first queried the current firmware version ID, by reading I\(^2\)C register 0x10. This ID corresponds to “Firmware Architecture version 1, Sense version 0, Cywee lib version 16, Water number 40, Active Engine 2, Project Mapping 1”. We then downgraded to the old firmware, and re-queried the firmware ID. As we can see, the old firmware is up and running, and returns a version ID which corresponds to “Firmware Architecture version 1, Sense version 0, Cywee lib version 10, Water number 19, Active Engine 1, Project Mapping 1”, much older!.

$ fastboot oem i2cr 0 0xe5 0x10 6
(bootloader) ret:0
(bootloader) > [8] = 1 0 10 28 2 1 0 0 0 0 0 0 0 0 0 0     
OKAY [ 0.013s]
finished. total time: 0.014s

$ fastboot oem sensorhubflash
...
(bootloader) RUU_frame_buffer_enable_flag=0                       
(bootloader) RUU_frame_buffer_enable_flag=0                       
(bootloader) RUU_frame_buffer_enable_flag=0                       
...                      
(bootloader) RUU_frame_buffer_enable_flag=0                       
OKAY [ 67.718s]
                                                  
finished. total time: 67.719s 
$ fastboot oem i2cr 0 0xe5 0x10 6
...                                                               
(bootloader) ret:0                                                
(bootloader) > [8] = 1 0 a 13 1 1 0 0 0 0 0 0 0 0 0 0           
OKAY [  0.015s]
                                                 
finished. total time: 0.016s  

PoC & Further Research

In addition to fetching the old firmware image from the flash (SER partition), for the sake of curiousity we also successfully obtained it from the SoC itself:

  1. We downgraded the SoC firmware by exploiting the vulnerability.
  2. We modified the CwMcuSensor driver (PoC can be found here). We disabled the firmware version check, and added a sysfs interface which allowed us to reboot the MCU into its bootloader mode and issue the bootloader READMEMORY command.
  3. We fetched the firmware from address 0x08000000

One can now take the old firmware and search for vulnerabilities.

Patch

Google patched the vulnerability on build N4F27B / bootloader 3.50.0.0143 by removing the sensorhubflash bootloader command:

...
$ fastboot oem sensorhubflash
(bootloader) [ERR] Command error !!!
OKAY [  0.013s]
finished. total time: 0.015s

In addition, access to the I\(^2\)C buses has also been removed from the bootloader – the I\(^2\)C related bootloader commands are no longer available:

$ fastboot oem i2cr 1 0xb8 6 1
...
(bootloader) [ERR] Command error !!!
OKAY [  0.011s]

finished. total time: 0.012s

Please note that although Google published the advisory on the April Security Bulletin, the patch has been included only since the April 5 2017 Security Patch Level, where the April Nexus 9 image (N4F26X) has the April 1 2017 Security Patch Level, hence it does not contain the patched bootloader.

Timeline

  • 04-May-17
    : Public disclosure.
  • 01-May-17
    : Patch available.
  • 03-Apr-17
    : Vendor advisory available.
  • 01-Mar-17
    : Added as ALEPH-2017010.
  • 01-Feb-17
    : Vulnerability triaged by Vendor (Moderate).
  • 28-Nov-16
    : Reported.

Posts

Credit

External References