Translated ['src/mobile-pentesting/android-app-pentesting/flutter.md'] t

This commit is contained in:
Translator 2025-05-20 05:38:17 +00:00
parent 7ea0effa66
commit b57269ee59

View File

@ -0,0 +1,74 @@
# Flutter
{{#include ../../banners/hacktricks-training.md}}
# Flutter
Flutterは**GoogleのクロスプラットフォームUIツールキット**で、開発者が単一のDartコードベースを書き、**Engine**ネイティブ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の2層下に存在**するため、JavaのSSLピンニングバイパスでは触れません。
* **BoringSSLはlibflutter.so内に*独自の* CAストアを使用**しているため、Burp/ZAP CAをAndroidのシステムストアにインポートしても何も変わりません。
* libflutter.so内のシンボルは**ストリップされており、マングルされています**。これにより、動的ツールから証明書検証関数が隠されます。
### 正確なFlutterスタックのフィンガープリンティング
バージョンを知ることで、正しいバイナリを再構築またはパターンマッチできます。
Step | Command / File | Outcome
----|----|----
スナップショットハッシュを取得 | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…`
ハッシュを→エンジンにマップ | **enginehash**リストをreFlutterで | Flutter 3 · 7 · 12 + engine commit `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. 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バイトを取得し、スペース区切りの16進数文字列に変換して `sig` を置き換えます。
* **Flutterのリリースごとに1つのパターンを保持**し、迅速な再利用のためにチートシートに保存します。
### プロキシを通じてトラフィックを強制する
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/)