Android安全–阿里移动安全挑战赛2014的第二题分析

这次分析是参考大神的步骤来的,主要是为了熟练下IDA的使用。

apk下载地址:http://pan.baidu.com/s/1dD357XZ

一、安装apk文件,打开软件如下:

QQ截图20150913231058

而我们破解的目的就是得到真正的密码。

二、首先使用apktool反编译apk,找到按钮的监听函数,在里面可以看到调用一个check函数来对用户输入进行验证,然后返回结果。

QQ截图20150913231131

而我们看到这个函数申明为native,所以这个函数的处理逻辑是在so中。

QQ截图20150913231159

当然这里的破解不是让你直接改smali的判断条件然后反编译这么简单,我们要把真正的密码找出来。

三、使用IDA打开libcrackme.so,找到securityCheck函数的申明:

QQ截图20150913231236

这里,把v3  按  y  重命名类型为JNIEnv*  ,就可以看到调用了GetStringUTFChars把用户输入的字符串转成char,然后和v6进行比较,相等返回1,否则返回0.那么我们看看v6的值是什么?

QQ截图20150913231307

赶紧把这个密码输进去,,,,然后提示错误。。。

所以并没有这么简单,肯定是在加载so的时候对这个字符串进行了改变,运行的时候这个地方已经变了,所以才不对。

那程序运行后,再附加上去看看这个地址的字符串变成什么了,但是发现一旦附加程序就会退出,所以程序有调试检测的代码。

所以得对.init_array和JNI_OnLoad这两个地方下断点。

QQ截图20150913231355

这里按SHIFT+F7就可以显示段。

QQ截图20150913231438

四、还记得上次http://www.alonemonkey.com/linker-load-so.html这篇文章里面说的,如何在.init_array下断点吧。

首先在.init_array断下来,但是发现执行完.init_array段后,程序并没有退出,继续对JNI_OnLoad下断点,发现每次执行到如下位置后程序就会退出。

QQ截图20150913231516

跟进去看看,原来这里调用了pthread_create函数,因为是在这里创建了线程不断检测调试状态,所以程序一附加就会退出。既然有调试检测,那么肯定会调用fopen,fgets打开进程,并获取进程状态,判断TracerPId的值是不是为0,不为0就是正在调试状态。

接着在fopen的地方下断点,断下来后,查看R0的值:

QQ截图20150913192650

也就是程序开始读取进程的状态了。

然后找到LR,看看是程序的什么地方调用的。

QQ截图20150913192748

这里并看不出汇编代码,只知道地址是:AB672420,减去模块加载地址:AB671000   得到文件偏移:1420

QQ截图20150913231710

也就是这里调用的fopen,查询进程状态的。返回到libcrackme.so继续往下执行,程序接着调用了fgets以及strstr来查找TracerPid的值,虽然我们可以在每次调用的时候去修改TracerPid的值,但是线程在不停的跑,这样是不现实的。

但是发现调用fopen函数的位置在sub_130C这个方法里面,而sub_130C是在这里调用的:

QQ截图20150913202122

直接把这个函数去掉不就行了,找到这个函数的地址000016B8,然后用winhex打开找到二进制代码,把原来的13 FF FF EB改成00 00 A0 E1,因为ARM是没有单独的NOP指令的。于是我们采用movs r0,r0作为NOP。对应的机器码为”00 00 A0 E1”。再来看已经 没有了:

QQ截图20150913202043

改完之后重新保存,回编译,再次签名运行,再附加上去已经没有调试检测了。

五、再次找到原来v6指向的字符串。

QQ截图20150913204206

输入aiyou,bucuoo   验证成功!

 

六、kill大法。

该技巧是QEver 在《MSC的伪解题报告》中提到的。利用kill我们可以让程序挂起,然后用ida挂载上去,获取有用的信息,然后可以再用kill将程序恢复运行。我们还是拿自毁程序密码这个应用举例,具体实行方法如下:

1 首先用ps获取运行的app的pid。

2 然后用kill -19 [pid] 就可以将这个app挂起了。

3 随后我们用ida attach上这个app。因为整个进程都挂起了,所以这次ida挂载后app并没有闪退。然后就可以在内存中找到答案了。

4 如果想要恢复app的运行,需要将ida退出,然后再使用kill -18 [pid]即可。

QQ截图20150913204847

忙活了这么久一个kill搞定, 膜拜大牛!

还有一种比较简单的方法就是,插桩,把_android_log_print函数移到下面,打印v6的值。

本文链接:http://www.alonemonkey.com/ailibaba-crack02.html