VNCTF2025 逆向kotlindroid wp
字数 1341 2025-08-29 08:30:24
Kotlin Android逆向分析:VNCTF2025逆向题解
题目概述
这是一个使用Kotlin编写的Android逆向题目,主要考察对Kotlin编译后的代码分析、AES-GCM加密算法的理解以及JNI本地代码的分析能力。
关键保护机制
- ProGuard保护:编译时启用了ProGuard进行混淆
- SO符号保留:保留了native库的符号信息
分析工具
- Jadx:反编译有问题
- JEB:成功反编译出关键逻辑
- Frida/动态调试:可用于获取运行时数据
- 静态分析:适用于native库分析
关键加密信息
- 加密算法:AES-GCM模式
- IV(初始化向量):
114514 - 密文:
MTE0NTE0HMuJKLOW1BqCAi2MxpHYjGjpPq82XXQ/jgx5WYrZ2MV53a9xjQVbRaVdRiXFrSn6EcQPzA== - Tag长度:128位(通过
getGCMParameterSpec设置)
密钥获取
在Button事件处理中传递了两个数组,通过异或运算得到AES密钥:
atrikeyssyekirta
JNI部分分析
关键函数
-
sec函数:- 调用JNI类获取数组
arr_b1作为add值 - 最终生成的密文放在IV后面
- 调用JNI类获取数组
-
native_natget本地方法:- 传入参数:
new byte[]{0x7B, 0x71, 109, 99, 97, 0x7A, 0x7C, 105} - 返回
add值(每次调用返回相同)
- 传入参数:
Native代码分析
- 符号保留:由于保留了符号,可以直接搜索
native_natget函数 - 参数传递:
- 传入3个参数,最后一个是我们提供的数组
- 初始化传入的数组并创建实例入栈
- 本地数据:
01 1f 09 11 15 1f 0e 0a 17
加密循环逻辑
-
两个关键异或操作:
Kotlin_ByteArray_get(x0_43, 8 s% x0_45)):取本地数据第9个字节0x17x0_42:循环取前8位x0_37:取初始化的传入数组实例
-
解密
mysecret:- 根据上述逻辑可以解出
mysecret - 后续函数在
mysecret后追加add字符串,返回给Java层
- 根据上述逻辑可以解出
解密步骤总结
- 获取AES密钥:
atrikeyssyekirta - 获取IV:
114514 - 获取密文:
MTE0NTE0HMuJKLOW1BqCAi2MxpHYjGjpPq82XXQ/jgx5WYrZ2MV53a9xjQVbRaVdRiXFrSn6EcQPzA== - 使用AES-GCM模式解密(Tag长度128位)
静态分析技巧
- 对于Kotlin编译的SO库,保留符号时可以直接搜索关键函数
- 注意Kotlin特有的数据结构和方法调用方式
- 关注数组操作和循环逻辑,特别是异或等位运算
动态调试技巧
- 使用Frida hook关键JNI方法获取参数和返回值
- 动态调试可以获取
add值的实际内容 - 监控加密过程中的中间值变化
完整解密流程
- 分析Java层获取加密参数
- 逆向JNI部分获取
add值 - 组合所有参数进行AES-GCM解密
- 验证解密结果
通过以上步骤,可以完整还原题目的加密逻辑并成功解密出原始数据。