Secure Notes
None of the free note taking app offer encryption... So I made my own!
Challenge
TL;DR: Brute force pin to decrypt note.
Examining the decompiled source code of the APK with JADX
, in LoginActivity
we can see a function where it seems to create a new notes.db
file with the d.k()
function. The function seems to concatenate the string from the textview
(most probably our pin field) 4 times to act as a password to this function.
public void onClick(View view) {
try {
d.k(this.f1583b.getText().toString() + this.f1583b.getText().toString() + this.f1583b.getText().toString() + this.f1583b.getText().toString(), new File(this.f1584c.getPath()), new File(LoginActivity.this.getCacheDir(), "notes.db"));
LoginActivity.this.startActivity(this.f1585d);
} catch (p0.a unused) {
Toast.makeText(LoginActivity.this.getApplicationContext(), "Wrong password", 0).show();
}
}
Navigating to source code of the d.k()
, we can see that it is an AES decryption function:
public static void k(String str, File file, File file2) {
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(str.getBytes(), "AES");
Cipher instance = Cipher.getInstance("AES");
instance.init(2, secretKeySpec);
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bArr = new byte[((int) file.length())];
fileInputStream.read(bArr);
byte[] doFinal = instance.doFinal(bArr);
FileOutputStream fileOutputStream = new FileOutputStream(file2);
fileOutputStream.write(doFinal);
fileInputStream.close();
fileOutputStream.close();
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e2) {
throw new a("Error encrypting/decrypting file", e2);
}
}
Now, as the pin is only 4 digits, we can bruteforce this combination and try to decrypt our encrypted database which can be found in the assets/database/db.encrypted
by extracting it from the APK using unzip. Below is a Java code reusing some of the app source code to brute force:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.WeakHashMap;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class brute_decrypt {
public static void main(String[] args) {
File file1 = new File("assets/databases/db.encrypted");
File file2 = new File("./notes.db");
for (int i = 0; i <= 9999; i += 1) {
String pin = String.format("%04d", i);
//System.out.println(pin);
// Pin is concatenated 4 times as AES key
k(pin + pin + pin + pin, file1, file2);
}
System.out.println("End");
}
public static void k(String str, File file, File file2) {
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(str.getBytes(), "AES");
Cipher instance = Cipher.getInstance("AES");
instance.init(2, secretKeySpec);
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bArr = new byte[((int) file.length())];
fileInputStream.read(bArr);
byte[] doFinal = instance.doFinal(bArr);
FileOutputStream fileOutputStream = new FileOutputStream(file2);
fileOutputStream.write(doFinal);
fileInputStream.close();
fileOutputStream.close();
// Print if successful
String pin = str.substring(0, 4);
System.out.println(pin);
file2 = new File("./valid/notes.db_" + pin);
fileOutputStream = new FileOutputStream(file2);
fileOutputStream.write(doFinal);
fileOutputStream.close();
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e2) {
//System.out.println("Error encrypting/decrypting file" + e2);
}
}
}
By compiling with javac
and running with java brute_function brute_function.class
, it outputs around 40 valid pins. Not sure why this is happening but there may be a bug somewhere, but due to laziness, just run grep -r ./valid -e "flag"
and get our flag. We can also see that the actual valid pin is 5732
.
Flag: flag{a5f6f2f861cb52b98ebedcc7c7094354}