通过两道CTF题,来了解和初步掌握smali动态调试的用法
快来跟布布解锁新姿势吧。
1: Ph0en1x-100
题目来自: 攻防世界 mobile 新手练习区
使用APKtool BOX 查壳。发现未加固。
使用Android Killer 打开apk。找到入口。如下图。
然后使用jeb或者jdx-gui打开APK文件查看反汇编过了JAVA代码。(JEB是一款常用于动态调试smali代码的一款软件)我们使用先用jdx-gui打开。然后进到上图所获取的程序入口。分析代码。下图是全文。
通过代码分析,可知,两个主要的方法要在名为:phcm.so文件中加载来获取。
然后继续分析下去,就是简单的if判断了。也是我们做出这道题的关键了。
if的条件就是如果getSecret(getFlag()) 返回的值等于 getSecret(encrypt(this.etFlag.getText().toString())) 就为真。前者getFlag()自己生成一段字符串。后者是读取我们输入的文本转换成字符串然后作为参数传入encrypt()这个方法里面,然后返回字符串又作为参数被getSecret()调用。到此,逻辑就分析完毕了。
由两种解法,一种是使用IDA静态分析SO里面getflag()的逻辑,查看他最后返回的值。而另一种方法就是我们接下来要讲的。动态分析smali代码,直接获取返回的值。
我们先要使APK可调试,我们需要在AndroidManifest.xml文件里添加可以使我们的调式代码的指令。然后保存,反编译回去。笔者使用Android Killer直接 修改 、反编译和安装。
然后打开JEB。加载APK。找到该地方的smali代码。连接手机(笔者为真机,也可在虚拟机上进行调试,都可)打开控制台使用adb指令查看设备是否连接。
如上图,手机已经正常连接。
附加调试
设断点
在手机上随便输入一点东西按GO。
程序开始运行,然后运行到我们设置的断点停下。
讲VM变量区的v1变量改为srting类型
然后按F6单步步入。留意右边变换的值。
运行到此时,v1变量的值出来,也为getflag()返回的值
此为我们需要的密文。此密文等价于encrypt(this.etFlag.getText().toString())返回的值,即此密文,是我们输入的字符串,经过encrypt()加密后的结果,我们使用IDA加载so文件,查看这个函数逻辑伪代码。
我们输入的每个字符都经过 -- 操作,即ASCII 码减去 1得到的密文。所以我们对密文的每一个字符经过 ++ 操作,即ASCII码加上1,即为 我们的原文,也是我们所要的flag。
脚本如下
2: FindPass
题目来自: Jarvis OJ REVERSE
上文步骤已经很详细了,省略一点,我们直入正题。
使用APKtool BOX 查壳。发现未加固。
使用Android killer 找到程序入口,因为我们已经知道了要smali调试代码,(笑)我们可以先在AndroidManifest.xml文件里添加可以使我们的调式代码的指令。保存、反编译、安装。
然后用jax-gui打开,主要逻辑如图
同为if判断。分析后发现也为比较两值得大小。
前者是我们输入的字符串,后者是程序读取一张图片返回字节流然后通过一系列运算存到ekey中。而后者,跟上一道题一样返回的结果也是程序帮我做完了。可以直接通过smali动态调试获取这个返回的结果。
我们直接操作。
JEB附加调试,设置断点
手机随便输入,使程序运行。
jeb上按F6单步步入
查看变量值
笔者改了v4,v5 ,v9的变量类型,最后在v9发现我们想要的值。此即为我们最终的flag
小结
如果你发现,一些与我们解题有关的方法返回值,是程序自己帮你运行算出的,也不用你输入参数,即可动态调试smali来获取这个返回值。