手把手教你逆向Flutter App
有个朋友说,看了一个 app,刚开始抓包只能抓一部分,参考了我的这篇文章,用了 HttpToolkit 工具,可以抓到所有的包了。但是接口中有个加密字段,反编译 app 后却看不到这个加密字段内容是怎么生成的!让我帮忙看下,于是就有了这篇文章。
- 样本:x彩云 6.2.3
1、使用HttpToolkit抓包
为了不浪费时间,就直接用HttpToolkit来抓 目标 app 的数据,抓到的数据如下
从上图中可以看到有个sign
字段,字段的内容长度是 32 位,应该是 MD5 签名。
2、分析 sign
想知道是对什么内容签名有几个方法:
- 使用算法助手 app
- 使用
Frida
Hook MD5 签名。 - 自己扒拉 app 代码,找到签名部分,具体分析。
方法 1 只能获取 jvm 层的签名,native 层的就获取不到了。方法 2 即可以 hook jvm 层的方法,也可以 hook native 层的,hook jvm 层只需要 hook md5 的签名方法就可以,就是**MessageDigest**
这个类中的方法,hook so 的话就要看 so 的代码,找到目标方法进行 hook 了。方法 3 是个体力活,当你想分析 app 的业务的时候可以用这个方法。
方法 1 和方法 2 中获取 jvm 层的 MD5 签名,原理上大同小异,都是 Hook **MessageDigest**
**这个类中的方法,**为了使用方便,就直接用算法助手
来查看 MD5 签名的内容。查了下算法助手 Hook 的结果,并没有 sign
字段的内容。这就说明 MD5 签名是在 so 中了。
这时就需要查看 app 代码,找到是目标 so,然后用 IDA 查看。我习惯用 MT 文件管理器
打开 样本 app,发现没有加固,直接可以查看 dex,然后搜索关键字 sign
,结果如下
结果有 11 个,与样本有关的就一个,看下代码
从这段代码中可以发现两个信息:
- 样本 app 中有 flutter 代码。
sign
字段的内容,可能是这个JcSigner.sign
生成的。
现在验证下 2,找到 sign
方法,代码如下
从图中可以看出sign
是 JNI 方法,也可以知道这个 so 的名字是libcommon_lib.so
,
直接用算法助手来 hook 这个类
重新请求下数据
sign 的内容为b187545bb291cddff2aa2b3ecc59c1c1
,到算法助手中看下
JcSigner.sign
方法生成的返回值正是接口中sign
的内容。
这时又有新的问题,绿色框内的也是一个 MD5 签名,由上文代码可知,这个MD5 签名来自 Flutter 代码。
到这里就正式到了本文的重点 Flutter编写的 app如何逆向?
3、Flutter 逆向
利用 Flutter 框架开发的 app,打包后,会将代码打包成 so,而且会将接口请求添加证书校验,防止中间人攻击,普通方法是抓不到包的。无形中增加了逆向的难度,说句题外话,用 Flutter 框架开发,不仅可以跨平台,还增加了安全性👍。
Flutter 框架开发的项目,打包后会生成两个 so,分别是 libapp.so
和 libflutter.so
,前者是业务相关的,后者是 Flutter 引擎用到的。
用 IDA 打开libapp.so
,会发现函数名都被混淆了,这时就要借助开源框架B(l)utter来还原混淆的函数名了。
3.1、使用B(l)utter还原函数名
B(l)utter官网有安装和使用方法,Linux、windows 和 mac 都行 我三个平台试了,最后只在 Linux 上成功,我的环境是
- ubuntu 22.04
- gcc version: 13.1.0
- 先 clone 下 blutter 的项目必须加 --depth=1
git clone https://github.com/worawit/blutter --depth=1
2. 按官方教程,先执行一下命令安装依赖
apt install python3-pyelftools python3-requests git cmake ninja-build \
build-essential pkg-config libicu-dev libcapstone-dev
- 然后运行blutter.py并提供libapp.so和libflutter.so的文件夹路径以及输出文件夹路径
等待执行完成,完成后输出文件夹目录如下
随后我们用ida反编译libapp.so,并运行输出文件夹中的IDApython脚本ida_script/addNames.py
,符号就被全部恢复出来啦
搜索一下,看有没有与 md5
相关的函数
果然有,这几个函数应该都与生成 MD5 签名有关,根据函数名称来猜测,应该是flutter_mogu$network$CommonUtil_CommonUtil__generateMd5_7ca1ac
函数与原文有关,那就验证下。
3.2、还原MD5签名
打开blutter_frida.js
文件,修改代码如下
这里的7ca1ac
就是native 函数的地址。执行下面的命令
# com.xxx.xxx 换成应用包名
frida -U -f com.xxx.xxx -l blutter_frida.js
重新抓包
再看下算法助手 hook 的值
再看下 Frida Hook 的值
验证下红框内的内容的MD5 签名
可以发现,刚好是算法助手绿框内的值,所以 Flutter 中的 MD5 签名是原文加盐得到的,盐就是wl@3f8a&316
,搞定收工。
3.3、余下工作
到这里还没完,现在只是知道了 Flutter 中的 MD5 签名,还不知道 sign 是怎么生成的,感兴趣的自己研究下。
说下答案,sign
的盐值,见下图
4、总结
目前为止,网上应该有很少逆向 Flutter 的教程,有的话,一般也是利用 reFlutter来的,但是这个 apk 太老了,现在已经不行了。还是推荐使用 Blutter
来做 Flutter 的逆向,在使用这个库的时候,唯一遇到的问题就是编译出错,如果你也遇到这个问题,并且解决不了的话,可以加我一起讨论。
本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系。
本文涉及到的代码项目可以去 爱码者说 知识星球自取,欢迎加入知识星球一起学习探讨技术。 关注公众号 爱码者说 及时获取最新推送文章。
转载自:https://juejin.cn/post/7376231612441395239