Flutter
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Flutter es el kit de UI multiplataforma de Google que permite a los desarrolladores escribir una única base de código Dart que el Engine (native C/C++) transforma en código máquina específico para Android e iOS. El Engine incluye un Dart VM, BoringSSL, Skia, etc., y se distribuye como la librería compartida libflutter.so (Android) o Flutter.framework (iOS). Todo el networking real (DNS, sockets, TLS) ocurre dentro de esta librería, no en las capas habituales Java/Kotlin o Swift/Obj-C. Ese diseño aislado es la razón por la que los hooks habituales a nivel Java con Frida fallan en apps Flutter.
Interceptar tráfico HTTPS en Flutter
This is a summary of this blog post.
Por qué interceptar HTTPS es complicado en Flutter
- La verificación SSL/TLS vive dos capas abajo en BoringSSL, por lo que los bypasses de SSL‐pinning a nivel Java no lo afectan.
- BoringSSL usa su propio almacén de CA dentro de libflutter.so; importar tu Burp/ZAP CA en el store del sistema Android no cambia nada.
- Los símbolos en libflutter.so están stripped & mangled, ocultando la función de verificación de certificados a herramientas dinámicas.
Identificar la pila Flutter exacta
Conocer la versión te permite reconstruir o buscar patrones en los binarios correctos.
| 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.
Target: ssl_crypto_x509_session_verify_cert_chain()
- Located in
ssl_x509.ccinside BoringSSL. - Returns
bool– un únicotruees suficiente para bypassear toda la comprobación de la cadena de certificados. - La misma función existe en todas las arquitecturas CPU; solo difieren los opcodes.
Opción A – Parcheo binario con reFlutter
- Clone los sources exactos del Engine & Dart para la versión Flutter de la app.
- Regex-patch dos hotspots:
- En
ssl_x509.cc, forzarreturn 1; - (Opcional) En
socket_android.cc, hard-codear un proxy ("10.0.2.2:8080").
- Re-compile libflutter.so, reemplazarla en el APK/IPA, firmar, instalar.
- Pre-patched builds para versiones comunes se distribuyen en los releases de reFlutter en GitHub para ahorrar horas de compilación.
Opción B – Hooking en vivo con Frida (la vía “hard-core”)
Porque el símbolo está strippeado, haces pattern-scan del módulo cargado buscando sus primeros bytes y luego cambias el valor de retorno en caliente.
// 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"); }
});
Por favor, proporciona el contenido de src/mobile-pentesting/android-app-pentesting/flutter.md que quieres que traduzca al español, o pega el texto aquí.
frida -U -f com.example.app -l bypass.js
Consejos para portar
- 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.
Forzar el tráfico a través de tu 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.
Flujo rápido de TLS bypass para Flutter (Frida Codeshare + system CA)
When you only need to observe a pinned Flutter API, combining a rooted/writable AVD, a system-trusted proxy CA, and a drop-in Frida script is often faster than reverse-engineering libflutter.so:
-
Instala tu proxy CA en el almacén del sistema. Sigue Install Burp Certificate para hashear/renombrar el certificado DER de Burp y empujarlo a
/system/etc/security/cacerts/(writable/systemrequired). -
Coloca un binario
frida-servercoincidente y ejecútalo como root para que pueda adjuntarse al proceso de 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 &'"
- Instala las herramientas del lado del host y enumera el paquete objetivo.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
- Inicia la app Flutter con el hook de Codeshare que neutraliza las comprobaciones de pin de BoringSSL.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause
El script Codeshare anula el verificador TLS de Flutter, por lo que se acepta cualquier certificado (incluidos los generados dinámicamente por Burp), eludiendo las public-key pin comparisons.
-
Ruta el tráfico a través de tu proxy. Configura la GUI del proxy Wi‑Fi del emulador o fíjalo mediante
adb shell settings put global http_proxy 10.0.2.2:8080; si el enrutamiento directo falla, recurre aadb reverse tcp:8080 tcp:8080o a un host-only VPN. -
Si la app ignora los ajustes de proxy del OS, redirige los sockets con un shim de Frida. Herramientas como frida4burp hook
dart:io/BoringSSL socket creation para forzar que las sesiones TCP salientes usen tu proxy, incluso conHttpClient.findProxyFromEnvironmenthardcodeado o bypasses de Wi‑Fi. Configura el host/puerto del proxy en el script y ejecútalo junto con el bypass TLS:
frida -U -f com.example.target --no-pause \
--codeshare TheDauntless/disable-flutter-tls-v1 \
-l frida4burp.js
Funciona en iOS mediante un Frida gadget o USB frida-server; encadenar el socket redirect con el bypass de TLS restaura tanto el enrutamiento como la aceptación de certificados para Burp/mitmproxy.
Una vez que la CA es confiada a nivel del OS y Frida anula la lógica de pinning de Flutter (más socket redirection si es necesario), Burp/mitmproxy recupera visibilidad completa para API fuzzing (BOLA, token tampering, etc.) sin volver a empaquetar el APK.
Hook basado en offset de la verificación de BoringSSL (no signature scan)
Cuando los scripts basados en patrones fallan entre arquitecturas (p. ej., x86_64 vs ARM), engancha directamente el verificador de chain de BoringSSL por dirección absoluta dentro de libflutter.so. Flujo de trabajo:
- Extrae la librería con la ABI correcta del APK:
unzip -j app.apk "lib/*/libflutter.so" -d libs/y elige la que coincida con el dispositivo (p. ej.,lib/x86_64/libflutter.so). - Analízala en Ghidra/IDA y localiza el verificador:
- Fuente: BoringSSL ssl_x509.cc función
ssl_crypto_x509_session_verify_cert_chain(3 args, devuelve bool). - En builds stripped, usa Search → For Strings →
ssl_client→ XREFs, luego abre cadaFUN_...referenciado y selecciona el que tenga 3 args tipo puntero y un retorno booleano. - Calcula el offset en tiempo de ejecución: toma la dirección de la función mostrada por Ghidra y réstale la image base (p. ej., Ghidra suele mostrar
0x00100000para PIE Android ELFs). Ejemplo:0x02184644 - 0x00100000 = 0x02084644. - Engancha en tiempo de ejecución usando base + offset y fuerza el éxito:
// 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);
Notas
- Los Signature scans pueden tener éxito en ARM pero fallar en x86_64 porque cambia la disposición de los opcodes; este método de offset es agnóstico a la arquitectura siempre que recalcules el RVA.
- Este bypass hace que BoringSSL acepte cualquier chain, permitiendo HTTPS MITM independientemente de los pins/CA de confianza dentro de Flutter.
- Si enrutas forzosamente el tráfico durante el debugging para confirmar el bloqueo TLS, por ejemplo:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
…todavía necesitarás el hook anterior, ya que la verificación ocurre dentro de libflutter.so, no en Android’s system trust store.
Referencias
- 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
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


