Flutter
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Flutter è il toolkit UI cross-platform di Google che permette agli sviluppatori di scrivere un singolo codice Dart che l’Engine (C/C++ nativo) trasforma in codice macchina specifico per piattaforma per Android & iOS. L’Engine include una Dart VM, BoringSSL, Skia, ecc., e viene distribuito come la libreria condivisa libflutter.so (Android) o Flutter.framework (iOS). Tutte le operazioni di networking reali (DNS, sockets, TLS) avvengono all’interno di questa library, non nei soliti livelli Java/Kotlin Swift/Obj-C. Questo design a compartimenti è il motivo per cui i soliti hook Frida a livello Java falliscono sulle app Flutter.
Intercepting HTTPS traffic in Flutter
Questo è un riassunto di questo blog post.
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
Conoscere la versione permette di ricostruire o fare pattern-match sui binari corretti.
| Step | Command / File | Outcome |
|---|---|---|
| Get snapshot hash | python3 get_snapshot_hash.py libapp.so | 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.
Obiettivo: 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.
Opzione A – Binary patching con reFlutter
- Clona le sorgenti esatte di Engine & Dart per la versione Flutter dell’app.
- Regex-patch due hotspot:
- In
ssl_x509.cc, forzarereturn 1; - (Opzionale) In
socket_android.cc, hard-code un proxy ("10.0.2.2:8080").
- Ricompila libflutter.so, rimpiazzala nell’APK/IPA, firma, installa.
- Build pre-patchati per versioni comuni sono forniti nei release di reFlutter su GitHub per risparmiare ore di compilazione.
Opzione B – Live hooking con Frida (la via “hard-core”)
Poiché il simbolo è stripped, si esegue un pattern-scan sul modulo caricato per i suoi primi byte, poi si modifica il valore di ritorno al volo.
// 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"); }
});
Non hai fornito il contenuto del file. Per favore incolla qui il contenuto di src/mobile-pentesting/android-app-pentesting/flutter.md che vuoi tradurre oppure caricalo.
frida -U -f com.example.app -l bypass.js
Consigli per il porting
- Per arm64-v8a o armv7, prendi i primi ~32 byte della funzione da Ghidra, convertili in una stringa esadecimale separata da spazi, e sostituisci
sig. - Mantieni un pattern per release di Flutter, salvali in un cheat-sheet per riuso rapido.
Forzare il traffico attraverso il tuo proxy
Flutter di per sé ignora le impostazioni proxy del dispositivo. Opzioni più semplici:
- Android Studio emulator: Settings ▶ Proxy → manual.
- Dispositivo fisico: evil Wi-Fi AP + DNS spoofing, o modulo Magisk modificando
/etc/hosts.
Quick Flutter TLS bypass workflow (Frida Codeshare + system CA)
Quando hai solo bisogno di osservare un’API Flutter protetta da certificate pinning, combinare un AVD rootato/scrivibile, una proxy CA di sistema trusted e uno script Frida drop-in è spesso più veloce del reverse-engineering di 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). -
Posiziona un binario
frida-servercompatibile ed eseguilo come root in modo che possa collegarsi al processo Flutter:
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 &'"
- Installa il host-side tooling e enumera il target package.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
- Avvia l’app Flutter con l’hook Codeshare che neutralizza i pin checks di BoringSSL.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause
Lo script Codeshare sovrascrive il Flutter TLS verifier in modo che ogni certificato (inclusi quelli generati dinamicamente da Burp) venga accettato, aggirando le public-key pin comparisons.
-
Instrada il traffico tramite il tuo proxy. Configura la GUI del proxy Wi‑Fi dell’emulatore o forzala tramite
adb shell settings put global http_proxy 10.0.2.2:8080; se il routing diretto fallisce, ricorri aadb reverse tcp:8080 tcp:8080o a un host-only VPN. -
Se l’app ignora le impostazioni proxy del SO, reindirizza i socket con uno shim Frida. Strumenti come frida4burp hookano la creazione dei socket di
dart:io/BoringSSL per forzare le sessioni TCP in uscita verso il tuo proxy, anche conHttpClient.findProxyFromEnvironmenthardcoded o bypass del Wi‑Fi. Imposta host/port del proxy nello script e avvialo insieme al TLS bypass:
frida -U -f com.example.target --no-pause \
--codeshare TheDauntless/disable-flutter-tls-v1 \
-l frida4burp.js
Works on iOS via a Frida gadget or USB frida-server; chaining the socket redirect with the TLS bypass restores both routing and certificate acceptance for Burp/mitmproxy.
Once the CA is trusted at the OS layer and Frida quashes Flutter’s pinning logic (plus socket redirection if needed), Burp/mitmproxy regains full visibility for API fuzzing (BOLA, token tampering, etc.) without repacking the APK.
Offset-based hook of BoringSSL verification (no signature scan)
When pattern-based scripts fail across architectures (e.g., x86_64 vs ARM), directly hook the BoringSSL chain verifier by absolute address within libflutter.so. Workflow:
- Estrai la libreria con ABI corretta dall’APK:
unzip -j app.apk "lib/*/libflutter.so" -d libs/e scegli quella che corrisponde al dispositivo (es.,lib/x86_64/libflutter.so). - Analizza in Ghidra/IDA e individua il verifier:
- Source: BoringSSL ssl_x509.cc function
ssl_crypto_x509_session_verify_cert_chain(3 args, returns bool). - Nelle build stripped, usa Search → For Strings →
ssl_client→ XREFs, poi apri ogniFUN_...referenziata e scegli quella con 3 argomenti di tipo puntatore e ritorno booleano. - Calcola l’offset a runtime: prendi l’indirizzo della funzione mostrato da Ghidra e sottrai l’image base (es., Ghidra spesso mostra
0x00100000per PIE Android ELFs). Esempio:0x02184644 - 0x00100000 = 0x02084644. - Hook at runtime by base + offset and force success:
// 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);
Note
- Signature scans possono riuscire su ARM ma mancare su x86_64 perché il layout degli opcode cambia; questo offset method è agnostico all’architettura fintanto che ricalcoli l’RVA.
- Questo bypass fa sì che BoringSSL accetti qualsiasi chain, abilitando HTTPS MITM indipendentemente da pins/CA trust all’interno di Flutter.
- Se forzi il routing del traffico durante il debugging per confermare il blocco TLS, ad esempio:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
…avrai comunque bisogno dell’hook sopra, poiché la verifica avviene all’interno di libflutter.so, non nel system trust store di Android.
Riferimenti
- 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
- Practical Mobile Traffic Interception
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


