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 toolkit de UI multiplataforma de Google que permite a los desarrolladores escribir una única base de código en Dart que el Engine (C/C++ nativo) convierte 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 de Java/Kotlin o Swift/Obj-C. Ese diseño aislado es la razón por la que los hooks de Frida a nivel Java habituales fallan en apps Flutter.
Interceptar tráfico HTTPS en Flutter
Este es un resumen de esta blog post.
Por qué interceptar HTTPS es complicado en Flutter
- La verificación SSL/TLS vive dos capas más abajo en BoringSSL, así que los bypasses de SSL‐pinning a nivel Java no la afectan.
- BoringSSL usa su propio almacén de CA dentro de libflutter.so; importar tu CA de Burp/ZAP 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 las herramientas dinámicas.
Identificar la versión exacta del stack de Flutter
Saber la versión te permite reconstruir o hacer pattern-match de los binarios correctos.
| Paso | Comando / Archivo | Resultado |
|---|---|---|
| Obtener el hash del snapshot | python3 get_snapshot_hash.py libapp.so | adb4292f3ec25… |
| Mapear hash → Engine | enginehash list in reFlutter | Flutter 3 · 7 · 12 + engine commit 1a65d409… |
| Obtener commits dependientes | DEPS file in that engine commit | • dart_revision → Dart v2 · 19 · 6• dart_boringssl_rev → BoringSSL 87f316d7… |
Encuentra get_snapshot_hash.py here.
Target: ssl_crypto_x509_session_verify_cert_chain()
- Localizada en
ssl_x509.ccdentro de BoringSSL. - Devuelve
bool– un únicotruees suficiente para omitir 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
- Clona las fuentes exactas del Engine y Dart para la versión de Flutter de la app.
- Regex-patch dos puntos calientes:
- En
ssl_x509.cc, forzarreturn 1; - (Opcional) En
socket_android.cc, hard-codear un proxy ("10.0.2.2:8080").
- Recompila libflutter.so, insértala de nuevo en el APK/IPA, firma e instala.
- Las builds pre-patched para versiones comunes se incluyen en los releases de reFlutter en GitHub para ahorrar horas de compilación.
### Opción B – Live hooking con Frida (la vía “hard-core”) Debido a que el símbolo está stripped, realizas un pattern-scan del módulo cargado buscando sus primeros bytes y luego cambias el valor de retorno al vuelo.
// 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"); }
});
No se proporcionó el contenido del archivo. Pega aquí el contenido de src/mobile-pentesting/android-app-pentesting/flutter.md que quieres traducir y lo traduciré al español manteniendo la sintaxis Markdown/HTML y las reglas indicadas.
frida -U -f com.example.app -l bypass.js
Consejos para portar
- Para arm64-v8a o armv7, toma los primeros ~32 bytes de la función desde Ghidra, conviértelos a una cadena hex separada por espacios, y reemplaza
sig. - Mantén un patrón por Flutter release, almacénalos en una cheat-sheet para reutilización rápida.
Forzar el tráfico a través de tu proxy
Flutter en sí ignora los ajustes de proxy del dispositivo. Opciones más sencillas:
- Android Studio emulator: Settings ▶ Proxy → manual.
- Physical device: evil Wi-Fi AP + DNS spoofing, o módulo Magisk editando
/etc/hosts.
Quick Flutter TLS bypass workflow (Frida Codeshare + system CA)
Cuando solo necesitas observar una API pinned de Flutter, combinar un AVD rooteado/escribible, una CA de proxy confiable por el sistema y un script Frida drop-in suele ser más rápido que reverse-engineering de 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/(requiere/systemescribible). -
Coloca un binario
frida-servercoincidente y ejecútalo como root para que pueda adjuntarse al proceso 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 en el host y enumera el paquete objetivo.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
- Lanza la app Flutter con el hook Codeshare que neutraliza BoringSSL pin checks.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause
El script Codeshare sobrescribe el verificador TLS de Flutter de modo que se acepta cualquier certificado (incluidos los generados dinámicamente por Burp), eludiendo las comparaciones de pin de clave pública.
- Route traffic through your proxy. Configura el proxy Wi‑Fi del emulador mediante la GUI o impónlo vía
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 una host-only VPN.
Una vez que la CA es confiada a nivel del OS y Frida anula la lógica de pinning de Flutter, Burp/mitmproxy recupera visibilidad completa para API fuzzing (BOLA, token tampering, etc.) sin repackear el 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:
- Extract the right-ABI library from the APK:
unzip -j app.apk "lib/*/libflutter.so" -d libs/and pick the one matching the device (e.g.,lib/x86_64/libflutter.so). - Analyze in Ghidra/IDA and locate the verifier:
- Source: BoringSSL ssl_x509.cc function
ssl_crypto_x509_session_verify_cert_chain(3 args, returns bool). - In stripped builds, search for the string
"ssl_client"and inspect XREFs; identify the function taking three pointer-like args and returning a boolean. - Compute the runtime offset: take the function address shown by Ghidra and subtract the image base used during analysis to get the relative offset (RVA). Example:
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);
Notas
- Recalcula el offset para cada build objetivo y arquitectura de CPU; las diferencias del compiler/codegen rompen firmas hardcoded.
- Este bypass provoca que BoringSSL acepte cualquier chain, habilitando HTTPS MITM sin importar pins/CA trust dentro de Flutter.
- Si enrutas forzosamente el tráfico durante la depuración para confirmar el bloqueo TLS, p. ej.:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
…aún necesitarás el hook anterior, ya que la verificación ocurre dentro de libflutter.so, no en el almacén de confianza del sistema de Android.
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
- BoringSSL ssl_x509.cc (ssl_crypto_x509_session_verify_cert_chain)
- SSL Pinning Bypass – Android
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.
HackTricks

