Flutter

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Flutter é a toolkit de UI cross-platform do Google que permite aos desenvolvedores escreverem uma única base de código Dart que o Engine (nativo C/C++) transforma em código máquina específico da plataforma para Android & iOS. O Engine agrupa um Dart VM, BoringSSL, Skia, etc., e é distribuído como a biblioteca compartilhada libflutter.so (Android) ou Flutter.framework (iOS). Todo o networking real (DNS, sockets, TLS) acontece dentro dessa biblioteca, não nas camadas usuais Java/Kotlin Swift/Obj-C. Esse design compartimentado é o motivo pelo qual os hooks habituais via Frida ao nível Java falham em apps Flutter.

Interceptando tráfego HTTPS em Flutter

Este é um resumo deste blog post.

Por que a interceptação de HTTPS é complicada no Flutter

  • A verificação SSL/TLS fica duas camadas abaixo em BoringSSL, então os bypasses de SSL‐pinning em Java não a alcançam.
  • BoringSSL usa seu próprio store de CA dentro de libflutter.so; importar sua CA do Burp/ZAP para o store do sistema Android não altera nada.
  • Símbolos em libflutter.so são stripped & mangled, escondendo a função de verificação de certificado das ferramentas dinâmicas.

Identificar a stack Flutter exata

Saber a versão permite reconstruir ou fazer pattern-match dos binários corretos.

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…

Encontre get_snapshot_hash.py here.

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").
  1. Re-compile libflutter.so, drop it back into the APK/IPA, sign, install.
  2. 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.

// 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"); }
});

I don’t have access to your files. Please paste the contents of src/mobile-pentesting/android-app-pentesting/flutter.md here and I’ll translate the English text to Portuguese following your rules (keeping code, tags, links and paths unchanged).

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

Dicas de portabilidade

  • For arm64-v8a or armv7, pegue os primeiros ~32 bytes da função no Ghidra, converta para uma string hex separada por espaços e substitua sig.
  • Mantenha um padrão por versão do Flutter, armazene-os em um cheat-sheet para reutilização rápida.

Forçando o tráfego pelo seu proxy

O Flutter em si ignora as configurações de proxy do dispositivo. Opções mais fáceis:

  • Android Studio emulator: Settings ▶ Proxy → manual.
  • Dispositivo físico: evil Wi-Fi AP + DNS spoofing, ou módulo Magisk editando /etc/hosts.

Quick Flutter TLS bypass workflow (Frida Codeshare + system CA)

Quando você só precisa observar uma API Flutter pinada, combinar um AVD rootado/gravável, uma proxy CA confiável pelo sistema e um script Frida drop-in geralmente é mais rápido do que fazer engenharia reversa do libflutter.so:

  1. Instale sua proxy CA no armazenamento do sistema. Siga Install Burp Certificate para hash/renomear o certificado DER do Burp e empurrá-lo para /system/etc/security/cacerts/ (é necessário /system gravável).

  2. Coloque um binário frida-server correspondente e execute-o como root para que ele possa anexar-se ao 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. Instale as ferramentas no host e enumere o pacote alvo.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
  1. Inicie o app Flutter com o hook Codeshare que neutraliza as BoringSSL pin checks.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause

O script Codeshare substitui o verificador TLS do Flutter de modo que todo certificado (incluindo os gerados dinamicamente pelo Burp) é aceito, contornando public-key pin comparisons.

  1. Roteie o tráfego através do seu proxy. Configure a GUI do proxy Wi‑Fi do emulador ou force-a via adb shell settings put global http_proxy 10.0.2.2:8080; se o roteamento direto falhar, recorra a adb reverse tcp:8080 tcp:8080 ou a uma host-only VPN.

Uma vez que a CA seja confiada no nível do OS e o Frida anule a lógica de pinning do Flutter, o Burp/mitmproxy recupera visibilidade completa para API fuzzing (BOLA, token tampering, etc.) sem repackear o APK.

Hook baseado em offset da verificação do BoringSSL (no signature scan)

Quando pattern-based scripts falham entre arquiteturas (e.g., x86_64 vs ARM), hook diretamente o chain verifier do BoringSSL por endereço absoluto dentro de libflutter.so. Fluxo de trabalho:

  • Extraia a biblioteca com o ABI correto do APK: unzip -j app.apk "lib/*/libflutter.so" -d libs/ e escolha aquela que corresponde ao dispositivo (e.g., lib/x86_64/libflutter.so).
  • Analise no Ghidra/IDA e localize o verificador:
  • Fonte: BoringSSL ssl_x509.cc função ssl_crypto_x509_session_verify_cert_chain (3 args, retorna bool).
  • Em builds sem símbolos, use Search → For Strings → ssl_client → XREFs, então abra cada FUN_... referenciado e escolha aquele com 3 argumentos do tipo ponteiro e retorno booleano.
  • Calcule o offset em runtime: pegue o endereço da função mostrado pelo Ghidra e subtraia a image base (por exemplo, Ghidra frequentemente mostra 0x00100000 para PIE Android ELFs). Exemplo: 0x02184644 - 0x00100000 = 0x02084644.
  • Faça o hook em tempo de execução usando base + offset e force o sucesso:
// 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

  • Scans de assinatura podem ter sucesso em ARM, mas falhar em x86_64 porque o layout de opcode muda; este método por offset é agnóstico à arquitetura desde que você recalcule o RVA.
  • Este bypass faz com que o BoringSSL aceite qualquer cadeia, permitindo HTTPS MITM independentemente dos pins/CA trust dentro do Flutter.
  • Se você forçar o roteamento do tráfego durante a depuração para confirmar o bloqueio do TLS, e.g.:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>

…você ainda precisará do hook acima, já que a verificação acontece dentro de libflutter.so, e não no Android’s system trust store.

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks