Blog: Android

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

David Lodge 25 Nov 2013

So… if you read my last Android post you would have seen a little technique to replicate the Hak5 keyboard brute force for Android PINs without the use of extra hardware, if the Android device has ADB enabled.

Just to remind you, the three flaws of the Hak5 method are:
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’ve effectively fixed flaw 3, but can we close on flaw 2?

One technique is to use some basic maths to look at reducing the area of the password being cracked. Android will allow 5 incorrect PINs before it will lock the PIN for 30 seconds and will bring up a warning screen showing how many bad PINs have been typed:

Android-PIN-error-message

So, if we divide up the range of brute-forcing, into, say 10 chunks of 1000 PINs each, we can run the job until it finishes and read the number of incorrectly typed PINs. If it’s 1000, then the PIN wasn’t in that chunk. If it is less, then we take the provided number away from 1000 and the PIN should be around there.

For example, if we have a PIN of 4673, then after running each chunk we should see the following messages:

You have incorrectly typed your PIN 1000 times
You have incorrectly typed your PIN 2000 times
You have incorrectly typed your PIN 3000 times
You have incorrectly typed your PIN 4000 times
You have incorrectly typed your PIN 330 times

So we know that the PIN must be around 4670 and can do a manual or watched exploit from there.

But, you know what? This isn’t sexy or exciting! I’ve got much better things to do with my time than watch the incorrect PINs on an android device go up and up. Fortunately we have some more Android utilities that can help us with this.

If you’ve tried to run the rubber ducky attack, or my attack on an Android device you’ll have noticed that we need to know two things:
1. When the passcode has worked
2. When the screen has switched off

Starting with issue 2: Android will switch the screen off on Keyguard after 30 seconds of idle time. Which will mess up our timing on the brute force. We can switch the screen back on by issuing the following command through adb:

input keyevent KEYCODE_POWER

But this toggles the power state and could lead us to a situation where the screen is off when we try and do our brute forcing. We could put an extra delay in, but this would increase that 16 hour time.

What we could do is to read the state of the power. The official way to do this is to set up a service to listen for the ACTION_SCREEN_ON and ACTION_SCREEN_OFF intents. This isn’t the best solution for us as we’re not trying to install anything on the devices.

If we dig a bit more into the API we can discover the PowerManager APIs which has an isScreenOn() method. This method was added in API level 7, or ECLAIR_MR1 (Android 2.1) which means that it should be supported in most current Android devices.

An interface to PowerManager runs as the power service, which we can send messages to using the service command. The service command allows us to talk to running services, and more importantly call a method, using its call command.

We have to be careful here as the interfaces may change with each major version of Android, so the below case is for Android 4.2.2 (Jelly Bean MR1) which happens to be installed on my testing tablet. For this version of Android the isScreenOn() method is call number 9 and takes no parameters.

So if we call this through the command line when the screen is off, we can see:

shell@android:/ $ service call power 9
service call power 9
Result: Parcel(00000000 00000000 ‘……..’)

And if the screen is on we see:

shell@android:/ $ service call power 9
service call power 9
Result: Parcel(00000000 00000001 ‘……..’)

For the next issue (1. How do we know when the passcode has worked) we need to know whether or not the screen is enabled.

From Android 4.1, a new user interface automation testing API came in, which has a convenient command line front end call uiautomator. One of the facilities of uiautomator is a facility to dump the layout of the current task (or activity in Android parlance) as an XML file.

If we use the uiautomator to dump the current layout (using the uiautomator dump command) then we should see the highest node of the Keyguard screen:

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”true”?>
<hierarchy rotation=”1″>-<node bounds=”[0,0][1440,828]” selected=”false” password=”false” long-clickable=”false” scrollable=”false” focused=”false” focusable=”false” enabled=”true” clickable=”false” checked=”false” checkable=”false” content-desc=”” package=”android” class=”android.widget.FrameLayout” text=”” index=”0″>

Leaving us with a package of android and a class of android.widget.FrameLayour as the top node. Most other applications have the package set to the name of the application.

So, this leaves us with a technique to perform a relatively sturdy brute force attack on a Keyguard PIN, which will tell us when it finishes and is pretty robust. The final step is to mangle it together into a script (see below) and show an example:

$ perl ./brute-lock.pl
Starting bruteforce
[…]
Trying 1200 to 1204
Trying 1205 to 1209
Trying 1210 to 1214
Trying 1215 to 1219
Trying 1220 to 1224
Trying 1225 to 1229
Trying 1230 to 1234
The screen is unlocked, last code is 1234

NB: The brute-lock.pl script I wrote, is a simple rough and ready proof of concept, which is available here.