某数字藏品app逆向
字数 1570 2025-08-29 22:41:24
Flutter数字藏品App逆向分析教学文档
一、环境准备
- 测试设备:Pixel 2 (Android 10)
- 目标App:某数字藏品App (版本信息经过编码处理)
- 工具准备:
- Frida (用于动态Hook)
- IDA Pro (用于静态分析)
- Burp Suite/Charles (用于抓包)
- Blutter (Flutter逆向工具)
- wt-js_debug (RSA/AES解密工具)
二、初步分析
1. 抓包分析
首次尝试抓包时发现HTTPS握手失败,表明App存在证书校验机制。可能原因:
- Java层或Native层添加了证书校验
- 使用Flutter框架开发,其网络库自带证书校验
2. Flutter特征确认
解包APK后发现以下Flutter特征文件:
- libapp.so
- libflutter.so
确认App使用Flutter框架开发,因此证书校验可能来自Flutter的网络库。
三、绕过Flutter证书校验
1. 定位关键函数
在libflutter.so中搜索字符串"ssl_client",找到关键函数session_verify_cert_chain。
2. Frida Hook脚本
编写Frida脚本Hook该函数并修改返回值为true:
function hook_ssl_verify_result(address) {
Interceptor.attach(address, {
onLeave: function(retval) {
console.log("Original retval: " + retval);
retval.replace(0x1);
console.log("Modified retval: " + retval);
}
});
}
function hook_ssl() {
var m = Process.getModuleByName("libflutter.so");
var exports = m.enumerateExports();
for (var i = 0; i < exports.length; i++) {
if (exports[i].name.indexOf("session_verify_cert_chain") !== -1) {
console.log("Found session_verify_cert_chain at: " + exports[i].address);
hook_ssl_verify_result(exports[i].address);
return;
}
}
}
setTimeout(hook_ssl, 5000);
使用spawn模式运行Frida,成功绕过证书校验后可以捕获到加密的API响应。
四、加密响应分析
捕获到的响应格式:
{
"data": "加密数据",
"encryptKey": "加密后的AES密钥"
}
加密流程推测
- 客户端和服务端各自生成RSA密钥对,交换公钥
- 服务端生成随机AES密钥(key1)
- 服务端使用key1加密数据得到data1
- 服务端使用客户端公钥加密key1得到key2
- 服务端发送{data1, key2}给客户端
- 客户端使用私钥解密key2得到key1
- 客户端使用key1解密data1得到明文
五、静态分析
1. 使用Blutter导出信息
使用Blutter工具导出Flutter App的信息表,帮助IDA识别函数名。
2. RSA解密函数定位
在IDA中搜索"rsa"相关字符串,定位到疑似RSA解密的函数:
ibox_flutter_cores_util_code_encrypt_utils_EncryptUtils::rsaDecrypt_5c9f54
3. 关键函数分析
发现自定义函数_transformPem,其功能是将PEM格式密钥转换为适合解析的格式。
函数偏移:0x5c0fd4
六、动态Hook获取私钥
1. Frida Hook脚本
Hook _transformPem函数获取私钥:
var base = Module.getBaseAddress("libapp.so");
var transformPem = base.add(0x5c0fd4);
Interceptor.attach(transformPem, {
onLeave: function(retval) {
console.log("Private key: " + retval.readUtf8String());
var file = new File("/sdcard/private_key.pem", "w");
file.write(retval.readUtf8String());
file.flush();
file.close();
}
});
2. 私钥提取
使用hexdump提取私钥:
hexdump -C /sdcard/private_key.pem
七、数据解密
1. 解密encryptKey
使用获取的私钥和wt-js_debug工具解密encryptKey字段,得到AES密钥。
命令示例:
wt-js_debug -d -k private_key.pem -i encryptKey.bin -o aes_key.txt
2. 解密data
使用得到的AES密钥解密data字段,模式为ECB(因响应中无IV字段)。
命令示例:
openssl enc -d -aes-256-ecb -in data.bin -out plaintext.json -K $(cat aes_key.txt | xxd -p -c 256)
八、总结
关键点
- 证书校验绕过:Flutter应用通常通过
session_verify_cert_chain函数实现证书校验 - 加密流程:典型的RSA+AES组合加密,RSA用于加密AES密钥,AES用于加密数据
- 私钥获取:通过Hook PEM转换函数可以获取硬编码的私钥
- 解密顺序:先RSA解密encryptKey,再用得到的AES密钥解密data
防御建议
- 避免在客户端硬编码私钥
- 使用更复杂的密钥保护机制
- 实现动态密钥交换协议
- 增加代码混淆和反调试措施
附录:工具下载
- Blutter: [GitHub仓库]
- wt-js_debug: https://52king.lanzouu.com/iYFe5076yfmf
- Frida: https://frida.re/