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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Flutter é a toolkit de UI multiplataforma do Google que permite aos desenvolvedores escreverem uma única base de código Dart que o Engine (C/C++ nativo) converte em código de máquina específico da plataforma para Android e iOS. O Engine inclui uma Dart VM, BoringSSL, Skia, etc., e é distribuído como a biblioteca compartilhada libflutter.so (Android) ou Flutter.framework (iOS). Toda a rede real (DNS, sockets, TLS) acontece dentro dessa biblioteca, não nas camadas Java/Kotlin ou Swift/Obj-C habituais. Esse design compartimentado é o motivo pelo qual os hooks de Frida ao nível Java normalmente falham em apps Flutter.
Intercepting HTTPS traffic in Flutter
Isto é um resumo deste blog post.
Why HTTPS interception is tricky in Flutter
- A verificação SSL/TLS está duas camadas abaixo no BoringSSL, então bypasses de SSL-pinning em Java não o afetam.
- O BoringSSL usa seu próprio repositório de CA dentro de libflutter.so; importar a CA do seu Burp/ZAP no repositório do sistema Android não altera nada.
- Símbolos em libflutter.so são stripped & mangled, escondendo a função de verificação de certificados das ferramentas dinâmicas.
Identificar a stack Flutter exata
Saber a versão permite recompilar ou fazer pattern-match nos binários corretos.
| 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.
Alvo: ssl_crypto_x509_session_verify_cert_chain()
- Localizada em
ssl_x509.ccdentro do BoringSSL. - Retorna
bool– um únicotrueé suficiente para burlar toda a verificação da cadeia de certificados. - A mesma função existe em todas as arquiteturas de CPU; apenas os opcodes diferem.
Opção A – Patch binário com reFlutter
- Clone os códigos-fonte exatos do Engine e do Dart para a versão Flutter do app.
- Regex-patch dois pontos críticos:
- Em
ssl_x509.cc, forçarreturn 1; - (Opcional) Em
socket_android.cc, codificar estaticamente um proxy ("10.0.2.2:8080").
- Recompilar libflutter.so, colocá-la novamente no APK/IPA, assinar, instalar.
- Builds pré-patchados para versões comuns são disponibilizados nos releases do reFlutter no GitHub para economizar horas de tempo de build.
Opção B – Hooking em tempo real com Frida (o caminho “hard-core”)
Como o símbolo está stripped, você pattern-scan o módulo carregado pelos seus primeiros bytes e então altera o valor de retorno em tempo de execução.
// 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"); }
});
Preciso do conteúdo do arquivo src/mobile-pentesting/android-app-pentesting/flutter.md para traduzir. Por favor, cole aqui o texto (ou confirme como quer fornecer o arquivo). Vou retornar a tradução para português mantendo exatamente a mesma sintaxe Markdown/HTML e sem traduzir tags, links ou caminhos.
frida -U -f com.example.app -l bypass.js
Dicas de portabilidade
- Para 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 através do seu proxy
Flutter itself ignora as configurações de proxy do dispositivo. Opções mais fáceis:
- Android Studio emulator: Configurações ▶ Proxy → manual.
- Physical device: AP Wi‑Fi malicioso + 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 costuma ser mais rápido do que engenharia reversa do libflutter.so:
-
Install your proxy CA in the system store. Siga Install Burp Certificate para hash/renomear o certificado DER do Burp e colocá-lo em
/system/etc/security/cacerts/(requer/systemgravável). -
Drop a matching
frida-serverbinary and run it as 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 &'"
- Instale as ferramentas do lado do host e enumere o pacote alvo.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
- Inicie o aplicativo Flutter com o Codeshare hook que neutraliza as verificações de pin do BoringSSL.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause
O script Codeshare sobrescreve o Flutter TLS verifier de modo que todo certificado (incluindo os gerados dinamicamente pelo Burp) é aceito, contornando verificações de public-key pin.
-
Route traffic through your proxy. Configure o proxy Wi‑Fi do emulador pela GUI ou force via
adb shell settings put global http_proxy 10.0.2.2:8080; se o roteamento direto falhar, recorra aadb reverse tcp:8080 tcp:8080ou a uma VPN host-only. -
If the app ignores OS proxy settings, redirect sockets with a Frida shim. Ferramentas como frida4burp hook
dart:io/BoringSSL socket creation para forçar sessões TCP de saída pelo seu proxy, mesmo comHttpClient.findProxyFromEnvironmenthardcoded ou Wi‑Fi bypasses. Defina o host/porta do proxy no script e execute-o junto com o TLS bypass:
frida -U -f com.example.target --no-pause \
--codeshare TheDauntless/disable-flutter-tls-v1 \
-l frida4burp.js
Funciona no iOS via um Frida gadget ou USB frida-server; encadear o socket redirect com o TLS bypass restaura tanto o roteamento quanto a aceitação de certificados para Burp/mitmproxy.
Uma vez que a CA é confiada no nível do OS e o Frida quashes Flutter’s pinning logic (mais socket redirection, se necessário), o Burp/mitmproxy recupera visibilidade total para API fuzzing (BOLA, token tampering, etc.) sem repacking the APK.
Offset-based hook of BoringSSL verification (no signature scan)
Quando scripts baseados em pattern falham entre arquiteturas (e.g., x86_64 vs ARM), faça o hook diretamente no verificador de chain do BoringSSL por endereço absoluto dentro de 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, use Search → For Strings →
ssl_client→ XREFs, then open each referencedFUN_...and pick the one with 3 pointer-like args and a boolean return. - Compute the runtime offset: take the function address shown by Ghidra and subtract the image base (e.g., Ghidra often shows
0x00100000for PIE Android ELFs). 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
- Varreduras de assinatura podem ter sucesso em ARM, mas falhar em x86_64 porque o opcode layout muda; este método de offset é agnóstico à arquitetura desde que você recalcule o RVA.
- Esse bypass faz com que o BoringSSL aceite qualquer cadeia, permitindo HTTPS MITM independentemente dos pins/confiança da CA dentro do Flutter.
- Se você forçar o roteamento do tráfego durante a depuração para confirmar o bloqueio de TLS, por exemplo:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
…você ainda vai precisar do hook acima, pois a verificação ocorre dentro de libflutter.so, e não no Android’s system trust store.
Referências
- 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
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
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


