Flutter
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Flutter is Google’s cross-platform UI toolkit that lets developers write a single Dart code-base which the Engine (native C/C++) turns into platform-specific machine code for Android & iOS. The Engine bundles a Dart VM, BoringSSL, Skia, etc., and ships as the shared library libflutter.so (Android) or Flutter.framework (iOS). All actual networking (DNS, sockets, TLS) happens inside this library, not in the usual Java/Kotlin Swift/Obj-C layers. That siloed design is why the usual Java-level Frida hooks fail on Flutter apps.
FlutterでのHTTPSトラフィックの傍受
This is a summary of this blog post.
なぜFlutterでHTTPSの傍受は難しいのか
- SSL/TLS verification lives two layers down in BoringSSL, so Java SSL‐pinning bypasses don’t touch it.
- BoringSSL uses its own CA store inside libflutter.so; importing your Burp/ZAP CA into Android’s system store changes nothing.
- Symbols in libflutter.so are stripped & mangled, hiding the certificate-verification function from dynamic tools.
正確なFlutterスタックのフィンガープリント取得
Knowing the version lets you re-build or pattern-match the right binaries.
| Step | Command / File | Outcome |
|---|---|---|
| スナップショットハッシュを取得 | python3 get_snapshot_hash.py libapp.so | adb4292f3ec25… |
| ハッシュ → Engine の対応付け | enginehash list in reFlutter | Flutter 3 · 7 · 12 + engine commit 1a65d409… |
| 依存コミットを取得 | DEPS file in that engine commit | • dart_revision → Dart v2 · 19 · 6• dart_boringssl_rev → BoringSSL 87f316d7… |
Find get_snapshot_hash.py here.
ターゲット: ssl_crypto_x509_session_verify_cert_chain()
- Located in
ssl_x509.ccinside BoringSSL. - Returns
bool– a singletrueis enough to bypass the whole certificate chain check. - Same function exists on every CPU arch; only the opcodes differ.
Option A – Binary patching with reFlutter
- Clone the exact Engine & Dart sources for the app’s Flutter version.
- Regex-patch two hotspots:
ssl_x509.cc内で、return 1;を強制する- (任意)
socket_android.cc内でプロキシをハードコードする("10.0.2.2:8080")。
- Re-compile libflutter.so, drop it back into the APK/IPA, sign, install.
- Pre-patched builds for common versions are shipped in the reFlutter GitHub releases to save hours of build time.
Option B – Live hooking with Frida (the “hard-core” path)
Because the symbol is stripped, you pattern-scan the loaded module for its first bytes, then change the return value on the fly.
// 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"); }
});
ファイルの内容(src/mobile-pentesting/android-app-pentesting/flutter.md の中身)を送ってください。受け取り次第、指定のルールに従って日本語に翻訳して返します。
frida -U -f com.example.app -l bypass.js
移植のヒント
- For arm64-v8a or armv7, grab the first ~32 bytes of the function from Ghidra, convert to a space-separated hex string, and replace
sig. - Keep one pattern per Flutter release, store them in a cheat-sheet for fast reuse.
プロキシ経由でトラフィックを強制
Flutter自体は デバイスのプロキシ設定を無視する。簡単な方法:
- Android Studio emulator: Settings ▶ Proxy → manual.
- 物理デバイス: evil Wi-Fi AP + DNS spoofing、または Magisk module で
/etc/hostsを編集。
Quick Flutter TLS bypass workflow (Frida Codeshare + system CA)
ピン留めされた Flutter API を観察するだけなら、rooted/writable AVD、システムで信頼されたプロキシ CA、そしてドロップインの Frida スクリプトを組み合わせる方が、libflutter.so をリバースエンジニアリングするより速いことが多い:
-
Install your proxy CA in the system store. Follow Install Burp Certificate to hash/rename Burp’s DER certificate and push it into
/system/etc/security/cacerts/(writable/systemrequired). -
Drop a matching
frida-serverbinary and run it as root so it can attach to the Flutter process:
adb push frida-server-17.0.5-android-x86_64 /data/local/tmp/frida-server
adb shell "su -c 'chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &'"
- ホスト側のツールをインストールし、ターゲットパッケージを列挙する。
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
- Codeshare hookでBoringSSLのpin checksを無効化してFlutterアプリを起動する。
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause
The Codeshare script overrides the Flutter TLS verifier so every certificate (including Burp’s dynamically generated ones) is accepted, side-stepping public-key pin comparisons.
- Route traffic through your proxy. エミュレータの Wi-Fi proxy GUI を設定するか、
adb shell settings put global http_proxy 10.0.2.2:8080で強制してください。直接ルーティングが失敗する場合は、adb reverse tcp:8080 tcp:8080またはホスト専用の VPN にフォールバックします。
Once the CA is trusted at the OS layer and Frida quashes Flutter’s pinning logic, Burp/mitmproxy regains full visibility for API fuzzing (BOLA, token tampering, etc.) without repacking the APK.
オフセットベースのフックによる BoringSSL 検証 (no signature scan)
パターンベースのスクリプトがアーキテクチャ間(例:x86_64 vs ARM)で失敗する場合、libflutter.so 内の絶対アドレスで BoringSSL の chain verifier を直接フックします。ワークフロー:
- APK から適切な ABI のライブラリを抽出する:
unzip -j app.apk "lib/*/libflutter.so" -d libs/として、デバイスに合ったものを選択(例:lib/x86_64/libflutter.so)。 - Ghidra/IDA で解析して verifier を特定する:
- Source: BoringSSL ssl_x509.cc function
ssl_crypto_x509_session_verify_cert_chain(3 args, returns bool). - Stripped ビルドでは、Search → For Strings →
ssl_client→ XREFs を使い、参照されている各FUN_...を開いて、ポインタ風の引数が3つで boolean を返すものを選びます。 - ランタイムオフセットを計算する: Ghidra に表示される関数アドレスからイメージベースを引きます(例: Ghidra は PIE Android ELF で
0x00100000を表示することが多い)。例:0x02184644 - 0x00100000 = 0x02084644。 - ランタイムで base + offset にフックして成功を強制する:
// frida -U -f com.target.app -l bypass.js --no-pause
const base = Module.findBaseAddress('libflutter.so');
// Example offset from analysis. Recompute per build/arch.
const off = ptr('0x02084644');
const addr = base.add(off);
// ssl_crypto_x509_session_verify_cert_chain: 3 args, bool return
Interceptor.replace(addr, new NativeCallback(function (a, b, c) {
return 1; // true
}, 'int', ['pointer', 'pointer', 'pointer']));
console.log('[+] Hooked BoringSSL verify_cert_chain at', addr);
注意
- Signature scansはARMでは成功する場合があるが、opcode layoutが変わるためx86_64では見逃されることがある; このoffset methodはRVAを再計算すればアーキテクチャに依存しない。
- このバイパスはBoringSSLに任意のchainを受け入れさせ、Flutter内部のpins/CAの信頼設定にかかわらずHTTPS MITMを可能にする。
- TLS blockingを確認するためにデバッグ中にトラフィックを強制ルーティングする場合、例:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
…上記のフックは依然として必要です。検証は libflutter.so 内で行われ、Android’s system trust store では行われません。
参考文献
- https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/
- Flutter SSL Bypass: How to Intercept HTTPS Traffic When all other Frida Scripts Fail (vercel)
- Flutter SSL Bypass: How to Intercept HTTPS Traffic When all other Frida Scripts Fail (medium)
- PoC Frida hook for Flutter SSL bypass
- BoringSSL ssl_x509.cc (ssl_crypto_x509_session_verify_cert_chain)
- SSL Pinning Bypass – Android
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


