某数字藏品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密钥"
}

加密流程推测

  1. 客户端和服务端各自生成RSA密钥对,交换公钥
  2. 服务端生成随机AES密钥(key1)
  3. 服务端使用key1加密数据得到data1
  4. 服务端使用客户端公钥加密key1得到key2
  5. 服务端发送{data1, key2}给客户端
  6. 客户端使用私钥解密key2得到key1
  7. 客户端使用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)

八、总结

关键点

  1. 证书校验绕过:Flutter应用通常通过session_verify_cert_chain函数实现证书校验
  2. 加密流程:典型的RSA+AES组合加密,RSA用于加密AES密钥,AES用于加密数据
  3. 私钥获取:通过Hook PEM转换函数可以获取硬编码的私钥
  4. 解密顺序:先RSA解密encryptKey,再用得到的AES密钥解密data

防御建议

  1. 避免在客户端硬编码私钥
  2. 使用更复杂的密钥保护机制
  3. 实现动态密钥交换协议
  4. 增加代码混淆和反调试措施

附录:工具下载

  • Blutter: [GitHub仓库]
  • wt-js_debug: https://52king.lanzouu.com/iYFe5076yfmf
  • Frida: https://frida.re/
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: 使用spawn模式运行Frida,成功绕过证书校验后可以捕获到加密的API响应。 四、加密响应分析 捕获到的响应格式: 加密流程推测 客户端和服务端各自生成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 函数获取私钥: 2. 私钥提取 使用hexdump提取私钥: 七、数据解密 1. 解密encryptKey 使用获取的私钥和wt-js_ debug工具解密encryptKey字段,得到AES密钥。 命令示例: 2. 解密data 使用得到的AES密钥解密data字段,模式为ECB(因响应中无IV字段)。 命令示例: 八、总结 关键点 证书校验绕过 :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/