Skip to content

Instantly share code, notes, and snippets.

@DavideGalilei
Created December 8, 2022 11:12
Show Gist options
  • Save DavideGalilei/344ceb9922efc6a5cae25b63ce76235d to your computer and use it in GitHub Desktop.
Save DavideGalilei/344ceb9922efc6a5cae25b63ce76235d to your computer and use it in GitHub Desktop.
Dump sqlcipher me.lam.calculatorvault sqlite database using Frida [ROOT]
// Thanks to https://ackcent.com/recovering-sqlcipher-encrypted-data-with-frida/
// frida -U -l sqlcipher_dump.js -f me.lam.calculatorvault
Java.perform(function() {
function dumpDb(File, db, path) {
var file = File.$new(path + ".plaintext");
file.delete();
db.rawExecSQL("ATTACH DATABASE '" + path + ".plaintext' AS plaintext KEY '';SELECT sqlcipher_export('plaintext');DETACH DATABASE plaintext;");
console.warn("\t[+] Dumped plaintext database at " + path + ".plaintext");
}
console.log("[-] Waiting for Java...");
while (!Java.available) {
}
console.log("[+] Java available!");
var File = Java.use("java.io.File");
console.log("[+] Hooked: " + File);
var CipheredSQLiteDatabase = Java.use("net.sqlcipher.database.SQLiteDatabase");
console.log("[+] Hooked: " + CipheredSQLiteDatabase);
CipheredSQLiteDatabase.openOrCreateDatabase.overload('java.lang.String', '[C', 'net.sqlcipher.database.SQLiteDatabase$CursorFactory', 'net.sqlcipher.database.SQLiteDatabaseHook', 'net.sqlcipher.DatabaseErrorHandler').implementation =
function(path, c, factory, hook, error) {
var db = this.openOrCreateDatabase(path, c, factory, hook, error);
console.log(path);
dumpDb(File, db, path)
return db;
};
});
@DavideGalilei
Copy link
Author

DavideGalilei commented Aug 28, 2023

Followup: just use the hardcoded sqlcipher key in the apk (with sqlcipher3 defaults)
308202bb308201a3a00302010202043ae411dc300d06092a864886f70d01010b0500300d310b30090603550406130238363020170d3137303331353130303431385a180f33303136303731363130303431385a300d310b300906035504061302383630820122300d06092a864886f70d01010105000382010f003082010a0282010100bbfe0147bd703505972b4c934afae6abf94257214f3ce720647b963bdfcf8c4644c65885f25b3cad1f8a91f5092f63cb28bcd5ed63c8ce22d6a193864284e03f86d475191d95aca1497860d183f9bcad1be70bf0a1e158d0fe3554a02ce687a1ddc50f17b2a5a61d467dba692be3df5cbb500df0aa52315081e9c149c736a4aa97c65cedf4cdb958751abd0a941401b764d2df70943a173d1e00615fa7fd886e6b6c93529b29549a667bbadc385ea3fe466b9cd23ff31373bee256db7520dc29c247608797badec8420fda45bb120a7714ea2909abd6b919fc125dfe4ffb9265b10a180362b7105df5fc22fb0de0aa17c47550288cc362cab5d54f1c7173dafd0203010001a321301f301d0603551d0e0416041436b53e659ac48f80a48d54d78a12cef6b651def5300d06092a864886f70d01010b050003820101001534e524e61725eac8d4c7d5ab78f807a22583ab9ca2532e10c39f4f18e22758efa98811a439ef9fd92f283fd5ec56e7af930b074e5a10ed5ac1047e26a948245c38380ffcb1eba3e1ff473ea46d85fd74d97bc5baa3982f87299e3249b82a75b639d5d1d703411cf0030da44887f012f7ca0c766db21d42bcfacb14ad0c28d28002cac40da2a752f68db4af1be267d832e310566f75554827bcf842adca875c28a6ffcde4aec4912e8c45d7b3dba4eb33ceccfa7cf6ea7a8ba3caeb619cbcca92c610214ebe80c7bac300f63ab4427a40a73a6f0d74d1f8ffb37380524624b14cc83425a0609e7e03ba9ea8658460448c2cfec2cb8f8b71db51e11944962ff2

sqlcipher/sqlcipher#437 (comment)

sqlite> PRAGMA key = '308202bb308201a3a00302010202043ae411dc300d06092a864886f70d01010b0500300d310b30090603550406130238363020170d3137303331353130303431385a180f33303136303731363130303431385a300d310b300906035504061302383630820122300d06092a864886f70d01010105000382010f003082010a0282010100bbfe0147bd703505972b4c934afae6abf94257214f3ce720647b963bdfcf8c4644c65885f25b3cad1f8a91f5092f63cb28bcd5ed63c8ce22d6a193864284e03f86d475191d95aca1497860d183f9bcad1be70bf0a1e158d0fe3554a02ce687a1ddc50f17b2a5a61d467dba692be3df5cbb500df0aa52315081e9c149c736a4aa97c65cedf4cdb958751abd0a941401b764d2df70943a173d1e00615fa7fd886e6b6c93529b29549a667bbadc385ea3fe466b9cd23ff31373bee256db7520dc29c247608797badec8420fda45bb120a7714ea2909abd6b919fc125dfe4ffb9265b10a180362b7105df5fc22fb0de0aa17c47550288cc362cab5d54f1c7173dafd0203010001a321301f301d0603551d0e0416041436b53e659ac48f80a48d54d78a12cef6b651def5300d06092a864886f70d01010b050003820101001534e524e61725eac8d4c7d5ab78f807a22583ab9ca2532e10c39f4f18e22758efa98811a439ef9fd92f283fd5ec56e7af930b074e5a10ed5ac1047e26a948245c38380ffcb1eba3e1ff473ea46d85fd74d97bc5baa3982f87299e3249b82a75b639d5d1d703411cf0030da44887f012f7ca0c766db21d42bcfacb14ad0c28d28002cac40da2a752f68db4af1be267d832e310566f75554827bcf842adca875c28a6ffcde4aec4912e8c45d7b3dba4eb33ceccfa7cf6ea7a8ba3caeb619cbcca92c610214ebe80c7bac300f63ab4427a40a73a6f0d74d1f8ffb37380524624b14cc83425a0609e7e03ba9ea8658460448c2cfec2cb8f8b71db51e11944962ff2';
ok
sqlite> PRAGMA cipher_migrate;
0
sqlite> .schema
CREATE TABLE IF NOT EXISTS "BOOKMARK" ("_id" INTEGER PRIMARY KEY ,"TITLE" TEXT NOT NULL ,"CONTENT" TEXT);
CREATE TABLE IF NOT EXISTS "CHOSEN_FILE" ("_id" INTEGER PRIMARY KEY ,"PATH" TEXT NOT NULL ,"NAME" TEXT NOT NULL ,"EXTENSION" TEXT NOT NULL );
CREATE TABLE IF NOT EXISTS "CONTACT" ("_id" INTEGER PRIMARY KEY ,"NAME" TEXT NOT NULL ,"NICK" TEXT,"PHONE" TEXT,"EMAIL" TEXT,"BIRTHDAY" TEXT,"ADDRESS" TEXT,"FACEBOOK" TEXT,"TWITTER" TEXT,"WE_CHAT" TEXT,"QQ" TEXT,"NOTE" TEXT);
CREATE TABLE IF NOT EXISTS "NOTE" ("_id" INTEGER PRIMARY KEY ,"CONTENT" TEXT NOT NULL ,"DATE_TIME" INTEGER NOT NULL ,"VISIBLE" INTEGER NOT NULL );
CREATE UNIQUE INDEX IDX_CHOSEN_FILE_PATH ON "CHOSEN_FILE" ("PATH" ASC);
CREATE UNIQUE INDEX IDX_NOTE_DATE_TIME ON "NOTE" ("DATE_TIME" ASC);
sqlite> select count(*) from sqlite_master;
6
sqlite> ATTACH DATABASE 'decrypted.db' AS decrypted KEY '';
sqlite> SELECT sqlcipher_export('decrypted');

sqlite> DETACH DATABASE decrypted;
sqlite> <Ctrl-D to exit>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment