# [zer0pts CTF 2020] Locked KitKat
###### tags: `zer0pts CTF` `forensics`
## Overview
We're given an Android disk image. Our goal is to find the pattern lock.
Since this is an old version of Android (KitKat), we can recover the pattern from `/data/system/gesture.key`.
## Solution
`gesture.key` uses SHA1 hash.
You can write a simple brute-force script.
```c
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#define MAX_LENGTH 9
void sha1(unsigned char *data, unsigned char *hash, int len) {
SHA_CTX c;
SHA1_Init(&c);
SHA1_Update(&c, data, len);
SHA1_Final(hash, &c);
}
long crack(unsigned char *target, int len, int depth, unsigned long code) {
int i;
long result;
unsigned long c = code;
unsigned char hash[SHA_DIGEST_LENGTH];
unsigned char data[MAX_LENGTH];
if (depth == len) {
for (i = 0; i < len; i++) {
data[i] = c % 10;
c /= 10;
}
sha1(data, hash, len);
if (strncmp(target, hash, SHA_DIGEST_LENGTH) == 0) {
return code;
} else {
return -1;
}
} else {
for (i = 0; i < 10; i++) {
result = crack(target, len, depth + 1, code * 10 + i);
if (result != -1) break;
}
}
return result;
}
int main(void) {
int l, i;
unsigned char target[SHA_DIGEST_LENGTH];
long result;
FILE *fp = fopen("./gesture.key", "rb");
if (fp == NULL) {
perror("gesture.key");
return 1;
}
l = fread(target, SHA_DIGEST_LENGTH, 1, fp);
for(l = 1; l <= MAX_LENGTH; l++) {
result = crack(target, l, 0, 0);
if (result == -1) {
printf("[-] Failed: len=%d\n", l);
} else {
printf("Code: ");
for(i = 0; i < l; i++) {
printf("%c", (char)(0x30 + (result % 10)));
result /= 10;
}
putchar('\n');
fclose(fp);
return 0;
}
}
puts("Solution not found :(");
fclose(fp);
return 1;
}
```