Blog: Android

Brute Forcing Android PINs (or why you should never enable ADB part 1)

David Lodge 14 Nov 2013

About a year ago, those clever people over at Hak5 published a video, which showed the use of their Rubber Ducky HID emulator to unlock a 4 digit PIN on an android device.

This (ab)uses the flexibility of Android; that it allows the use of keyboards at the point of the Android Keyguard through the use of a USB On The Go (OTG) cable, or a similar USB hub, depending on the type of device.

This is a very useful tool in the Android tester’s armoury and one that I’ve made use of in the past to demonstrate why PINs are weak and should be avoided. But there are some problems with it that could do with working around:

1) It takes a long time (about 16 hours for 4 digits)
2) You have to monitor it to see when it gets to the passcode
3) You need a Rubber Ducky (or something else that can perform HID emulation)

We can’t do much about 1: that’s a feature of Keyguard that we have to live with. If we can fix the others we can just set it going in the background and go off and do something more interesting with our time.

Unfortunately, the Ducky, although a great tool, is controlled by a simplistic engine which doesn’t allow us much flexibility on controlling the process. So if we want to fix 2 then we must also get rid of the Ducky (which nicely fixes 3).

It turns out that Android has a built in native command, input, which allows the sending of input to the current activity, this includes Keyguard. The command was present on every Android device that I have and is even included in Firefox OS.

The documentation is a bit weak on what parameters the command takes, the basic command is just a shell script to spawn com.android.command.input.Input, and examination of the source shows that it’s just a front end to InputManager. The command line help tells us:

shell@android:/ $ input
input
usage: input …
input text <string>
input keyevent
input [touchscreen|touchpad] tap <x> <y>
input [touchscreen|touchpad] swipe <x1> <y1> <x2> <y2>
input trackball press
input trackball roll <dx> <dy>

And a quick web search shows that we can find the important key events in the KeyEvent class. A quick proof of concept with a basic tablet can be seen, by placing it so that Keyguard is active and running:

C:\tools>adb shell
shell@android:/ $ input text “1111”
input text “1111”
shell@android:/ $ input keyevent KEYCODE_ENTER
input keyevent KEYCODE_ENTER
shell@android:/ $

And, the tablet unlocks!

So lets do a basic proof of concept test shell script that just replicates the Ducky functionality:

for i in $(seq 0 5 9999);do for ((j=$i;j<$i+5;j++)); do key=$(printf “%04i” $j);echo “$key”; adb shell input text $key; adb shell input keyevent KEYCODE_ENTER;sleep 1;done; adb shell input keyevent KEYCODE_ENTER; sleep 29;done

Our next step is to tune this process to allow us to see whether we can programmatically see whether we have unlock the device and return either the exact lock code, or a narrow range. For manual follow up.

Those that have experience of Android can see that there’s one flaw in this technique: it requires the Android Debug Bridge (ADB) to be enabled. This is not the default setting for most Android devices and requires a “secret” configuration with all versions from Jelly Bean and up.

We can protect against this in a couple of ways:
1. Do not use PIN protection, use a good password instead
2. Never leave ADB active

In Part 2 I’ll be looking at that 16 hour wait and how we know when the PIN is cracked, among other things.