mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/flutter.md'] t
This commit is contained in:
parent
f3187b8423
commit
3756eca7a8
74
src/mobile-pentesting/android-app-pentesting/flutter.md
Normal file
74
src/mobile-pentesting/android-app-pentesting/flutter.md
Normal file
@ -0,0 +1,74 @@
|
||||
# Flutter
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# Flutter
|
||||
Flutter是**谷歌的跨平台UI工具包**,允许开发者编写单一的Dart代码库,**引擎**(本地C/C++)将其转换为Android和iOS的特定平台机器代码。引擎捆绑了**Dart VM**、**BoringSSL**、Skia等,并作为共享库**libflutter.so**(Android)或**Flutter.framework**(iOS)发布。所有实际的网络操作(DNS、套接字、TLS)都发生在**这个库内部**,*而不是*在通常的Java/Kotlin Swift/Obj-C层。这种孤立的设计是通常的Java级Frida钩子在Flutter应用中失败的原因。
|
||||
|
||||
## 在Flutter中拦截HTTPS流量
|
||||
|
||||
这是这篇[博客文章](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/)的摘要。
|
||||
|
||||
### 为什么在Flutter中拦截HTTPS很棘手
|
||||
* **SSL/TLS验证位于BoringSSL的两层下方**,因此Java SSL固定绕过不会触及它。
|
||||
* **BoringSSL在libflutter.so内部使用其*自己的* CA存储**;将你的Burp/ZAP CA导入Android的系统存储不会改变任何东西。
|
||||
* libflutter.so中的符号是**剥离和混淆的**,隐藏了证书验证功能,使动态工具无法使用。
|
||||
|
||||
### 确定确切的Flutter栈
|
||||
知道版本可以让你重建或模式匹配正确的二进制文件。
|
||||
|
||||
步骤 | 命令 / 文件 | 结果
|
||||
----|----|----
|
||||
获取快照哈希 | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…`
|
||||
映射哈希 → 引擎 | **enginehash**列表在reFlutter中 | Flutter 3 · 7 · 12 + 引擎提交 `1a65d409…`
|
||||
拉取依赖提交 | 在该引擎提交中的DEPS文件 | • `dart_revision` → Dart v2 · 19 · 6<br>• `dart_boringssl_rev` → BoringSSL `87f316d7…`
|
||||
|
||||
在这里找到[get_snapshot_hash.py](https://github.com/Impact-I/reFlutter/blob/main/scripts/get_snapshot_hash.py)。
|
||||
|
||||
### 目标: `ssl_crypto_x509_session_verify_cert_chain()`
|
||||
* 位于BoringSSL内部的**`ssl_x509.cc`**。
|
||||
* **返回`bool`** – 一个`true`就足以绕过整个证书链检查。
|
||||
* 每个CPU架构都有相同的函数;只有操作码不同。
|
||||
|
||||
### 选项A – 使用**reFlutter**进行二进制补丁
|
||||
1. **克隆**应用的Flutter版本的确切引擎和Dart源代码。
|
||||
2. **正则补丁**两个热点:
|
||||
* 在`ssl_x509.cc`中,强制`return 1;`
|
||||
* (可选)在`socket_android.cc`中,硬编码一个代理(`"10.0.2.2:8080"`)。
|
||||
3. **重新编译**libflutter.so,将其放回APK/IPA中,签名,安装。
|
||||
4. **预补丁构建**的常见版本在reFlutter GitHub发布中提供,以节省数小时的构建时间。
|
||||
|
||||
### 选项B – 使用**Frida**进行实时钩取(“硬核”路径)
|
||||
由于符号被剥离,你需要对加载的模块进行模式扫描以获取其前几个字节,然后动态更改返回值。
|
||||
```javascript
|
||||
// attach & locate libflutter.so
|
||||
var flutter = Process.getModuleByName("libflutter.so");
|
||||
|
||||
// x86-64 pattern of the first 16 bytes of ssl_crypto_x509_session_verify_cert_chain
|
||||
var sig = "55 41 57 41 56 41 55 41 54 53 48 83 EC 38 C6 02";
|
||||
|
||||
Memory.scan(flutter.base, flutter.size, sig, {
|
||||
onMatch: function (addr) {
|
||||
console.log("[+] found verifier at " + addr);
|
||||
Interceptor.attach(addr, {
|
||||
onLeave: function (retval) { retval.replace(0x1); } // always 'true'
|
||||
});
|
||||
},
|
||||
onComplete: function () { console.log("scan done"); }
|
||||
});
|
||||
```
|
||||
请运行它:
|
||||
```bash
|
||||
frida -U -f com.example.app -l bypass.js
|
||||
```
|
||||
*移植提示*
|
||||
* 对于 **arm64-v8a** 或 **armv7**,从 Ghidra 中获取函数的前 ~32 字节,转换为以空格分隔的十六进制字符串,并替换 `sig`。
|
||||
* 每个 Flutter 版本保持 **一个模式**,将它们存储在备忘单中以便快速重用。
|
||||
|
||||
### 通过代理强制流量
|
||||
Flutter 本身 **忽略设备代理设置**。最简单的选项:
|
||||
* **Android Studio 模拟器:** 设置 ▶ 代理 → 手动。
|
||||
* **物理设备:** 恶意 Wi-Fi AP + DNS 欺骗,或 Magisk 模块编辑 `/etc/hosts`。
|
||||
|
||||
## 参考
|
||||
- [https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/)
|
Loading…
x
Reference in New Issue
Block a user