本文是深入研究逆向工程和利用 Flutter Android 应用程序中的未知漏洞进行漏洞赏金或渗透测试之前的先决条件。
从0到1:
许多框架已经成为了当今移动应用开发的便利工具,在它们之上有很多不同的框架和不同的编程语言, Java 作为 Android 基本开发的语言,因为它易学习,尽管他们仅将其用作语法但 Android 本身并未编译为 JVM,一旦涉及 Android NDK,C/C++ 也会被讨论。
但是,如果使用 Dart 语言来开发 Android 应用程序呢?Dart 是一种被认为在客户端进行了优化的编程语言,开发出的应用程序支持跨平台。Dart 本身是由谷歌开发的,有人说Dark语言对初学者更加友好。
然后是另一个名为 Flutter 的组件,它最初是一个 UI 开发工具包,但它使用 Dart 作为后端桥梁,用于组件之间的通信。这就是为什么 Flutter 有自己的 GUI 渲染,开发人员可以根据自己的意愿来轻松控制所有布局,而且它速度非常快,因为 Flutter 依靠 JIT(Just-In Time)进行开发且没有中间环节,由于 Dart 使用 AOT(Ahead of Time),因此选择 Dart 来弥补 JIT 的缺点,因此使得 Flutter 和 Dart 完美结合,因为当应用程序启动时,AOT 会参与其中,因此该框架保持最佳的用户体验和性能,它还使其成为一个完整的 SDK,并且支持多平台(Windows、macOS、Linux)运行。
管中窥豹:
Dart SDK 本身具有生成快照的能力, Dart 需要这个快照来加速程序运行的过程。该快照不像 VM 快照或其他快照一样被称为程序状态,而更像是一个序列化的二进制包文件以减少启动时间,它被称为内核快照作为第一个被引入,后又推出了 JIT Snapshot 和 AOT Snapshot,但这两个不是跨平台的。
在 Flutter 应用程序中,此快照起着至关重要的作用,因为它还保存了编译后的源代码,但它是一个“剥离的”ELF 二进制文件,但我们仍然可以恢复它的函数名称。令人惊奇的是,每个快照版本都有所不同,因此作为逆向工程师,需要检查 Dart 如何生成其快照。
当Flutter应用程序构建完成时,我们将看到两个库,libfltter.so和libapp.so,libfltter.so是一个包装为共享对象的Flutter引擎,libapp.so则是源代码本身的二进制格式(快照)。
如果想更深入地了解 ROData、Dart 对象和结构映射的方式,可以参考 Andre Lipke 撰写的相关博文(https://blog.tst.sh/reverse-engineering-flutter-apps-part-1/)。
寻找盲点:
当开发人员想要发布他们的应用程序时,无论是网站还是移动应用程序以及任何类型的数字基础设施,他们通常犯的一个错误是忘记关闭调试模式, Flutter 应用程序也不例外。
当应用程序仍处于调试模式时会发生什么?可能会看到一些可能会泄露的机密信息,例如应用程序日志记录的详细程度、PII 等。
Flutter 具有三种类型的构建模型,debug、profile和release,它们之间有着显著的差异。在debug模式下,调试被启用,因此可以通过模拟器调试应用程序。
当启动仍处于Debug模式的应用程序时,是一种糟糕的做法,这是因为当 Flutter 将源代码编译成 Dart 内核字节码时,会生成一个名为 kernel_blob.bin 的文件。
让我们假设一个场景,某公司想让你对一款基于Flutter的APK做黑盒渗透测试,那么你需要静态和动态分析应用程序的执行流程,首先,你需要确定应用程序是否处于Debug模式。当反编译 APK 后,首先需要看的是文件夹,如果 kernel_blob.bin 存在于文件夹内,那么基本就可以宣告Game Over了,因为我们可以无需任何特定工具就能轻松地从那里提取该应用程序的源代码。
接着我们可以提取该应用程序本身的函数或类,例如 API 密钥泄漏、用户名、密码等。如果足够幸运,还可以尝试获取默认的 Flutter 小部件函数名称,例如获取源代码的主要入口点:
grep/findstrMyApp()
而如果某公司希望对他们的APP程序中再次进行一次黑盒渗透测试,并且这一次他们使用了Release 模式,使 Dart 内核字节码不再存放在应用程序的assets文件夹中怎么办? Dart 源代码本身并不会出现在应用程序的 JVM 包中,因此我们将在第二篇文章中从静态和动态的底层视角进行深入分析。
参考:
https://dart.dev/community/who-uses-dart
https://insights.daffodilsw.com/blog/why-flutter-uses-dart
https://www.guardsquare.com/blog/current-state-and-future-of-reversing-flutter-apps
https://blog.tst.sh/reverse-engineering-flutter-apps-part-1/
https://docs.flutter.dev/testing/build-modes
https://github.com/dart-lang/sdk/wiki/Kernel-Documentation
https://www.guardsquare.com/blog/how-developers-secure-flutter-mobile-apps-in-2022-guardsquare
====正文结束====