Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

2015移动安全挑战赛(阿里&看雪主办)全程回顾(2)

0x1 分析

APK界面

题目下载

本次比赛的第二个题目仍然是一个独立的APK文件,安装后,需要用户输入特定的密码,输入正确会显示成功。第二题APK在Java层代码中并没有关键逻辑,将用户输入直接传给native so层中securityCheck这个native method(securityCheck方法在libcrackme.so中),由native code来决定返回正确与否。

用IDA工具打开libcrackme.so,首先看下程序的大致流程,可以看到在securityCheck这个方法调用前,在init_array段和JNI_Onload函数里程序都做了些处理,而在securityCheck方法的最后有一个判断,将用户输入和wojiushidaan做比较。尝试直接输入wojiushidaan,发现密码错误,因此可以猜测前面一大段逻辑的作用就是会把这个最终的字符串改掉。此时的思路是只需知道最终判断时候这个wojiushidaan地址上的变换后的值就行了。尝试使用IDA调试发现一旦attach上去,整个程序就退出,想必一定是在之前的代码中有反调试的代码。

0x2 巧妙的解法

同上一题一样,我们提供一种非常巧妙的解法:

注意到在最终比较之前,程序使用了android_log_print函数,当我们直接运行程序时,发现这里固定输出了

I/yaotong ( XXX): SecurityCheck Started...

这时候我们想,是否可以直接patch这个libcrackme.so,修改打印的内容,直接利用这个函数帮我们输出此时真正需要比较的值。

我们选择patch的方法是直接把这个log函数往下移,因为在0x12A4地址处正好有我们需要的打印的数据地址赋值给了R2寄存器(本来是为了给后面做比较用的),因此将代码段从0x1284到0x129C的地方都用NOP改写,在0x12AC的地方调用log函数,同时为了不影响R1的值,把0x12A0处的R1改成R3。

下面是对比patch前和patch后的图:

Patch前代码

Patch后代码

参考视频给出了完整的解决过程:

通过观察Logcat输出可知,最终密码为:

aiyou,bucuoo