当前位置:首页>安卓APP>CTF安卓逆向:ill-intentions

CTF安卓逆向:ill-intentions

  • 2026-09-03 19:31:21
CTF安卓逆向:ill-intentions

CTF安卓逆向:ill-intentions

1

Java层分析

1.1.首先,我们使用Jadx(或Jeb)打开APK,查看MainActivity的代码。

程序加载了native库native-lib。

定义了一个native方法CheckFlag,接收两个字符串参数(用户输入的flag和从assets读取的encflag),返回一个字符串。

点击按钮时,读取用户输入和assets下的Flag文件,调用CheckFlag进行验证,结果显示在TextView上。

1.2提取assets/Flag文件,得到encflag为:

Ku@'G_V9v(yGS

2

Native层分析

2.1.将APK解压,在lib/armeabi目录下找到libnative-lib.so,用IDA Pro打开

在IDA中搜索JNI_OnLoad函数,发现动态注册的代码:

2.2.查看动态注册表

双击off_4004,查看JNINativeMethod结构:

可以看到,CheckFlag方法实际绑定到了sub_DC8+1函数(Thumb模式)。而IDA中还有一个静态注册的函数Java_monkeylord_illusion_MainActivity_CheckFlag,这是一个常见的干扰项,真正的逻辑在动态注册的函数中。

2.3.分析真正的CheckFlag函数

双击sub_DC8,按F5生成伪代码:

函数将用户输入的字符串s和encflag字符串s2转换为C字符串。

对s的每个字符,进行运算:s[i]加上密钥字符串aLjavaLangStrin_0[i],减去64,然后调用sub_10C0,结果右移32位,再加32,得到加密后的字符。

最后比较加密后的字符串与s2(encflag),返回相应结果。

2.4.密钥字符串

双击aLjavaLangStrin_0,发现它指向一个长字符串:

这就是JNI方法签名,也是我们加密使用的密钥。由于encflag长度为13,我们只需要前13个字符作为密钥,即:"(Ljava/lang/S"。

2.5.加密算法分析

进一步分析sub_10C0函数,发现它是__aeabi_idivmod,即整数除法和取模运算。结合伪代码中的右移32位,实际上取的是除法的余数(ARM中__aeabi_idivmod返回的64位值高32位是余数,低32位是商)。

因此,加密算法可以简化为:

encrypted[i] = ( (flag[i] + key[i] - 64) % 93 ) + 32

3

解密算法推导

E - 32 = (F + K - 64) % 93

设 X = F + K - 64,则 X % 93 = E - 32
因此 X ≡ (E - 32) (mod 93)
又因为 X = F + K - 64,所以 F ≡ (E - 32) + 64 - K (mod 93)
即 F = ((E - 32) + 64 - K) % 93 + 93 * k,其中k为整数。
由于F是可打印字符(ASCII 32-126),k只能为0或1(因为93*2=186>126)。我们可以枚举k,选择在可打印范围内的字符。

4

编写Python脚本

4.1.Python脚本

enc_flag = "Ku@'G_V9v(yGS"data = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"data = [ord(i) for i in data]def main():    enc = [ord(i) for i in enc_flag]    flag = [0]*len(enc)    for i in range(len(enc)):        flag[i] = (enc[i]-32)+64-data[i]        while flag[i] < 0x32:            flag[i] += 93        while flag[i] > 125:            flag[i] -= 93    print("".join([chr(i) for i in flag]))if __name__ == '__main__':    main()
将encflag和密钥字符串转换为ASCII值列表。
对每个位置,计算(enc[i]-32) + 64 - key[i],这是从加密公式推导出的基础值。
由于模运算,实际值可能需要在基础值上加减93的倍数。我们通过两个while循环将结果调整到可打印字符范围(32-125)。
最后将ASCII值转换回字符,得到flag。
CISCN{GJ5728}

END

文章都看完了,还不点个赞

历史文章

SQL注入靶场显错注入(一)

LeakDetector自动化信息泄露侦察工具

CTF安卓逆向:ill-intentions

CTF安卓逆向:boomshakalaka-3

CTF安卓逆向:人民的名义-抓捕赵德汉1-200

Sunny网络中间件

JAVA代码审计:鉴权漏洞深度分析

你不知道的表网、深网与暗网世界

最新文章

随机文章