这道题是iscc 2017中的安卓第二题,所有的算法都在lib库中,而lib库又是加了壳的,所以就用动态调试解决吧。第一次动态调试安卓,就写的详细一些吧。
文中用到
1.能正常运行这个crackme的手机一部,需要root(本人手上的主力机是安卓7.1的就运行不了)
2.IDA一个
3.IDA神级插件Keypatch
4.安卓调试adb
5.python
6.这个crackme
题目链接
链接:http://pan.baidu.com/s/1kVLYYOJ 密码:e2tj
解析
准备
首先在手机上安装这个crackme,这个不需要多说。
通过jeb的逆向,发现所有与题目解题相关的代码都在libtutu.so中。ida直接载入会发现这个so是被加密的。
那就开始动态调试。
在ida的目录下有一个叫dbgsrv的文件夹
此次我们动态调试所需要的是android_server。
通过各种方法,把它放到/system/bin/
目录下,并给予执行权限
然后在电脑上执行adb shell
,输入su
拿到root权限后再输入andoird_server
。
看到Listening on port #23946...
再开一个命令行窗口,输入 adb forward tcp:23946 tcp:23946
进行端口转发。
至此,准备工作就完成了。
IDA连接调试
在手机端打开待调试的crackme
在x86的ida下,选择如下菜单
点击OK。
找到待调试的应用:
点击OK,等待片刻后进入调试界面。
由于要等待so解密,所以我们打开这一项
勾上这里
点击运行让程序跑起来。
手机端随便输入一些东西后点击确定,发现IDA成功断下。
出现这个直接点OK跳过
直接apply
断在linker
手动按f8从linker走到libart.so(我调试用的手机是安卓5.1的)
在Modules里找到libtutu.so
双击check
发现代码已经解密了。
可以按F5看看
一切正常。
方法一:静态分析
这些明显是函数指针,我们双击过去,按c
转换成代码,再回来按f5。
上面有个未知作用的函数,我们一层层点进去看,发现是strlen。
稍微重命名一下,我们可以看出就是一个AES_ECB模式的加密
IV和enc都有了,直接用python解密一下就出来了。
123456789 |
from Crypto.Cipher import AESiv = '122B157F2BAED2A6ACF7158807CF4F3C'.decode('hex')enc = '47FE6CEEA092F9A72A73B3763613701A'.decode('hex') cryptor = AES.new(iv,AES.MODE_ECB)dec = cryptor.decrypt(enc) print dec |
flag:6ae379eaf3ccada5
方法二:纯动态调试
既然都已经开始动态调试了,为什么还要劳烦我们去分析代码呢?总有人会这样想。
也算是锻炼一下动态的能力,我们现在用纯动态的方法来做。
首先,如果你脱完壳直接f9开跑的话,你会发现程序结束了,因为这个so里有一个叫做antiDebug的函数
我们不用去管这个函数内部到底干了什么,我们只要直接将这个函数在段首ret掉,这样下面的所有代码都不会被执行了。
我们掏出插件keypatch,ctrl+alt+k
改成POP {R4-R7,PC}
这样这个antiDebug就被patch掉了。
我们还发现这个so中自带了decrypt函数。
我们来到check函数,找到这一段。
我们要把原来的AES128_ECB_encrypt)(input, &IV, &enc_out)
改成AES128_ECB_decrypt)(enc_right, &IV, &enc_out)
,这样enc_out里保存的就是我们所需要的flag了。
这里,我们发现我们需要的enc_right保存在R6寄存器里
所以我们patch这两句
重新f5,现在变成了我们所希望的样子
用f2下好断点,f9运行
enc_out是在R7寄存器里,此时的R7为FFABD2A4
在数据窗口我们按G键,跳转到FFABD2A4
成功得到flag:6ae379eaf3ccada5
总结
作为第一次安卓动态调试,很多地方还做的很生疏,但收获也是很多的。
原文地址:https://www.cnblogs.com/sanxiandoupi/p/11643460.html