Current State of Android "Physical" Security
Posted on Mo, 2013-09-02 in android
About a year ago I gave a talk to my fellow students about the security of android devices, once you get physical access to them. This post will be pretty much that talk plus some additional infos and links. You can find the slides here [1].
The Evil Maid Attacks
An evil maid attack is an attack that assumes that you leave your device in the hotel room a maid comes in and has therefore gained physical access to your device. She then installs malware, dumps data or whatever else is possible. The classic target is the notebook. Against data theft we can use full disk encryption. Against malware we will want to harden our device as much as possible. Especially preventing booting from anything but our primary HDD. Unfortunately this only helps against a quick install, since the maid has physical access to the HDD, where she will probably find an unprotected bootloader or kernel. So to secure a notebook against this type of attack, one must deploy something like UEFI Secure Boot. Maids (or some hacker in a maid outfit who social engineered somone the hotel room key ;) can be devious.
So the situation with phones is a bit different. Usually you cannot simply disassemble it to get access to the persistent storage inside the device. But what can an attacker do with physical access?
Detour: Android Internals and Boot Process
Before I talk about what to do with physical access to android devices, I will give a short introduction to some of the android internals and specifically to the boot process. For more information on the android boot process checkout this excellent presentation [3] or this page [4].
Android Partition Layout
The android partition layout is differs from device to device, but there are some main components that can be found on every device.
On most devices / is actually a ramdisk that is created at every boot. So don't try to persist anything there. The contents of the ramdisk are loaded from the "boot" partition, where also the kernel lies. /system: contains the core OS, all the system binaries, configuration, the android framework etc. The apps and all the data that apps produce are stored in /data/. Another interesting partition is the recovery image partition. This partition contains a kernel and a ramdisk similar to the "boot" partition, but is not intended to boot the full system, but provide only basic functionality for recovering devices or updating the devices firmware. Flashing a new recovery image is usally one of the first steps when using a custom ROM. The there usually is a partition for the cache, which is used by the android JVM implementation (the dalvik VM). Finally we have the storage where the user has direct access. For example the SD card or internal memory. Those are usually acessible via /sdcard, /mnt/storage or something similar.
Boot Process
HTC/Qualcomm devices usually boot in the following manner. Don't forget that we have two "main" processors inside a typical phone. One that performs all the stuff related to the telephone network (called baseband processor) and one that processes all the applications and the actual OS (also called the applications processor).
- The baseband processor starts and loads the primary boot loader (PBL)
- The PBL loads the secondary boot load (SBL)
- The application processor boots the HBOOT bootloader
- HBOOT loads the kernel or recovery image
Other devices boot in a similar manner, although they use their custom bootloader(s) and everything is called a little different.
To achieve security during the boot process the bootloader verify the next step before continuing. So in this case the PBL verifies the signature of the SBL. The SBL verifies and loads the baseband code and the HBOOT bootloader. HBOOT the verifies and loads the kernel/recovery. This way no untrusted code can be booted.
For development this isn't really practical, so one can usually unlock the bootloader, so that untrusted kernels or recoveries can be booted. This is cool because we can use this to install custom ROMs. Most app processor bootloaders implement the fastboot protocol, so that it can be controlled over USB. fastboot is also the tool that ships with the android sdk and can be used to boot other kernels, recoveries, flash images to partitions and also unlock the phones bootloader. The later can be achieved by using:
fastboot oem unlock
What this does is disable signature checking of the kernel/recovery image but most devices also perform a factory reset (aka. formatting the /data/ partition) when the bootloader is unlocked. Note that not all devices have bootloader that can be that easily unlocked or relocked.
HTC S-ON/S-OFF
You can think of this as a more complete device lockdown. Additionally to a locked bootloader, the /system, kernel and recovery partition are hardware-write-protected. So even if we gain root on the phone, we cannot modify the system beyond a reboot. To gain S-OFF one can use an exploit or go the offical HTC way, where you need to submit a token and flash a signed blob, so that HTC can confirm that you know that the warranty is now voided. This makes the system, kernel and recovery partition writable and you are free to flash your own images.
Attack Scenarios
With all that in mind let's look at a couple of scenarios and what can happen to an android phone, when the attacker has physical access.
Scenario 1: Standard Phone
Prerequisites: stock ROM, no adb, no root
This is a pretty boring scenario, as the best you can do is pull the SD card out of the device and look for interesting things. There might be some personal data, pictures etc. More interesting might be Android apps that were moved to the sdcard or backups of app internal data to the SD card. But you probably can't totally own the phone, unless you have a working exploit for the USB driver, of which I'm not aware of any.
But what about devices that have no SD card? For example the Nexus S has no SD card, but only internal memory. The data is accessed via the Media Transfer Protocol and is only available if android is unlocked I'm not talking about the bootloader, but the actual OS that is running. Most android devices can only be used after a certain pattern is drawn. Alternatively you can use a PIN, a password or the new face unlock feature.
Smudge Patterns
In 2010, pretty soon after Android started booming, the first attack against the unlock pattern was presented [2]. The problem is that we leave smudge on the display after inputting the unlock pattern. If we input our pattern a few times we can see the line of smudge on the display and only have to guess the direction in which the pattern is input. And that's not hard to bruteforce ;)
The paper that presented the attack describes several possibilities using a camera and some image manipulation to make the pattern more visible [2].
Face unlock method introduced in Android 4 is another insecure method for unlocking the phone. It can be easily tricked by showing a picture of the owner (accessible via your favorite social network) to the phone. So if you are truely paranoid use a PIN or a password to protect your phone. But what if an attacker does actually manage to unlock your phone? I will discuss that in the next section.
Scenario 2: Developer Phone
Prerequisites: stock ROM, no root, adb enabled
Now we look at a phone that has adb enabled, because it's the phone of a developer that is also used privately.
Installing Malware
the first thing that comes to my mind is: install some malware:
adb install com.example.AngryBirdsStarTrek.apk
Using adb we can also access many parts of the system, although we are still restricted. We can give our malware all kinds of permissions to gain access to a lot of personal data. Unfortunately we don't have unlimited permissions, because the really awesome permissions are the system or systemOrSignature level permissions, which are only available to system apps or apps signed by the system vendor.
But that said we can get access to most personal data, such as contacts texts, phone calls etc.
We can also use our installed app to disable the "keyguard" lock, effectively bypassing any PIN, password, unlock pattern or face unlock. This is as simple as the following code (which might not be accurate anymore but I'm currently too lazy to check again ;)
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardLock mkeyguardLock = keyguardManager.newKeyguardLock("unlock");
mkeyguardLock.disableKeyguard();
Oh shit. So now we have nearly unrestricted access to the phone. But what to do now?
Intercepting Login Credentials
While we do have access to the phone we probably can't access any credentials stored by the installed apps. What if we need to give the phone back soon and going through all the email directly on the phone probably isn't practical. What we do now is go back a level deeper and start watching the network traffic produced by the android phone. This means we launch a classic man-in-the-middle attack. Since we have access to the phone we can easily connect to our own hostile wifi. Unfortunately we can't see all the login credentials, since most apps transmit the data via https or TLS. But wait we can just add our own CA certificate in the android trust store and look at all this confidential data :) I like to use the mitmproxy [5] tool for such purposes, but you could also use Burp or OWASP ZAP. Unfortunately not all apps seem to support the proxy setting in Android.
Stuff you can intercept are mostly auth tokens [6], which can give you the power to take over accounts. But sometimes you get lucky and directly spot a password. The following image shows the mitmproxy tool while intercepting an authentication request. The "Token" parameter is the token which is used to authenticate the device.
Google had a very serious bug, where you could even bypass the two-factor authentication once you had access to an applicaiton specific password, such as the android's login token, which you can observe with a mitm proxy [7]. This was fixed by google.
So this is already pretty serious, but there is another feature of Google's Android: the Backup & reset feature. This feature enables a backup of system settings, application data and wifi passwords to the google cloud. If we use the google authentication token we sniffed to log into the google account on another rooted phone, we can get all the stuff backed up to google in plaintext. I'd say: "All your wifi password are belong to us!".
Escalate to root
So this is already pretty serious now, but we still do not have root, so we can't install the really juicy malware and give the phone back. Well we could also use one of the countless root exploits for Android. Nearly every phone and Android version is vulnerable to some kind of root exploit. Because phone vendors can't keep up with patching or leave devices intentionally vulnerable, the likelyhood that a device with adb enabled is vulnerable is pretty high.
Scenario 3: Rooted Phone
Prerequisites: rooted, custom ROM and recovery, adb access
This chapter is short: your are totally screwed.
With root access everything is possible and an attacker has access to absolutely everything: credentials, wifi passwords and all the data. Installing a really nice rootkit is also no problem.
Ok but what if we disable adb?
Prerequisites: rooted, custom ROM and recovery, no adb access
Let's remember the stuff about the locked bootloader? Yes most guides for custom ROMs usually suggest unlocking the bootloader and leaving it that way. That's very good for an attacker.
Using fastboot we can just boot an arbitrary kernel and do whatever we want anyway :) We can also use the standard update.zip mechanism of the installed recovery to "flash" a rootkit and gain access to the phone, but this is just for added comfort. Note that relocking the bootloader with a custom recovery that supports flashing new ROMs is pretty pointless.
Scenario 4: Encrypted Phone
So Android introduced "full disk encryption" with the release of 3.0 Honeycomb [8]. The disk encryption targets only the /data/ partition. This means that the core OS and system binaries etc. are still not encrypted, which is probably good for performance, but also leaves them subject to tampering.
So what to do with an encrypted phone?
Prerequisistes: unlocked bootloader, no adb access
So we could execute arbitrary code, but we have to reboot the device. This means that we can easily install a rootkit and give it back to the owner, hoping that he doesn't flash a new ROM. But maybe we can do something else.
Bruteforcing the Encryption Key
Android encryption forces you to set a password or PIN to unlock your device. Unfortunately the same password is used for unlocking the phone for everyday use and for decrypting the device. This means that you will probably use a very weak password. Who has the time and the nerve to input a 16 character password for quickly reading a text message.
Unfortunately the disk encryption for Android is tailored for low-power low-performance devices. Android uses dmcrypt for performing the actual crypto. The information needed to decrypt the phone is saved in the last 16 kB of the encrypted partition. The encryption key is actually just a bunch of random bytes read from /dev/urandom. This key is then encrypted using the users password. Because user passwords are usually pretty low entropy and don't have the right length for an encryption key, a technique called "key stretching" [9] is used. Like almost everyone else the standardized PBKDF2 function is used to stretch the key. PBKDF2 stand for Password Based Key Derivation Function 2 and uses repeated hashing and salting to derive an actual encryption key [10]. This technique is not only useful to derive good encryption keys with various lengths from a master key, but also offers protection against brute-force attacks. PBKDF2 is a parameterized function that takes the number of iterations as parameter. The higher the iteration count the more work has to be done before the actual key can be tested.
Unfortunately the iteration count is hardcoded to 2000 on Android, which is in fact pretty low. For example the LUKS/dmcrypt setup on my Fedora box uses about 160000 iterations for PBKDF2. While this may not be possible on an Android device, an iteration count of 2000 is definitely too small. Additionally PBKDF2 is also pretty fast on GPUs.
Can you guess where this is going? Yes bruteforcing the password/PIN used to encrypt the device is absolutely feasible. It has actually been done with the hashcat bruteforcing tool [11]. So we see Android encryption isn't actually that secure.
Recovering the Encryption Key from Memory
Another attack against encrypted Android phones is called: FROST [12] [13]. As you might have guessed this is a form of cold boot attacks against Android phones. The researchers discovered that the contents of the RAM can be preserved across a device reboot by cooling it down. They showed that it is sufficient to cool the whole device, so it is not even needed to directly access the memory chips. They also wrote a recovery image and kernel module to search and dump any disk encryption keys that still reside in the memory of the Android device.
Not only encryption keys but also other possibly sensitive data such as pictures, documents or password to services can be retrieved using this cold boot attack.
Fortunately to boot into FROST or something similar, the phone needs to have an unlocked bootloader. As I wrote at the beginning unlocking should wipe all user data, which restricts FROST to recovering data from memory.
Defense and Conclusion
Let's be honest, the current state of Android "physical" security is pretty bad. But nevertheless there is one scenario in which you have pretty good chances against an attacker.
Prerequisites: locked bootloader, no custom recovery, encrypted phone, no adb, strong PIN/password
In this case the phone would be pretty secure. He cannot launch any network based attacks since hopefully TLS will protect most critical communication. An attacker cannot execute code unless he unlocks the bootloader first. Unlocking the bootloader will hopefully wipe your user data. So the only successful attack is recovering data from the RAM using a FROST style cold boot attack. Android apps dealing with sensitive data such as account credentials, tokens or crypto keys in any form, should flush them back to disk and from memory once the screen is locked. Another possibility would be to obfuscate such critical data inside the RAM, although this should be considered as a defense in depth strategy.
The first thing you should do when you get a lost phone back, is to factory reset the device, unlock the bootloader flash a new operating system, then relock the bootloader and hope that there is no rootkit hidden in the bootloader of the device (or somewhere else).
You are not necessarily bound to the original device firmware if your bootloader supports relocking with an arbitrary kernel image. Flashing a custom recovery usually leaves your device wide open, so you should only boot it directly via fastboot if you need the functionality of a custom recovery. In most cases it should be possible without flashing the recovery. Unfortunately no custom recovery that I know of supports any kind of authentication.
If you do a lot of development and constantly leave your device with adb enabled you could use the AdbSecure [14] app, which will disable adb when the screen is locked and enable it once the screen is unlocked. Note that since Android version 4.2 there is a property called "ro.adb.secure", which requires every "debugging device" to authenticate using an RSA key. The fingerprint of the key must be confirmed on the device and is saved during first debug attempt and checked the next time. This prevents that unkown devices get access to USB debugging without the screen unlock code. This means that you don't need something like AdbSecure, on devices that support it.
But now I leave the details of how to secure a device to another blog post ;)
For performing some of the attacks check out the work done by theKos, his "phone-to-phone adb" framework [16], a presentation [15] and this hak5 video [17]. The "raider backup tool" implements similar functionality [18]. FROST has also been released here [13].
Update 2013-11-19
Check out this awesome talk: https://www.youtube.com/watch?v=RHaxn1TzU3g
In short, what they did is to look at multiplexers in modern phones, which allow different kinds of signals be transmitted over one single wire/plug. One example would be USB on-the-go, which allows a device to act both as USB host and device. Another example they gave was the USB over the head-phone jack that small mp3-players such as this tiny Apple iPod (shuffle?) do.
They discovered that some Samsung phones multiplex a UART interface onto the USB plug. So with the right gear you can get the device to talk via UART with you and you get dropped into a small in-kernel debugger or a shell depending on the phone.
This is like a huge and crazy security risk, since you have nearly no control over it, except for mitigating on the software side... if you know about it that is.
[1] | http://f0rki.at/static/slides/evil-maid-on-droids_f0rki_hackingnight-2012-12-06.pdf |
[2] | (1, 2) http://static.usenix.org/events/woot10/tech/full_papers/Aviv.pdf |
[3] | http://www.sourceconference.com/publications/bos12pubs/android-modding-source.pdf |
[4] | http://tjworld.net/wiki/Android/HTC/Vision/BootProcess |
[5] | http://mitmproxy.org/ |
[6] | http://www.uni-ulm.de/en/in/mi/staff/koenings/catching-authtokens.html |
[7] | https://blog.duosecurity.com/2013/02/bypassing-googles-two-factor-authentication/ |
[8] | http://source.android.com/devices/tech/encryption/android_crypto_implementation.html |
[9] | http://en.wikipedia.org/wiki/Key_stretching |
[10] | http://en.wikipedia.org/wiki/PBKDF2 |
[11] | http://hashcat.net/forum/thread-2270-post-13608.html |
[12] | http://www1.cs.fau.de/filepool/projects/frost/frost.pdfa |
[13] | (1, 2) https://www1.informatik.uni-erlangen.de/frost |
[14] | https://play.google.com/store/apps/details?id=com.stericson.adbSecure |
[15] | http://kyleosborn.com/android/AndroidPhySec.pdf |
[16] | https://github.com/kosborn/p2p-adb/ |
[17] | https://www.youtube.com/watch?v=ah7DWawLax8 |
[18] | https://code.google.com/p/raider-android-backup-tool/ |