Flutter

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Flutter is Google se kruisplatform UI-werktuig wat ontwikkelaars toelaat om ’n enkele Dart-kodebasis te skryf wat die Engine (native C/C++) in platform-spesifieke masjienkode vir Android & iOS omskakel. Die Engine bevat ’n Dart VM, BoringSSL, Skia, ens., en word as die gedeelde biblioteek libflutter.so (Android) of Flutter.framework (iOS) versprei. Alle werklike netwerking (DNS, sockets, TLS) gebeur binne hierdie biblioteek, nie in die gewone Java/Kotlin Swift/Obj‑C‑lae nie. Daardie geïsoleerde ontwerp is waarom die gewone Java‑vlak Frida hooks op Flutter-apps misluk.

Afvang van HTTPS-verkeer in Flutter

Dit is ’n samevatting van hierdie blog post.

Waarom HTTPS-afvang in Flutter moeilik is

  • SSL/TLS-verifikasie lê twee lae dieper in BoringSSL, dus raak Java SSL‑pinning-omseilings dit nie.
  • BoringSSL gebruik sy eie CA‑store binne libflutter.so; om jou Burp/ZAP CA in Android se stelselstore te importeer verander niks.
  • Simbole in libflutter.so is gestript & gemanipuleer, wat die sertifikaat-verifikasiefunksie vir dinamiese gereedskap verberg.

Vingerafdruk van die presiese Flutter-stapel

Om die weergawe te ken laat jou toe om die regte binaries weer te bou of patrone te pas.

StepCommand / FileOutcome
Kry snapshot-hashpython3 get_snapshot_hash.py libapp.soadb4292f3ec25…
Koppel hash → Engineenginehash lys in reFlutterFlutter 3 · 7 · 12 + engine commit 1a65d409…
Haal afhanklike commitsDEPS file in that engine commitdart_revision → Dart v2 · 19 · 6
dart_boringssl_rev → BoringSSL 87f316d7…

Find get_snapshot_hash.py here.

Teiken: ssl_crypto_x509_session_verify_cert_chain()

  • Gevind in ssl_x509.cc binne BoringSSL.
  • Retourneer bool – ’n enkele true is genoeg om die hele sertifikaatkettingkontrole te omseil.
  • Dieselfde funksie bestaan op elke CPU‑argitektuur; slegs die opkodes verskil.

Option A – Binêre patching met reFlutter

  1. Kloon die presiese Engine- en Dart-bronne vir die app se Flutter‑weergawe.
  2. Regex-patch twee hotspots:
  • In ssl_x509.cc, dwing return 1; af.
  • (Opsioneel) In socket_android.cc, hard-code ’n proxy ("10.0.2.2:8080").
  1. Herkompileer libflutter.so, plaas dit terug in die APK/IPA, teken, installeer.
  2. Vooraf-gepatchte builds vir algemene weergawes word in die reFlutter GitHub releases verskaf om ure bou‑tyd te spaar.

### Option B – Live hooking with Frida (the “hard-core” path) Omdat die simbool gestript is, patroon-scan jy die gelaaide module vir sy eerste bytes en verander dan die terugkeerwaarde 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"); }
});

Ek het nie die inhoud van src/mobile-pentesting/android-app-pentesting/flutter.md nie. Plak asseblief die markdown-lêerinhoud hier, en ek sal dit na Afrikaans vertaal volgens die gegewe reëls.

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

Portering wenke

  • Vir arm64-v8a of armv7, haal die eerste ~32 bytes van die funksie uit Ghidra, omskep dit na ’n spasie-geskeide hex-string, en vervang sig.
  • Hou by een patroon per Flutter release, stoor dit in ’n cheat-sheet vir vinnige hergebruik.

Verkeer deur jou proxy afdwing

Flutter self negeer die toestel se proxy-instellings. Eenvoudigste opsies:

  • Android Studio emulator: Settings ▶ Proxy → manual.
  • Fisiese toestel: evil Wi-Fi AP + DNS spoofing, or Magisk module editing /etc/hosts.

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

