sixstartCTF 2018 android writeup

ripples 大佬出的安卓逆向,做起来好坑,瞎搞八搞终于做出来了。时间过去有点久,忘了这题在干嘛了。。。

文件链接:https://github.com/LeadroyaL/attachment_repo/tree/master/sixstar_2018

一、吐槽

先来吐槽一下,代码大量冗余,什么 load 、 loadLibrary 、 stringFromJNI 、 xxx ,没有任何用处而且显然是测试代码。

再吐槽第二点,这个程序根本跑不起来,我换了 N 台手机,全部 crash 而且原因还都不一样,题目给出 hint 是:跑不起来很正常,换台 dalvik 手机,静态分析也够用了。

二、java

java 层没有任何东西,进来就加载了liba.so,声明了多个 native 方法,最后调用了check0(String)这个方法,所以我们进去看liba.so。

三、liba.so

没有init_array。

有JNI_OnLoad,进来先 ptrace (0,0,0,0) 了一下,没有校验返回值,不知道是想干嘛,可能防止后来被 attach 上吧,但似乎没什么鬼用,因为会执行失败。

【插播一个小姿势,android 主进程调用 ptrace(0)时候永远是失败的】

然后用 JNI 绕了一大圈,声明过了 stringFromJNI ,又 registerNative  了这个函数,不知道想干嘛。。。看起来这个函数是用来计算 hash 的,为了校验文件完整性吧。

再用 JNI 绕一大圈,去加载libb.so,然后就退出掉。

再看看 check0(String) ,也是被静态绑定的,逻辑是 JNI直接调用 check0(String),下面看看 check0(String)在哪吧。

四、libb.so

这个 so 的节表被破坏了,先是想找轮子修一下的,但感觉修好以后也没那么好用吧,52pojie 有人写过类似的轮子,姑且能看一下吧。

init_array位于3E30的位置,只有一个函数,在0xED8。

0xED8里有一些 plt 表的东西,静态看我是看不出来的,所以动态调试就用上了,很好到这里适合还没有崩溃,能够下断点,dump 一份libb_runtime.so出来。

先打开 /proc/self/cmdline ,读一下看看和包名是否一致。

再打开libb.so,算一下哈希,存起来,当做 xor_key。这个 hash 可能是假的 hash,似乎反调试哪里被测到了,按理说 liba.so和libb.so的哈希都是 “*ctf”,反正直接给强行赋值过去就对了,同样在其他处引用也是这样的。

之后mprotect,将这段内存标记为 RWX,解出真正的代码,按理说是 JNI_OnLoad  那段。

JNI_OnLoad 里不知道在干嘛,我是动态调试的,所以直接断在了这里,往下走,进来算了liba.so和libb.so的哈希,对比是否相等,看起来预期是相等的,防止篡改。

再检测 tracerPid ,这段跳了,看到快死时候赶紧 set EIP,之后就绑定 check(String)函数了。

check 里面就很简单了,拿到 hash,做个平方,之后和输入数据 xor 一下,就得到密文了。

五、调试细节

首先,必须要断在libb.so的 init_array 里,对 liba.so 其实是不关心的,所以用 ida 打开libb.so,使用调试模式启动 app,断在libb.so的内存修改前。因为我调试时也不知道是如何解密的 shellcode,就直接在执行 shellcode 时候断下来了,后面步骤就比较简单了,主要是要知道在哪下断。

六、赛后交流

和作者大佬交流后,有几个有意思的地方:

问:为什么大部分手机都会 crash?

当时不知道,比较迷。现在看来可能是在check(String)里引起的,tracerPid 预期是与 ppid 相等的,但后来发现 tracerPid 在正常运行时候其实是0,就会主动退出。

问:为什么要绕一大圈去加载libb.so?

写2个 testcass

这两个看起来是没多大区别的,就是调用的位置有点不一样而已,经过大量测试,问题确实在这里。在JNI_OnLoad里加载时就会出现 crash,在 JNI 方法调用时候就可以被正常加载,得到一个初步的结论,JNI_OnLoad 里是不能去主动加载第二个 native shared library 的。具体原因未知,代码写很丑,没看出来。

附作者源码:https://github.com/sixstars/starctf2018/tree/master/re-baby-droid

 


=============================================================
随着访客的增多,LeadroyaL在本站流量的开支越来越多了,曾经1元能用1个月,现在1元只能用3天。如果觉得本文帮到了你,希望能够为服务器的流量稍微打赏一点,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code