Cracking the Pattern Lock on Android

As you maybe know it is very easy to get around the pattern lock on an Android smartphone. In this post we will describe the following two ways to get around it:

  • on a rooted smartphone
  • with the help of the JTAG interface

Some Background Information

The pattern lock is entered by the user joining points on a 3×3 matrix in his/her chosen order. Since Android 2.3.3 this pattern must involve a minimum of 4 points (on older Android versions the minimum was 3 points) and each point can only be used once. The points of the matrix are registered in a numbered order starting by 0 in the upper left corner and ending by 8 in the bottom right corner. So the pattern of the lock screen in the next figure would be 0 – 3 – 6 – 7 – 8.

      

Android stores this pattern in a special file called gesture.key in /data/system/. As storing the pattern in plain text wouldn’t be very save, Android only stores an unsalted SHA1-hashsum of this pattern (see the code snippet afterwards). Accordingly, our pattern is stored as c8c0b24a15dc8bbfd411427973574695230458f0.

private static byte[] patternToHash(List pattern) {
    if (pattern == null) {
        return null;
    }

    final int patternSize = pattern.size();
    byte[] res = new byte[patternSize];
    for (int i = 0; i < patternSize; i++) {
        LockPatternView.Cell cell = pattern.get(i);
        res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
    }
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] hash = md.digest(res);
        return hash;
    } catch (NoSuchAlgorithmException nsa) {
        return res;
    }
}

Due to the fact, that the pattern has a finite and very small number of possible combinations the use of an unsalted hash isn’t very save. It is possible to generate a dictionary (rainbow table) with all possible hashes and compare the stored hash with that dictionary in a few seconds. To assure some more safety, Android stores the gesture.key file in a restricted area of the filesystem where a normal user can’t access it. If you have to get around it, there are two ways from which you can choose.

On a Rooted Smartphone:

If you deal with a rooted smartphone and USB debugging is enabled, cracking of the pattern lock is quite easy. You just have to dump the file /data/system/gesture.key and compare the bytes of this file with your dictionary. If the smartphone is rooted but USB debugging is disabled, you just need to google a bit, there are plenty ways to enable debugging from outside the phone.

With the Help of the JTAG Interface:

If you deal with a stock or at least unrooted smartphone this whole process is a bit more complicated. First of all, you need special hardware like a Riff-Box and an JIG-adapter or some soldering skills. After you have gained a physical dump of the complete memory chip the chase for the pattern lock can start. In our experiment we used a HTC Wildfire with a custom ROM and Android 2.3.3 flashed on it and the pattern lock from the beginning of this post. After looking at the dump, we noticed that every chunk has an exact size of 2048 bytes. Since we know that our gesture.key file has 20 bytes of data (SHA1-hashsum) we searched for this combination of bytes and noticed, that there is one chunk starting with this 20 bytes followed by 2012 bytes of zeros and about 16 random bytes (seems to be some meta filesystem information). We did the same search on several other smartphone dumps (mainly older Android versions on the same phone) and it came out, that this method is the easiest way to get the pattern lock without being root.

In other words:

  • try to get a physical dump of the complete memory
  • search for a chunk with a size of 2048 bytes, starting with 20bytes random, followed by 2012 bytes zeros and 16 bytes random
  • extract that 20 bytes random at the beginning of the chunk
  • compare these 20 bytes with your dictionary
  • type in the corresponding pattern on the smartphone itself

We also included this functionality and a dictionary in our forensic toolkit ADEL.

17 Replies to “Cracking the Pattern Lock on Android”

  1. Hi,

    You mentioned that there are plenty of ways to enable USB debugging from outside the phone. I was searching for it on google, but I couldn’t find any.

    Would it be possible for you to post a link.

    Thanks.

    Regards,
    Nik

  2. Hi Nik,

    the words “from outside the phone” were maybe a bit misleading. The better manner of expression would have been “without using the system settings of Android” or “without unlocking the smartphone”.

    For Example, there are some exploits which are able to enable USB debugging and on many rooted phones you can enable USB debugging when booting into recovery mode.

    Best regards,
    Michael

  3. Thanks for the information.

    I was looking for a way to enable it on a non-rooted locked phone.

    Any suggestions?

    Regards,
    Nik

  4. Hi Nik,

    it depends on the type of smartphone and the purpose of the gathered information.

    If it is a samsung or htc smartphone and and the purpose is for testing only, I would suggest to flash a new kernel (or at least recovery-image) which has USB debugging enabled. On this phones you normally don’t need to flash a complete custom ROM and therefor you are not loosing the complete data. Or you can try to compile a exploit which is able to start automatically and enables USB debugging after BOOT_COMPLETED and put this exploit on the SDcard. (please understand that I’m not posting any links to exploits here)

    If you need the gathered information for a court case, I would suggest the JTAG-method.

    Best regards,
    Michael

  5. It depends on the phone type. On some phones you can use a modified recovery image with enabled adb and root shell.

  6. Hi. I’m trying to do this on cm11. So key file should be opened just with notepad? I opened it with notepad++ and I think this hash isn’t SHA1 or not even salted one: (W,vùÕ7ö ráàÌtéË´Ba) <-inside cm_gesture.key. The gesture.key was empty and I couldn't find lockscreen.salt from databases. The hashID can't identify this neither.

  7. Hi,
    I have a question..how 0-3-6-7-8 , sha-1 hash become C8C0B24A15DC8BBFD411427973574695230458F0
    ??? Thank you.

  8. Hi roger, just have a look at the code-snippet in the post above and use [0,3,6,7,8] as pattern (=> patternToHash([0,3,6,7,8])).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.