# Flutter {{#include ../../banners/hacktricks-training.md}} # Flutter 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. ## Intercepting HTTPS traffic in Flutter This is a summary of this [blog post](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/). ### Why HTTPS interception is tricky in Flutter * **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. ### Fingerprint the exact Flutter stack Knowing the version lets you re-build or pattern-match the right binaries. Step | Command / File | Outcome ----|----|---- Get snapshot hash | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…` Map hash → Engine | **enginehash** list in reFlutter | Flutter 3 · 7 · 12 + engine commit `1a65d409…` Pull dependent commits | DEPS file in that engine commit | • `dart_revision` → Dart v2 · 19 · 6
• `dart_boringssl_rev` → BoringSSL `87f316d7…` Find [get_snapshot_hash.py here](https://github.com/Impact-I/reFlutter/blob/main/scripts/get_snapshot_hash.py). ### Target: `ssl_crypto_x509_session_verify_cert_chain()` * Located in **`ssl_x509.cc`** inside BoringSSL. * **Returns `bool`** – a single `true` is 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** 1. **Clone** the exact Engine & Dart sources for the app’s Flutter version. 2. **Regex-patch** two hotspots: * In `ssl_x509.cc`, force `return 1;` * (Optional) In `socket_android.cc`, hard-code a proxy (`"10.0.2.2:8080"`). 3. **Re-compile** libflutter.so, drop it back into the APK/IPA, sign, install. 4. **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. ```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"); } }); ``` Run it: ```bash frida -U -f com.example.app -l bypass.js ``` *Porting tips* * 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. ### Forcing traffic through your proxy Flutter itself **ignores device proxy settings**. Easiest options: * **Android Studio emulator:** Settings ▶ Proxy → manual. * **Physical device:** evil Wi-Fi AP + DNS spoofing, or Magisk module editing `/etc/hosts`. ## References - [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/) {{#include ../../banners/hacktricks-training.md}}