Frida03 - 一个简单案例

198 阅读2分钟

案例文件

文件放到了 github.com/aprz512/And… 下,可以自行下载。

案例分析

我们可以使用 file 命令看一下这个文件,或者直接拖到 vscode 里面:

发现这是 android 的一个 backup 文件,我们可以将其解压,在 github 里面搜索 Android backup :

下载其 release 文件,将该文件解压一下:

java -jar abe.jar unpack 1.ab 1.tar

得到一个 1.tar 文件,解压出来,使用 tree 命令看一下目录:

└── com.example.yaphetshan.tencentwelcome
    ├── a
    │   ├── base.apk
  ├── db
    │   └── Demo.db
    ├── Encryto.db
    └── _manifest

里面有一个 base.apk,这个 apk 很老了,只能运行在低版本下,否则会报 so 链接错误。

我们使用 genymotion 开一个 android 5 的模拟器,安装运行界面如下d

点击登录可以进入下一个界面,但是提示明显不对:

反编译看下逻辑:

发现这个界面没有做什么判断,就直接给了一个提示,说明我们想要crack的逻辑不在这里,看下上一个界面的逻辑:

一进来就往数据库里面写了些数据,点击事件并没有使用这些数据。

但是看到 a 方法里面是有一些字符串处理逻辑的,而且这里的 SQLiteDataBase 有一个 loadLibs 方法,正常是没有的,搜索一下:

回想一下,我们解压出来的目录里面有一个 Encrypt.db,所以很明显,这里是要我们拿到这个加密数据库的密钥。看一下这个 sqlcipher 的用法,发现是在 getWritableDatabase 方法的时候传进去就行,那么就思路很简单了。

我们使用 frida hook 这个方法就行。

经过尝试,发现高版本 frida 在使用过程中会闪退,所以又装了一个 12.8.0 版本的环境。

首先,尝试一下 hook com.example.yaphetshan.tencentwelcome.a 类,发现它虽然继承了 net.sqlcipher.database.SQLiteOpenHelper 但是无法 hook 到 getWritableDatabase 方法。

所以,最后是直接 hook 了 net.sqlcipher.database.SQLiteOpenHelper 的 getWritableDatabase 方法:

android hooking watch class_method net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase --dump-args --dump-backtrace --dump-return

然后,手动调用 MainActivity 的 a 方法来触发逻辑执行:

...mple.yaphetshan.tencentwelcome on (Google: 5.1) [usb] # android heap search instances com.example.yaphetshan.tencentwelcome.MainActivity                                                                                              
Using exsiting matches for com.example.yaphetshan.tencentwelcome.MainActivity. Use --fresh flag for new instances.
Handle    Class                                               toString()
--------  --------------------------------------------------  -----------------------------------------------------------
0x100462  com.example.yaphetshan.tencentwelcome.MainActivity  com.example.yaphetshan.tencentwelcome.MainActivity@15a1e11e
...mple.yaphetshan.tencentwelcome on (Google: 5.1) [usb] # android heap execute 0x100462 a

得到调用堆栈以及参数如下:

[./incoming message] ----------------
(agent) [uwhcy5xnh7] Backtrace:
        net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(Native Method)
        com.example.yaphetshan.tencentwelcome.MainActivity.a(MainActivity.java:55)
        com.example.yaphetshan.tencentwelcome.MainActivity.onCreate(MainActivity.java:42)
        android.app.Activity.performCreate(Activity.java:5990)
        android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
        android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
        android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
        android.app.ActivityThread.access$800(ActivityThread.java:151)
        android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        android.os.Handler.dispatchMessage(Handler.java:102)
        android.os.Looper.loop(Looper.java:135)
        android.app.ActivityThread.main(ActivityThread.java:5254)
        java.lang.reflect.Method.invoke(Native Method)
        java.lang.reflect.Method.invoke(Method.java:372)
        com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

- [incoming message] ------------------
{
  "payload": "\u001b[90m[uwhcy5xnh7] \u001b[39mArguments \u001b[32mnet.sqlcipher.database.SQLiteOpenHelper\u001b[39m.\u001b[92mgetWritableDatabase\u001b[39m(\u001b[31mae56f99\u001b[39m)",
  "type""send"
}
- [./incoming message] ----------------
(agent) [uwhcy5xnh7] Arguments net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(ae56f99)

这里获取到的密钥为 :ae56f99。

使用 sqlitebrowser 打开:

拿到FLAG:

使用 base64 解码得到最终结果:

Tctf{H3ll0_Do_Y0u_Lov3_Tenc3nt!}

未标题-1.jpg