背景

ShadowShare 是一个共享节点的 APP,使用 flutter 开发。

我想把它的数据接口提取出来。经过抓包发现它的节点数据都存储在 gitee,下载下来后发现数据都加密了,看样子像是 AES 系列的。

使用算法助手 Pro 对它进行 Hook,但是未得到任何有用信息。猜测 flutter 将加解密部分在 so 的 native 层实现了,于是考虑逆向。

我经过一番搜索,又在多个群聊和论坛看到了许多“Flutter 搞不了”后,总算找到了一个叫 blutter 的可以逆向 Flutter 的项目 worawit/blutter。这篇文章既是对我这次逆向经历的记录,也作为 blutter 这个工具的使用教程。

逆向

需要准备的材料有:

  • 从需要逆向的软件 apk 中提取的 lib 文件夹
  • Termux
  • 至少 2GB 的剩余储存空间
  • 一个良好的网络环境

安装容器

这里使用 tmoe 脚本在 Termux 中安装 Debian 的 proot 容器搭建环境,如果你有其它环境可以跳过。

打开 Termux,给予必要的权限。

下载 tmoe 脚本并执行。

curl -o install.sh https://gitee.com/mo2/linux/raw/2/2
bash install.sh

Image description

接下来一路按 y,回车,等待 tmoe 安装完成。Image description

语言选择简体中文,选择 proot 容器。Image description

中途它会让你修改终端配色和字体,都不用管,跳过即可。Image description

DNS 随便选,因为后面需要手动设置。一言没用,建议关闭。Image description

挂载共享目录我建议选择 /sdcard,这样整个安卓的内部储存都能被容器内看到。其它的设置根据自己需求选择即可。Image description

接下来选择 parm64发行版列表 - Debian - 13-trixie。Image description
Image description

注意 blutter 需要 gcc13 才能正常工作,而我一开始装的 Debia Bookworm 只有 gcc12,所以根本跑不起来。后面我打算自己编译安装 gcc13,结果编译了将近一个小时都没好,果断放弃,重装 Debian trixie。

选择启动 proot,等待系统安装完成。(提示:系统安装完成后,可以在 Termux 里直接输入 tmoe 打开 tmoe 管理器,输入 tmoe p 进入容器里的 Debian 系统)Image description

设置环境

在容器内安装依赖。

apt update
apt install -y python3-pyelftools python3-requests git cmake ninja-build build-essential pkg-config libicu-dev libcapstone-dev

注意这里有一个 bug,执行上面命令的时候会提示 Temporary failure resolving 'deb.debian.org'Image description

这是因为容器内的 DNS 设置是没用的,需要手动设置 DNS。解决方法是手动修改容器内部的 /etc/resolv.conf 文件(它应该在安卓的 /data/data/com.termux/files/home/.local/share/tmoe-linux/containers/proot/debian-trixie_arm64/etc/ 目录下),添加下面几行,当然你也可以换成其它的 DNS 服务器。

nameserver 223.5.5.5
nameserver 1.1.1.1

Image description

修改 DNS 后再次执行上面的命令,就可以正常安装了。Image description

下载 blutter。

git clone https://github.com/worawit/blutter.git

Image description

开始逆向

进入 blutter 所在的目录

cd blutter

把从需要逆向的软件 apk 中提取的 lib 文件夹放到这个目录下,你可以使用 cp 命令从容器中挂载的安卓共享目录中复制,我这里直接使用 MT 管理器复制进去。Image description

接下来运行

python3 blutter.py arm64-v8a out_dir

其中 arm64-v8a 是应用的 lib 文件夹中 arm64-v8a 库所在的路径,out_dir 是输出的目录。

blutter 会自动识别 dart 版本并进行逆向。Image description

这个过程有点漫长,需要耐心等待。Image description

看到下面这样的提示,就代表逆向成功了,可以去输出目录下看结果。Image description

输出目录中应该有以下内容:

  • asm/*:libapp 中的源码
  • blutter_frida.js:适用于这个软件的 frida hook 脚本
  • objs.txt:Object Pool 中 Object 的完整(嵌套)转储
  • pp.txt:Object Pool 中的所有 Dart 对象

Image description

一旦环境设置好,以后每次逆向只需要把 lib 文件夹复制进去,指定输出目录就行了。

分析

dart 源码已经逆向出来了,但是与 AES 加解密相关的代码在哪里呢?

进入 asm/shadowshare 目录,通过对 home_screen.dart 的分析可以发现有一个叫做 aesDecrypt 的函数在 shadowshare/common/utils/encrypt_util.dart 文件中。Image description

打开这个文件,一个字符串 8YfiQ8wrkziZ5YFW 引起了我的注意,它很有可能与密钥有关。Image description

将这个文件丢给 AI 分析,得出结果:key 和 IV 都是这个字符串经过 UTF-8 编码得到的字节数组,填充方式为默认的 PKCS7。通过 AI 给出的代码,我成功解密了 gitee 仓库中加密的配置,后续会编写脚本实现自动解密。

AI 还指出在代码中硬编码 Key 和 IV 并使用相同的值是一个严重的安全漏洞,尤其是在 CBC 等模式下,会大大降低加密的安全性,但是在不使用非对称加密的情况下,好像确实只能这么干了。我自己也有一些软件是这么干的Image description

另外,我还发现这个软件除了在 gitee 中有仓库外,在 github 也有相同的仓库,并且内置了多个 github 反代加速地址,防失联措施做的挺不错。

Image description

这个有点意思,在关注,说不定哪天有用

好帖收藏,但瑟瑟发抖 xhj11

没想到在这能遇到逆向圈的道友ac01

  • oner

    Dev
  • #5

不错的逆向

  • James

    MANAGER
  • #6

大佬牛逼。但我最佩服的是大佬全程使用手机,太牛了