考察知识点
- hook 系统函数
- dump 内存搜索 flag
赛题链接
https://github.com/eternalsakura/ctf_pwn/blob/master/android逆向/EasyRe.apk
分析
java层
用jadx反编译apk,在java层的逻辑很简单。
读取flag.txt这个文件的内容,然后和我们的输入数据相对比,如果一致就提示“That’s the flag!”
找一下这个文件,0ctf{Too_Simple_Sometimes_Naive!!!}
不出意外是个假flag。
提示一下,请不要用模拟器打开去输入flag,那你会输出That’s the flag!
究其原因是因为模拟器都是用的x86去模拟arm,而这里动的手脚是在so文件里,所以请用真机测试。
so层分析
我们推测应该是在apk运行前做了什么操作,找到so文件用IDA打开
so文件里没有JNI_Onload函数,找到.init_array段,调用了my_init函数
打开后F5反编译,发现CheckSig和j_hook函数,推测做了签名验证反调试和对系统函数进行hook。
并且根据传入的参数判断应该是hook的read函数。
解题
http://www.purpleroc.com/MD/2015-03-31@0CTF_WriteUp.html
http://ipushino.blogspot.de/2015/04/0ops-ctf-qualifiers-2015-simpleapk.html
github上面给出的两篇wp都没有分析代码,而是在内存中搜索字符串。
我翻了翻代码看不太懂,就先学习一下这种姿势。
dump 内存搜索 flag
利用 ddms 的 dump HPROF file 功能 (带箭头的油桶图标)
然后搜索字符串:strings easyre.sjl.gossip.easyre.hprof | grep 0ctf
flag得到:0ctf{It’s_More_Than_Meets_The_Eye!}
利用 gore
gdb下载
Android NDK 在 r11 之后去掉了 toolchain 中的 gdb 工具,所以我下载了r10 的.(整包下载,只有gdbserver和gdb会报bug),就像下图这样。
将gdbserver放入手机并添加执行权限
adb push gdbserver /data/local/tmp
查找要dump的应用的pid
ps | grep 名字
启动gdbserver,指定监听端口
./gdbserver :1234 --attach pid
1234可随意指定
转发端口并调试
1 | adb forward tcp:1234 tcp:1234 |
gore dump 出内存后,搜索字符串
strings core.xxx | grep xxx
总结
dump出内存的第一种方法比第二种要快速高效一些。
另外,在我测试的时候,在不进行任何输入的时候,搜索字符串是搜索不到真正的flag的。
click前:
click后(随便输个123456):
这也验证了确实是hook了read函数,把从flag.txt读取的字符串进行了某种变换,得到0ctf{It’s_More_Than_Meets_The_Eye!}在内存中。