Wanneer jy slegs ’n pinned Flutter API hoef waar te neem, is die kombinasie van ’n gerooted/writable AVD, ’n system-trusted proxy CA en ’n drop-in Frida script dikwels vinniger as om libflutter.so te reverse-engineer:

  1. Installeer jou proxy CA in die system store. Volg Install Burp Certificate om Burp’s DER certificate te hash/rename en dit in /system/etc/security/cacerts/ te push (writable /system required).

  2. Plaas ’n ooreenstemmende frida-server binary en hardloop dit as root sodat dit aan die Flutter-proses kan koppel:

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. Installeer die host-kant gereedskap en enumereer die teikenpakket.
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
  1. Begin die Flutter-app met die Codeshare-hook wat BoringSSL pin checks neutraliseer.
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause

Die Codeshare-skrip oorskryf die Flutter TLS verifier sodat elke sertifikaat (insluitend Burp se dinamies gegenereerde sertifikate) aanvaar word, en so public-key pin comparisons omseil.

  1. Lei verkeer deur jou proxy. Konfigureer die emulator se Wi‑Fi proxy GUI of dwing dit af via adb shell settings put global http_proxy 10.0.2.2:8080; as direkte routering misluk, gebruik adb reverse tcp:8080 tcp:8080 of ’n host-only VPN.

  2. As die app OS proxy-instellings ignoreer, herlei sockets met ’n Frida shim. Gereedskap soos frida4burp hook dart:io/BoringSSL socket creation om outbound TCP sessions na jou proxy te dwing, selfs met hardcoded HttpClient.findProxyFromEnvironment of Wi‑Fi bypasses. Stel die proxy host/port in die skrip en voer dit langs die TLS bypass uit:

frida -U -f com.example.target --no-pause \
--codeshare TheDauntless/disable-flutter-tls-v1 \
-l frida4burp.js

Werk op iOS via ‘Frida gadget’ of USB frida-server; deur die socket redirect met die TLS bypass te ketting, herstel dit beide routing en sertifikaat-aanvaarding vir Burp/mitmproxy.

Sodra die CA op die OS-laag vertrou word en Frida Flutter se pinning logic quash (plus socket redirection indien nodig), herwin Burp/mitmproxy volle sigbaarheid vir API fuzzing (BOLA, token tampering, ens.) sonder om die APK te repak.

Offset-gebaseerde hook van BoringSSL verification (no signature scan)

Wanneer pattern-based scripts oor verskeie architectures misluk (bv. x86_64 vs ARM), hook direk die BoringSSL chain verifier by absolute address binne libflutter.so. Workflow:

  • Haal die regte ABI library uit die APK: unzip -j app.apk "lib/*/libflutter.so" -d libs/ en kies die een wat by die toestel pas (bv. lib/x86_64/libflutter.so).
  • Analiseer in Ghidra/IDA en lokaliseer die verifier:
  • Bron: BoringSSL ssl_x509.cc funksie ssl_crypto_x509_session_verify_cert_chain (3 args, returns bool).
  • In gestripte builds, gebruik Search → For Strings → ssl_client → XREFs, open elke verwysde FUN_... en kies die een met 3 pointer-like args en ’n boolean return.
  • Bereken die runtime offset: neem die funksie-adres wat deur Ghidra gewys word en trek die image base af (bv. Ghidra wys dikwels 0x00100000 vir PIE Android ELFs). Voorbeeld: 0x02184644 - 0x00100000 = 0x02084644.
  • Hook by runtime deur base + offset te gebruik en forceer sukses:
// 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);

Aantekeninge

  • Signature scans kan op ARM sukses behaal maar op x86_64 misluk omdat die opcode-indeling verander; hierdie offset-metode is argitektuur-agnosties solank jy die RVA herbereken.
  • Hierdie bypass veroorsaak dat BoringSSL enige sertifikaatketting aanvaar, wat HTTPS MITM moontlik maak ongeag pins/CA trust binne Flutter.
  • As jy traffic force-route tydens debugging om TLS blocking te bevestig, bv.:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>

…jy sal steeds die hook hierbo nodig hê, aangesien verifikasie binne libflutter.so plaasvind, nie in Android se stelselvertrouenswinkel nie.

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks