本帖最后由 Mint_Grass 于 2023-12-02 10:12 编辑
首先就是最常见的直接把apk拖入jadx,发现两个native函数,打开ida 很显然是动态注册,查看jni_onload,看这个架势是有混淆的,不过还能看 先看一下init,发现有四个函数,一个一个看,第一个是在往.bss区域塞数据(劝退点:什么是bss区域) 第二个是函数像是在换表 看看第三个,看着也是在初始化 最后是第四个,看这个图片有经验的就知道估计是反调试。。。别问为什么,要问就问自己为什么不知道一路跟进去虽然有混淆。但是逻辑还是比较简单的。 就是简单的一个strstr检测frida的反调试,所以直接hook libso里面的strstr函数就行了 看完init段就该看正文了,先使用frida直接过了反调试,后面很多字段就可以直接hook出来,我hook了几个给大家看看,至于动态注册的流程我就不赘述了, 可能会有很多新手,会发现明明用到了v12,v13怎么注册的时候只有v11.这是因为,他们在一个栈上,而且是连续的。混淆的时候经常会出现这种情况,打pwn的选手应该会对这个非常熟悉,是的这又是一个劝退点 接着往下看,很显然sub_35A4就是我们要找的CheckUsername的地址,直接进入函数,一大堆蛇皮混淆,这种情况下,最好的办法就是直接倒着看,有个memcmp函数,那么很显然这个username应该是写死的。那么逻辑应该就是先加密完然后再与写定的值进行比较。如此一来那么sub_6C2C就相当可疑。自己可以尝试查看一下sub_6C2C参数的交叉引用,你会发现这个最核心的逻辑就在这个函数上。 进入sub_6C2C函数后,一看就是rc4算法,明晃晃的256,看不出来的可以劝退。用CyberChef测试过后,带入app发现不对,还是return false。是的能解出来值,但是不对,好像被魔改了。。如果对rc4算法有研究的估计一眼就看出来,看不出来也可以用土办法。你已经知道账号的位数了,是10位的,那么自己传10个1,进去然后和正经算法做个对比就知道是多了一层异或。真正出问题的地方在于这里。 他多异或了一层下标于是我们可以获得账号Re_1s_eaSy根据java层的逻辑走,我们可以发现x = Re_1s_eaSy123456但是这个完全没有交叉引用,这就很奇怪 先把这个放一边,去看check2函数sub_3F0C,拉到最下面,熟悉的memcmp函数,一般当username写死了,那么密码一般也是写死的, 当然了不排除使用timestamp当随机变量的。这种在实战中非常常见。如果使用timestamp当作随机变量再加上强一点的混淆,这道题目就会变难不少。仔细看的话很容易就看出来了这个密码最后加密出来是16位的,而且通过交叉引用一路往上跟踪,就可以获得从native层调用这个x的流程。 首先需要判断这个是什么算法。最开始我们发现了一个s盒修改的点,这是一个由256个元素的s盒,外加密钥Re_1s_eaSy123456也是凑足了128位的长度, 容易联想到的就是aes换了s盒,如果结果尝试出来不行,那么只能硬着头皮继续分析,比较幸运的是,这题就到此为止了。总的来说感觉这题考察的点还是相当多的,动态注册,反调试,代码混淆,算法魔改。就一般实战的原生安卓app如果不是特别牛逼的大厂或者企业级加固也就差不多这样了,最多就弄个防抓包。而且实战中rc4用的其实不怎么多(不知道为啥ctf总喜欢弄两个rc4),aes还是不少的,换表可以注意一下。注:若转载请注明大神论坛来源(本贴地址)与作者信息。
下方隐藏内容为本帖所有文件或源码下载链接:
游客你好,如果您要查看本帖隐藏链接需要登录才能查看,
请先登录
|