解这道题的时候我几乎是刚开始接触安卓逆向,安卓 apk 运行的机制,apk 的文件结构和 ARM 下面的汇编语法等等,甚至逆向一个 apk 的基本思路都不知道。也因为如此,做这道题花了将近两天时间,在此过程中还看了其他朋友的解题思路,最后终于求得 flag。但即使如此,还是有很多地方没有搞明白,所以这篇 wp 讲的是主要的解题思路,不会深入讲解(我自己还不是太明白)。

(以下都是文字,没有贴图,可能有点枯燥,抱歉~)

以下为程序验证流程分析:

1、用 Android Killer 打开 apk,发现加载了 libeasy.so 文件,如果 func 函数返回值为真,则说明输入正确的验证码,并且该验证码即为 flag。

2、func 函数以及其他验证过程的实现位于 libeasy.so 文件中,因此用 IDA 打开该文件分析。但是在该文件中并没有发现 func 函数,观看其它朋友解题思路后发现主要函数是 cxa_begin_match() 函数。

3、实验吧里面的题目似乎是少了一个提示,在 SCTF 中有一个提示是「Hint:反调试、关键点在init段」。在 init 段发现有一个 _cxa_chk_fail() 函数。分析该函数后发现该函数的主要功能是调用 sub_1A74() 函数给 tempabc 和 m_y 这两个全局变量(是全局变量?不熟悉 java 语法,不敢确定)赋值,结果是 tempabc = "syc",m_y = 6 或者 tempabc = "xctf",m_y = 9(实际解题过程中发现 tempabc = "syc",m_y = 6,但为什么选这一组值我还没有弄明白)。

4、话题回到 cxa_begin_match()。调用 gun_arm_fini_29() 函数获取输入的验证码,验证码首先和对应的 下标+1 做异或运算。

5、然后在 imp_Unwind_k() 函数中依据 m_y (值为 6)的大小进行移位操作,并将处理后的验证码存放到 tempstr 中。在该函数前面有一段代码,应该是反调试的,静态分析就不理会了哈。

6、接着在 gun_armfini_33() 函数中依据 tempabc 字符串中的数据(实际上是 "syc")对验证码中的英文字母进行运算,其它字符不做更改,并将处理过的验证码存放到 s 中。运算结束后在 gun_armfini_33() 的返回处调用了 imp_Unwind_j() 函数判断经过上面处理过后的验证码的前 11 个字节是否为 "GoodCracK3R"(该字符串并不是直接给出,而是分析得出)。

7、gun_armfini_33() 出来后,回到 cxa_begin_match(),取 v21,即验证码第 11 个字节之后的剩余字符(即验证码中 "GoodCracK3R" 后面的剩余字符)存放到 dest 中,取 src,及第 9、10、11 共三个字符存放到 seed 中(由 "GoodCracK3R" 可知,此三个字符即为 'K', '3', 'R')。

8、然后进入 gun_armfini_21() 函数。在该函数中首先调用 gun_armfini_23() 函数,依据 seed 中的数据对一个长度为 260 的字符串 v8 赋值。

9、接着调用 gun_armfini_36() 函数依据 v8 字符串中的数据对 dest 字符串中的数据做运算。

10、经过以上运算后,回到 cxa_begin_match(),得到的 dest 字符串中的数据以 %x 十六进制的形式打印到 v18 字符串中,然后调用 gun_arm_ldiv0() 函数,在该函数中将 v18 指向的字符串与 "a8e5588f7e3f758" (简单的减法运算得来,并不直接给出)作比较。

7、如果第四步中验证码前 11 个字节与 "GoodCracK3R" 相等并且 v18 与 "a8e5588f7e3f758" 相等,则说明输入的验证码正确,该验证码即为正确的 flag。

以下为求解思路:

1、依据 "a8e5588f7e3f758" 作 gun_armfini_21() 函数的逆运算得到 dest 字符串。

2、将 dest 字符串连接在 "GoodCracK3R" 后面,达到长度为 19  的对英文字母处理过的验证码。

3、将该验证码作 gun_armfini_33() 函数的逆运算得到移位后的验证码。

4、将移位后的验证码作 imp_Unwind_k() 函数的逆运算得到与下标值异或后的验证码。

5、将验证码与 下标+1 做异或运算,得到正确的输入验证码,也即得到 flag。

注意:

1、"a8e5588f7e3f758" 对应过来的字符串应该是 { 0xa8, 0xe5, 0x58, 0x8f, 0x7e, 0x3, 0xf7, 0x58 } 而不是 { 0xa8, 0xe5, 0x58, 0x8f, 0x7e, 0x3f, 0x75, 0x8 },这个感觉好坑啊,在这里错了好久。

2、要耐心,要耐心,要耐心,越菜越要耐心,不能放弃

(以上说明如有错误,请指正,谢谢)
Flag:

温馨提示: 此处内容需要评论本文后刷新才能查看,支付2元即可直接查看所有Flag。

小广告:关于获取西普实验吧所有Writeup请点击这里查看索引

查看所有Flag需要付费,需要获取所有Flag的童鞋请访问这里成为付费用户,可以自助把自己的注册邮箱加入网站白名单,即可免回复看到本站所有Flag

Flag大全地址:所有Flag

PS:本站不是实验吧的官方站点,纯粹是个人博客,收取Flag费用仅是维持服务器费用,做站不易,且行窃珍惜,如果喜欢我的博客,愿意捐赠的,可以扫描下面的二维码

微信二维码:
支付宝二维码: