如何从移动应用中提取 AI 模型文件
你不会去下载一个 AI
从移动应用中提取 AI 模型
如果你在“喝下 Kool-Aid”(比喻盲目信任或追随),你会觉得人工智能无处不在。
毫不意外,那些财力最雄厚的企业——疯狂投入巨资雇佣研究人员、囤积数据并训练大规模模型——正在这个领域中处于领先地位。
现在,许多应用开始直接在设备上集成 AI 模型。对于需要频繁推理的场景(比如即时照片滤镜或实时物体检测),这种方式非常好,能够提供速度和离线访问。
并且,由于任何在你设备上运行的东西都可以被设备访问,对于那些好奇想一探究竟的人来说,现在正是一个黄金机会。
攻击目标
微软的 Seeing AI 应用,被称为“为盲人设计的会说话的相机”,是一项非常有用的技术。你可以把它对准物体、文档,甚至是货币,它都能通过文本转语音,来描述它所看到的内容。
它其中一个突出的功能是 货币识别,支持 17 种以上的货币,共识别 225 种不同的钞票。这对于无障碍使用非常有帮助,使视障用户无需依赖他人就能独立识别纸币。
不过,我之所以选中它并不是偶然的。Frida Telegram 频道的一位成员专门对这款应用的货币识别功能感兴趣,向我提出了问题。
初步侦查
Android 应用以 APK 文件(Android Package Kit)的形式分发,本质上是一个存档,其中包含应用运行所需的一切:应用二进制文件、字体和图片等资源,以及其他资产。
而 AI 模型通常也是以文件的形式存在,通常放在这些资产(assets)里。
为了查看 APK 的内容,我们可以使用 apktool 进行反编译,把它的结构解包到一个文件夹里,以便深入研究。
在检查 assets
文件夹后,我们发现了一个名为 currency
的文件,大小超过 16MB,并且还配有一个 currency-labels.txt
。
这看上去是个不错的文件,直到我们发现它并不是真正的我们所想的那种“可直接读取的好东西”。
currency
无法被 file
命令检测出来,使用 binwalk 得到的结果是一堆乱码,而它的 熵(entropy) 值始终为 1。这些都强烈表明该文件是被加密过的。
继续前行
接下来,我们可以尝试逆向工程,找出应用是如何解密 currency
文件的。开发者们可以使用各种“以安全换混淆”的手段,比如把文件倒着读、向左移动 12 位再向右移动 2 位、每隔一个字节就执行一次模 3 运算、再减去你生日的 UNIX 时间戳,诸如此类乱七八糟的操作。
虽然研究这些确实很有意思,但我更喜欢能够真正把项目做完。
最终,这个带有所有权重和偏置的加密模型,还是要被加载到某种神经网络推理引擎(Neural Inference Engine)里。
市面上有很多框架可以用来做这件事,最常见的就是 TensorFlow;而在资源紧张的设备上尤其常用 TensorFlow Lite。
回头再看 apktool
的结果,可以看到 com.microsoft.seeingai
确实在使用 TensorFlow Lite。
经过一些谷歌搜索文档,你会发现 org.tensorflow.lite.NativeInterpreterWrapper
有一些方法可以用来加载 *.tflite
模型。
Frida 时间到
Frida 是一款强大的动态插桩(instrumentation)工具包,几乎可以在所有操作系统上运行,包括 QNX。
它允许你附加到正在运行的进程,并动态修改其行为。借助 Frida,你可以跟踪方法调用,查看其参数和返回值,甚至可以改写方法,以添加你自己的逻辑。
checkKey(key)
?当然,return true
就行。它真的非常强大。
在移动应用研究中,Objection 特别好用——它是一个 CLI 工具,内置了许多 Frida 脚本,能够方便地执行常见任务。
让我们跟踪对 org.tensorflow.lite.NativeInterpreterWrapper
的所有函数调用:
android hooking watch class org.tensorflow.lite.NativeInterpreterWrapper
如你所见,应用在启动时就调用了 .createModelWithBuffer(java.nio.ByteBuffer, long)。
这里的 java.nio.ByteBuffer
很可能就是解密后的 *.tflite
模型!
长话短说,我会重写这个方法来把模型dump到磁盘上。
TensorFlow Lite Dumper - Frida Codeshare
如果你像我一样在速度较慢的模拟器上运行 Android,那么脚本执行可能需要一点时间。
脚本结束后,用 adb pull
拖一下,就把 currency.tflite
拿到本地啦!
为了验证文件内容,我使用了 Netron 这款基于 Web 的神经网络可视化工具。如果 Netron 能读取 currency.tflite
文件,就说明我们成功导出了完整的 TensorFlow Lite 模型,包括权重和偏置。
完美!我们成功提取出了货币识别模型,包含了所有的权重和偏置。
复制粘贴(CTRL + C;CTRL + V)
由于我的脚本是通过 hook TensorFlow Lite 来dump模型的,所以我们可以把这套攻击手法用在任何使用 TensorFlow Lite 的应用上。
Adobe Scan 就是一个不错的案例,我自己还经常使用。它最棒的功能就是用手机相机扫描文档。
要是有人……哦,打住 🤭
附录
有点好笑的是,我写这篇文章和脚本的时候,正好是在参加 38C3,那一年的口号是 “Illegal Instructions”(非法指令)。
文中展示的一切,或许也算是“非法指令”。
请记住,AI 模型和大多数其他事物一样,通常被视为知识产权。在使用或修改任何提取出来的模型之前,你需要获得所有者的明确许可。
PS:有很多人都在讨论 AI 模型到底算不算知识产权。我不知道,也没有去写法律。
这是“免责声明”的部分,可以随便忽略。