某数字藏品app逆向
北海 移动安全 317浏览 · 2025-04-01 10:39

本文仅用于技术交流学习



前言

环境: pixel2 android10

app: 5pWw5a2X5Y6{beihai_delete}f55SfYXBrIDEuMS43I{beihai_delete}GNvbS5pemVuLmFiYw==



正文

抓包

打开app,随手抓一个包,发现握手失效了。说明证书出了问题,第一时间想到了证书校验。要么这个app是在java或者native层加入了证书校验机制,要么是这个app通信使用的是flutter开发的通信部分。flutter框架使用的网络请求库具有证书校验机制

image.png


打开apk包看一下,发现了flutter的特征libapp.so和libflutter.so

image.png


使用脚本来绕过flutter的证书校验

先找到session_verify_cert_chain函数偏移

反编译libflutter.so,进入字串视图

image.png


通过字符串ssl_client定位session_verify_cert_chain

image.png




编写脚本hook住session_verify_cert_chain修改其返回值为true即可,脚本如下:

spawn模式运行

image.png


成功抓到包了,可以看见返回包里面有data和encryptKey两个字段。data大概是加密后的返回数据,encryptKey则应该是加密后的key

image.png




算法分析

市面上有部分app的返回包就是这种data和encryptKey的形式

app接收返回包后的工作是,app会用内置的算法1解密encryptKey字段的值得到key,然后使用算法2和key解密data得到明文

这里面的算法1和算法2很常见的就是rsa和aes,并且aes应该是ecb模式的,因为返回包中并没有加密的iv字段

对于使用rsa结合aes的情况,服务端给客户端传输数据的大概流程如下:

客户端和服务端均生成一对RSA秘钥,私钥各自保管,公钥给对方;

服务端使用随机函数生成AES加密要用的秘钥key1;

服务端使用key1对要传输的数据进行AES加密,生成data1;

服务端使用客户端给的公钥对key1进行RSA加密,生成key2;

服务端将data1和key2一起发给客户端;

客户端拿到数据后,先使用自己的私钥对key2进行RSA解密,得到服务端生成的随机秘钥key1,再使用key1对data1进行AES解密就得到真实的数据了。



带着上面的猜测来看看反编译代码



对于flutter app,先要掏出blutter来导出信息表

image.png


ida导入output/ida_script/addNames.py

image.png




导入后就可以看到不少函数有函数名了

搜索一些rsa,找到了疑似rsa解密的函数

image.png


在函数ibox_flutter_cores_util_code_encrypt_utils_EncryptUtils::rsaDecrypt_5c9f54中有不少dart官方库的影子

下面将图中部分反编译代码和flutter正向开发的代码对应

在dart的encrypt库的api中没有找到_transformPem,说明_transformPem应该是自定义的函数

根据上下文和函数名,可以猜测_transformPem是用于将PEM格式的密钥字符串转换为适合解析的格式

那么里面的返回值就是rsa的解密密钥,hook这个函数,dump它的返回值

_transformPem的偏移为0x5c0fd4,hook代码如下:

attach模式运行,成功打印出private key

image.png




先用hexdump把私钥提取出来

image.png


使用wt-js_debug解密得到aes的密钥

工具地址:https://52king.lanzouu.com/iYFe5076yfmf

image.png






再用aes密钥解密data密文

image.png




尝试使用ecb模式解密,成功得到data明文

image.png




0 条评论
某人
表情
可输入 255

没有评论

目录