前言
全程划水的我还是要跟着大哥混才有饭吃
开干
题目首先给了一个 Android APK,应用名为where is flag
,包名为com.example.iscc.whereisflag
,下载下来安装先看看:
图中只有一个 GetFlag 按钮,点击之后会弹出一个flag {you can do it 666}
的 Toast,很明显不是我们需要的东西,直接上apktool
:
解包之后,按照之前做题的经验,res
目录里面可能会有东西,果不其然:app-release/res/values/strings.xml
文件中:
找到了一个被分成了三段的base64编码:RmxhZyU3QllvdXJBcmVDYW5keQ==
,解出来是:Flag{YourAreCandy
接下来开始寻找第二部分,使用 JEB 直接打开 APK:
APK 并没有做混淆,直接跟进 MainActivity
,右键单击它并将 smali 代码转为 Java 代码:
可以看到按钮的 onCreate
事件中会先调用上面的 Check 函数检测 Flag 是否正确,如果不正确就输出 666 那串字符。经过分析得出:
- 文本长必须为偶数
- 将文本按照奇偶数拆分为两组
- 所有字符串的ASCII相加起来不能大于800,否则报错
- 把偶数组的第一位和最后一位调换
- 奇数位ASCII小于91 偶数位ascii大于96
- 奇数位 倒数第一位和倒数第二位必须相等
- 奇数位[1] - 奇数位[0] == 4
- 偶数位[0] - 偶数位[1] == 4
- 奇数位[0]和倒数第二位的差值必须为 4
- 偶数位[0]必须被 25 整除
- (奇数位[3] + 偶数位[3] + 偶数位[2]) / (奇数位[0] + 奇数位[1]) = 2
- 奇数位[2] + 偶数位[1] 必须被 10 整除
- 偶数位的第二和第三位都必须被 11 整除
由于前半段 Flag 已经拿到,所以可以确定该 Flag 的最后一位是 },花括号的 ASCII 值为 125,所以有以下推导:
若偶数位最后一位是 },根据第八条规律(偶数位[0] - 偶数位[1] == 4),125-121=4,121 对应的 ASCII 是小写字母 y,所以偶数倒数第二位为字母 y
设奇数位第一位为N,那么奇数位第二位为 N+4,第三位为 N-4,根据规则第三位和第四位必须相同。所以我们得到:
1 | 奇数位数组: |
1 | 偶数位数组: |
于是我们可以大致推测出后半段的部分是 ?????y?}
,自己写了个 Python 脚本指定 ASCII 进行爆破,得到结果:
1 | flag is +c/y'y'} |
最后发现倒数第四条是正确的flag,拼接得到:Flag{YourAreCandyInMyEyE}