Recently I’ve been looking at an application that has some data that I’d like to scrape and use/format for my own selfish desires. The application we are targeting is on iOS + Android so I went through the usual flow on my iPhone - mitmproxy - no good. traffic must be SSL / non-HTTP. Android cert-pinning stops app on init - wireshark w/ rvictl on iOS device - SSL traffic pulling initial data catalog / no API fetches once app is initialized (sqlite init)
After getting blocked and giving up for about a month I decided to root my OG Nvidia Shield and dig a little deeper..
Digging Deeper
Prereqs > Root phone -> Install Xposed Framework -> Download [Inspeckage] Module -> Get Started

My initial hope was that Inspeckage would solve all my problems and I wouldnt have to dig too much into Xposed but in the ended up being the launching pad to the golden catalog.
After turning on Inspeckage and letting the app boot up for
the first time we can see a few things. (1) https traffic, (2)
files created zip/certs/js+img assets. I was hoping the SQLite
tab would light up and we could query against .db file
immediately but that would be too easy 
Ripping things apart
Before getting into the .apk I figured it would be worthwhile to see what was stored on my device adb shell && cd /data/data/com.package.name/ and… explore!
The main thing I was looking for here was something in the
databases/ or files/ directories. Luckily we were able to spot
a TARGET.db within files/databases
but it was definitely encrypted (dreaded “file is encrypted or
not a database” when querying) > Remember that if the app
is not debuggable you won’t be able to
adb pull /pathtoDBFile.db instead you’ll have to
adb shell && su && mkdir /sdcard/data && cp /pathoDBFile /sdcard/data
and then pull that file
Inspeckage has the handy download .apk so there’s a few things we can do here (starting with the most obvious) - unzip it and take a look at what we’ve got
dan@dan-MacBookPro:~/riperino$ unzip og.apk
Archive: og.apk
inflating: META-INF/MANIFEST.MF
inflating: META-INF/CATEXTKY.SF
inflating: META-INF/CATEXTKY.RSA
inflating: AndroidManifest.xml
inflating: assets/_where-is-www.txt
...
extracting: assets/icudt46l.zip
extracting: assets/www/assets/
.... a ton of assets (selected some potential highlights)
inflating: assets/www/config/config.json
inflating: assets/www/cordova.js
inflating: assets/www/css/bootstrap/
inflating: assets/www/js/
extracting: res/drawable/icon.png
inflating: res/xml/config.xml
extracting: resources.arsc
inflating: classes.dex
...
inflating: lib/armeabi/libsqlcipher.so
inflating: lib/armeabi-v7a/libsqlcipher.so
inflating: lib/x86/libsqlcipher.so
From looking at the contents we can tell the basic structure but we are mostly interested in a few files - libsqlcipher.so & assets/icudt46l.zip (interesting fallback zip for sqlcipher..possible fun attack vector) - classes.dex (exactly what it says)
This confirms our hunch about SQLite and explains the missing contents from the SQLite tab while using Inspeckage. Now the hope is that classes.dex reveals something blatantly obvious..
Reading some code
There are quite a few tools for digging into the contents of that .dex file but I’ll go over my comfortable flow (unnecessary .dex -> .jar step with tools like Bytecode Viewer but the extra step does provide some extra possibilities if we really need to build a custom apk)
Using the dex2jar toolkit
we can use the classic d2j-dex2jar to give us the
handy .class files zipped to .jar (while not perfect this is
almost always “good enough” for what we need)
After creating the .jar its time to pop open Java Decompiler and dig into
the package in question.. And after a little while we run into
this section of code (masterKey makes us happy
and definitely worth hooking into?) 
After reading the docs for getReadableDatabase
it’s clear that’s indeed the SQLite password and if the
developer also followed the documentation they would also have
called createAndGetDBPath which would serve as
the initialization.. Lo and behold the
DBHelper.class implements that class and we can
add a hook to ensure we catch the key when we reboot the app
### Hooking and Winning Without getting too tangential Xposed
is great and the documentation
is outstanding for anyone interesting in getting started.
If the development tutorial is not enough the content online
was more than enough to clear up any potential blockers.
public class Main implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
findAndHookMethod("com.****.core.db.DBHelper", lpparam.classLoader, "createAndGetDBPath", Context.class, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("Hooked em': DBHelper#createAndGetDBPath ");
XposedBridge.log("----------------------------------------");
XposedBridge.log(param.args[1].toString());
XposedBridge.log("----------------------------------------");
}
});
}
}
We load our hook module, reboot our device and when we rerun the app we see something beautiful in the logs
Hooked em': DBHelper#createAndGetDBPath
----------------------------------------
base64masterKey== (totally legit..)
----------------------------------------
Now I should be able to
Sqlcipher rippedDB.db
PRAGMA key=”base64masterKey==”
.tables
And get something other than
file is encrypted or not a database.
Unfortunately this didn’t work on my machine and I thought I
was getting juked out and went to bed.

After thinking about questions like these (1,
2,
3)
all night + the following day of family time it became clear
versions must be the issue in my case. After figuring out the
difference between Commercial and
Community it became clear this was just a time save and
the same version was being used for both and the commercial
folks were just given the latest binaries without having to
work for them. Since we have some compatriots who dont like
working much either I ran brew install sqlcipher
and of course things just worked..
Mac - 3.15.2
Ubuntu 16.04 - 3.8.6
As an additional aside there are some open source “sqlbrowser applications” that have sqlcipher as a feature but dont do a great job revealing the versioning. Just build community versions as they are released and things should be fine / bank on everyone being on commercial and brew updating at the same time :D
Upon using the correct version we see a beautiful table list and can query to our heart’s content.
Retro
The entire sqlcipher seems incredibly trivial given the release strategy and knowing what we know about hooking. The fact that the key is going to be passed around no matter what makes things quite easy unless some additional precautions are taken but unfortunately it just moves the problem a step deeper. In the end the Android SQLDatabase methods are going to used and we can hook them no matter how many Proxys/Helpers are introduced to the codebase. After digging further into the Xposed modules someone wrote a generalized hook that looks for the specific sqlcipher native package to hook into.. This seems to reinforce my belief that it’s general uselessness but there must be a reason big companies are giving them money (other than the desire to avoid building it themselves)