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

Flutter è il toolkit UI cross-platform di Google che permette agli sviluppatori di scrivere una singola code-base 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 libreria condivisa libflutter.so (Android) o Flutter.framework (iOS). Tutto il networking reale (DNS, sockets, TLS) avviene all’interno di questa libreria, non nei consueti layer 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

Questa è una sintesi di questo blog post.

Why HTTPS interception is tricky in Flutter

  • La verifica SSL/TLS risiede due layer più in basso in BoringSSL, quindi i bypass di SSL‐pinning a livello Java non la toccano.
  • BoringSSL usa il suo proprio CA store dentro libflutter.so; importare la CA di Burp/ZAP nello store di sistema Android non cambia nulla.
  • I simboli in libflutter.so sono stripped & mangled, nascondendo la funzione di verifica dei certificati agli strumenti dinamici.

Fingerprint the exact Flutter stack

Conoscere la versione permette di ricostruire o fare pattern-match sui binari corretti.

StepCommand / FileOutcome
Get snapshot hashpython3 get_snapshot_hash.py libapp.soadb4292f3ec25…
Map hash → Engineenginehash list in reFlutterFlutter 3 · 7 · 12 + engine commit 1a65d409…
Pull dependent commitsDEPS file in that engine commitdart_revision → Dart v2 · 19 · 6
dart_boringssl_rev → BoringSSL 87f316d7…

Find get_snapshot_hash.py here.

Target: ssl_crypto_x509_session_verify_cert_chain()

  • Si trova in ssl_x509.cc dentro BoringSSL.
  • Restituisce bool – un singolo true è sufficiente per bypassare l’intera verifica della catena di certificati.
  • La stessa funzione esiste su ogni arch CPU; cambiano solo gli opcode.

Opzione A – Binary patching con reFlutter

  1. Clona le esatte sorgenti Engine & Dart per la versione Flutter dell’app.
  2. Regex-patch due hotspot:
  • In ssl_x509.cc, forzare return 1;
  • (Opzionale) In socket_android.cc, hard-code un proxy ("10.0.2.2:8080").
  1. Ricompila libflutter.so, reinseriscila nell’APK/IPA, firma, installa.
  2. Pre-patched builds per versioni comuni sono forniti nelle release GitHub di reFlutter per risparmiare ore di build.

Opzione B – Live hooking con Frida (la via “hard-core”)

Poiché il simbolo è stripped, si esegue un pattern-scan del modulo caricato per i suoi primi byte, quindi si cambia 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 posso accedere ai file locali. Incolla qui il contenuto di src/mobile-pentesting/android-app-pentesting/flutter.md che vuoi tradurre e procederò a tradurlo in italiano mantenendo esattamente la stessa sintassi markdown/HTML e le regole che hai indicato.

frida -U -f com.example.app -l bypass.js

Suggerimenti per il porting

  • Per arm64-v8a o armv7, prendi i primi ~32 byte della funzione da Ghidra, converti in una stringa esadecimale separata da spazi e sostituisci sig.
  • Conserva un pattern per release di Flutter, salvali in un cheat-sheet per riutilizzi rapidi.

Forzare il traffico attraverso il tuo proxy

Flutter di per sé ignora le impostazioni proxy del dispositivo. Opzioni più semplici:

  • Android Studio emulator: Impostazioni ▶ Proxy → manuale.
  • Physical device: evil Wi-Fi AP + DNS spoofing, o modulo Magisk che modifica /etc/hosts.

Flusso rapido per bypass TLS di Flutter (Frida Codeshare + system CA)

Quando hai solo bisogno di osservare una pinned Flutter API, combinare un AVD rooted/writable, una system-trusted proxy CA e uno script Frida drop-in è spesso più veloce che reverse-engineerare libflutter.so:

  1. Installa la tua proxy CA nello store di sistema. Segui Install Burp Certificate per calcolare l’hash/rinominare il certificato DER di Burp e copiarlo in /system/etc/security/cacerts/ (è richiesto /system scrivibile).

  2. Piazza un binario frida-server corrispondente ed eseguilo come root in modo che possa agganciarsi 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 &'"
  1. Installa la strumentazione lato host ed enumera il pacchetto target.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
  1. Avvia l’app Flutter con il Codeshare hook che neutralizza i controlli PIN 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, eludendo i confronti di public-key pin.

  1. Route traffic through your 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 l’instradamento diretto fallisce, ricorri a adb reverse tcp:8080 tcp:8080 o a una host-only VPN.

Una volta che la CA è considerata attendibile a livello di OS e Frida annulla la logica di pinning di Flutter, Burp/mitmproxy recupera piena visibilità per API fuzzing (BOLA, token tampering, ecc.) senza dover ripaccare l’APK.

Offset-based hook of BoringSSL verification (no signature scan)

Quando gli script basati su pattern falliscono tra architetture (es., x86_64 vs ARM), aggancia direttamente il chain verifier di BoringSSL tramite l’indirizzo assoluto all’interno di libflutter.so. Flusso di lavoro:

  • 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 localizza il verifier:
  • Sorgente: 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 ogni FUN_... referenziata e scegli quella con 3 argomenti di tipo puntatore e un ritorno booleano.
  • Calcola l’offset a runtime: prendi l’indirizzo della funzione mostrato da Ghidra e sottrai l’image base (es., Ghidra spesso mostra 0x00100000 per i PIE Android ELF). Esempio: 0x02184644 - 0x00100000 = 0x02084644.
  • Aggancia a runtime usando base + offset e forza il successo:
// 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 avere successo su ARM ma mancare su x86_64 perché il layout degli opcode cambia; questo offset method è indipendente dall’architettura purché ricalcoli l’RVA.
  • Questo bypass fa sì che BoringSSL accetti qualsiasi catena, abilitando HTTPS MITM indipendentemente dai pins/CA trust all’interno di Flutter.
  • Se forzi il routing del traffico durante il debug 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 del hook di cui sopra, poiché la verifica avviene all’interno di libflutter.so, non in Android’s system trust store.

Riferimenti

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