In my recent Android trainings and the Android security talk I gave at AppForum 2014 I was asked to provide a sort of a demo that can be easily replicated to explain the importance of maintaining a proper security posture. So I created a script that ‘recovers’ PSKs from the device and displays them.
Before moving on, a brief disclaimer: Android (or iOS, or Windows) are pretty secure, it is up to the user how much of this security is traded for convenience (or ignorance).
The Android system UI never displays the existing PSKs to the user, so we need to look elsewhere. Wi-Fi settings are in fact stored in the file /data/misc/wifi/wpa_supplicant.conf. You’ll be surprised to see all PSKs there in plan text. Well, normally, this file is not accessible by anyone, but root, so regular apps cannot see it (unless you’re rooted, which is always a bad idea for production devices). Thus, we should be fine. However, root or not, doesn’t really matter:
- All OS settings (including WLAN) are managed by the Settings Provider.
- The Settings Provider is implemented as a package: com.android.providers.settings.
- Just like any other package, its data can be backed up via ADB.
- Backup can be made secure (encrypted) on insecure.
- Insecure backup can be unpacked with data extracted from it.
Security of a backup depends entirely on user’s decision at the backup time. It’s nice to deal with a consumer-oriented OS! 🙂
Assuming the device is connected over ADB:
W:\>adb backup -f settings.ab -noapk com.android.providers.settings Now unlock your device and confirm the backup operation
Touching the ‘Backup’ button on the Android device generates a settings.ab file, which is unencrypted, since we haven’t specified the password (remember trading convenience for security?). Now, we need to extract it, but how?
The very first result of Googling for “Extract Android Backup” leads to http://sourceforge.net/projects/adbextractor/
W:\abe>java -jar abe.jar unpack settings.ab settings.tar Strong AES encryption not allowed Magic: ANDROID BACKUP Version: 1 Compressed: 1 Algorithm: none 6144 bytes written to settings.tar.
Now we have a TAR file that can be opened by most popular archivers:
Automating the attack
Now, in order to make this attack happen we need to connect the device to USB, launch ADB, tap on the screen, etc. Can this be automated?
The answer is “kinda yes”. The reason for “kinda” will become apparent in a moment. Here’s a sample CMD script that I wrote (full version of the script is attached further down). Mind the string wraps.
adb wait-for-device :: simulate power key and swipe to unlock adb shell input keyevent 26 adb shell input swipe 230 650 430 650 :: start backup in a separate thread, give some time for the animation start adb backup -f settings.ab -noapk com.android.providers.settings adb shell sleep 1 :: tap the "Backup now" and wait for backup to complete adb shell input tap 360 750 adb shell sleep 5 :: simulate Home and Power keys as if nothing happened adb shell input keyevent 3 adb shell input keyevent 26 :: extract backup and unpack it java -jar abe\abe.jar unpack settings.ab settings.tar tar -xf settings.tar :: find the WLAN section and display it grep --text -A2 "ssid" apps\com.android.providers.settings\f\flattened-data > _PSK.txt start _PSK.txt
Using the Android input shell command, we are able to simulate all sorts of taps and swipes and special keypresses (using the keyevent, which is fully documented here) . Knowing the screen resolution of our device we can fully automate the process, provided ADB is enabled – just plug the device into USB port, and a text file with PSKs pops up ~15sec later. Considering that ADB server can be ran on another Android device you don’t even need a computer for that.
Note: because back up process requires us to start the backup (which puts the script on hold) and then tap the screen – we need to use Windows “start” command to run the backup command in a separate window to prevent it from blocking the script. The delay is important, since we need for the prompt animation to finish before we can tap the screen in the right place (1sec is enough).
You can download the whole packaged solution to play with your device here: extractPSK-zip (rename from PDF to ZIP – WordPress limitation).
Note: Some devices allow unlocking by the ‘menu’ key (keyevent 82) instead of sending a whole swipe.
Limitations and workarounds
Well, the most obvious one is that the script is resolution-dependent. That’s because it was thrown together in <10min to run a demo on a specific device. Running
W:\>adb shell dumpsys window | grep "Display:"
Produces Display: init=… cur=480×800 app=… rng=…, where cur is the current display resolution. Using a scripting language with regular expression support one can determine resolution, orientation and position of the controls. I’m not doing it, because it’s not supporting the core concept, but you are welcome to face the challenge, check this page for starters.
Then, there must be no PIN/Password/pattern lock. Seems like a major barrier, but, in fact, is also manageable, thanks to various bugs. Here’s one way that worked for me so far on all pre-KK builds:
adb shell am start -n com.android.settings/com.android.settings.ChooseLockGeneric --ez confirm_credentials false --ei lockscreen.password_type 0 --activity-clear-task
For KK the adb shell pm clear com.android.keyguard command is said to work, but I haven’t tested it yet (wrecked my device 😦).
Then, there’s only ADB left. You can’t turn ADB on remotely, but it’s surprising how many people have it on: advanced users, enthusiasts, “hackers”, developers. ADB is used in lots of homebrewn deployment, configuration and control scripts (just like this one) when consumer devices do get into enterprise environments. And, of course, few bother to turn it off after they’re done. Plus, if you manage to get the phone in your hands (“Can I make a quick call?”, “Can I check out this fancy app/game/photos of yours?”, etc) – nothing prevents you from enabling it in 20sec. And after you gain connection once, it’s easy to reconfigure it to work over plain TCP/IP (i.e. Wi-Fi) instead of USB and enjoy remote
mayhem control it provides.
In Android <= 4.1 ADB has no authentication, turning it into an IMMENSE backdoor. Do watch this short film, it’s a very old soviet animation, the quality sucks, but it delivers the message extremely well.
In Android 4.2.2 ADB became ‘secure’ by requesting the host device authorization before actually allowing the connection. However, not for long.
So, the only way to reliably have ADB on is to have Android 4.4.3+, which is [most likely] only available if your device was manufactured in 2013 and the manufacturer is under Google’s ADA (Android Distribution Agreement), which means they MUST release updates to their phones. Raise your hand if you have at least one an oriental AOSP-built sub $150 phone. I have one – it was released with 4.0.3 and got a single update in its entire life to …4.0.3 with some most apparent driver bugfixes.
So, the only real way to protect from this is to have ADB fully off, and not allow a slightest chance for someone to turn it on.
What does it all mean in the Enterprise environment? What if you have to run Android in Enterprise? To be honest, I see just two choices:
1. Run it on proper Enterprise devices. For example, our devices have the core OS slightly modified (still maintaining app compatibility within CTS), but things like PSKs, certificates and many other passwords are actually moved out of standard Android frameworks (and additionally encrypted where needed). It is still transparent for law-abiding and properly written apps, but if try and back that device up, you will not see any PSKs at all (with the exception of an older OS build for one of them, which is exactly the one I’m using for demos 🙂). Other enterprise vendors might or might not do the same, but as a security-conscious Enterprise customer I would definitely run a check like this to see whether the device is an easy prey for script kiddies.
2. Run it on popular flagship consumer devices that have lasting community support. The Android community is far more agile and responsive than most device manufacturers. For example, CyanogenMod and some other mods got FakeID vulnerability patched (and released) within 24hrs from disclosure, even before Google. Have you seen such reaction from any vendor out there? In addition, popular devices (like the SGS3) that have been abandoned by their manufacturers continue getting updates in 3rd party ROMs, which allows for increased longevity and investment protection. Of course, the devices need to be future-proofed: have max RAM/internal flash available to support the new ever-so-hungry Android releases and be popular enough to ensure community is even interested in them. This raises CapEx a bit (especially given that many vendors void your warranty as soon as you’re off the stock firmware), but may still be viable if the ‘coolness factor’ is an important part of your operations (employee rewards, customer-facing duties in boutiques, etc). In addition, the most popular devices from major vendors have MDM support, which means you will not fall prey to a huge surge in OpEx (time and money required to manage all those devices manually).
Thus, the bottom line is that relying on manufacturer is not an option, unless the manufacturer manufactured something specifically for the Enterprise market. This is true for all of them: Apple, Google, Samsung, Sony, LG, HTC, younameit: the size of Enterprise handheld market (in units) is <0.5% of the consumer handheld market – who would care?
Now, there’s one thing I don’t want you to get wrong from this. Yes, Android has bugs, but who doesn’t? Apple does, Windows does, the space-rocket-launching-microcontrollers also do, and in all cases there were reports of things blowing up. This post is not about bugs. In 90%+ of cases, the security is compromised because of design/configuration/convenience/ignorance issues.
ADB is a backdoor. The [supposedly] most secure phone ever – The Blackphone – was hacked using ADB. Which had to be manually enabled.
Running insecure backups w/o encryption is equally stupid on any OS, be it mobile, server or desktop. Similar tools exist for iOS, and, I’m pretty confident, they also allow recovering all sorts of sensitive information.
This post is about not enabling the backdoors, not trading essential security for convenience (we all have to compromise), or, at least, understanding the consequences and being ready to face them.
Bottom line: you devices are only as secure as you configure them to be. Be safe! 🙂