Flutter

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Flutter Google का एक क्रॉस-प्लैटफ़ॉर्म UI toolkit है जो डेवलपर्स को एक ही Dart code-base लिखने देता है जिसे Engine (native C/C++) प्लेटफ़ॉर्म-विशिष्ट मशीन कोड में बदल देता है (Android & iOS)। Engine में Dart VM, BoringSSL, Skia आदि बंडल होते हैं और यह shared library के रूप में भेजा जाता है: libflutter.so (Android) या Flutter.framework (iOS)। सारा वास्तविक नेटवर्किंग (DNS, sockets, TLS) यही library के अंदर होता है, सामान्य Java/Kotlin Swift/Obj-C लेयर में नहीं। यही सिलो-डिज़ाइन वजह है कि सामान्य Java-level Frida hooks Flutter apps पर काम नहीं करते।

Intercepting HTTPS traffic in Flutter

This is a summary of this blog post.

Why HTTPS interception is tricky in Flutter

  • SSL/TLS verification lives two layers down in BoringSSL, इसलिए Java SSL‐pinning bypasses इसे नहीं छू पातीं।
  • BoringSSL uses its own CA store जो libflutter.so के अंदर रहता है; आपका Burp/ZAP CA Android’s system store में इम्पोर्ट करने से कुछ नहीं बदलता।
  • Symbols in libflutter.so stripped & mangled होते हैं, जिससे certificate-verification function dynamic tools से छिप जाता है।

Fingerprint the exact Flutter stack

Version जानना आपको सही binaries re-build या pattern-match करने में मदद करता है।

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…

Find get_snapshot_hash.py here.

Target: ssl_crypto_x509_session_verify_cert_chain()

  • Located in ssl_x509.cc inside BoringSSL.
  • Returns bool – एक single true पूरे certificate chain check को bypass करने के लिए पर्याप्त है।
  • Same function exists on every CPU arch; सिर्फ opcodes अलग होते हैं।

Option A – Binary patching with reFlutter

  1. उस app के Flutter version के लिए exact Engine & Dart sources clone करें।
  2. दो hotspots को regex-patch करें:
  • ssl_x509.cc में, return 1; जबरन लगाएँ
  • (Optional) socket_android.cc में proxy को हार्ड-कोड करें ("10.0.2.2:8080").
  1. libflutter.so re-compile करें, इसे APK/IPA में वापस डालें, sign करके install करें।
  2. सामान्य versions के लिए pre-patched builds reFlutter GitHub releases में उपलब्ध हैं ताकि build समय बचाया जा सके।

### Option B – Live hooking with Frida (the “hard-core” path) Symbol stripped होने के कारण, आप loaded module में उसके first bytes के लिए pattern-scan करते हैं, फिर रनटाइम पर return value बदल देते हैं।

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

मैं उस फ़ाइल तक पहुँच नहीं रखता। कृपया src/mobile-pentesting/android-app-pentesting/flutter.md की सामग्री यहाँ पेस्ट करें — मैं उसे दिए गए निर्देशों के अनुसार Markdown और टैग बिना बदले हिंदी में अनुवाद कर दूँगा।

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

पोर्टिंग टिप्स

  • For arm64-v8a or armv7, Ghidra से फ़ंक्शन के पहले ~32 बाइट निकालें, उन्हें space-separated hex string में कन्वर्ट करें, और sig को बदलें.
  • एक pattern प्रति Flutter release रखें, तेज़ पुन:उपयोग के लिए इन्हें एक cheat-sheet में स्टोर करें।

अपने proxy के माध्यम से ट्रैफ़िक फोर्स करना

Flutter स्वयं device proxy settings को अनदेखा करता है। सबसे आसान विकल्प:

  • Android Studio emulator: Settings ▶ Proxy → manual.
  • Physical device: evil Wi-Fi AP + DNS spoofing, या Magisk module से /etc/hosts एडिट करना।

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

जब आपको केवल pinned Flutter API को observe करना हो, तो rooted/writable AVD, system-trusted proxy CA, और एक drop-in Frida script को मिलाकर इस्तेमाल करना अक्सर libflutter.so का reverse-engineering करने से तेज़ होता है:

  1. Install your proxy CA in the system store. Burp के DER certificate को hash/rename करने और उसे /system/etc/security/cacerts/ में push करने के लिए Install Burp Certificate का पालन करें (writable /system आवश्यक)।

  2. Drop a matching frida-server binary and run it as root ताकि यह Flutter process से attach कर सके:

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. host-side tooling इंस्टॉल करें और target package को enumerate करें।
pip3 install frida-tools --break-system-packages
adb shell pm list packages -f | grep target
  1. Codeshare hook के साथ Flutter app को स्पॉन करें जो BoringSSL pin checks को निष्क्रिय कर देता है।
frida -U -f com.example.target --codeshare TheDauntless/disable-flutter-tls-v1 --no-pause

The Codeshare script overrides the Flutter TLS verifier so every certificate (including Burp’s dynamically generated ones) is accepted, side-stepping public-key pin comparisons.

  1. अपने proxy के माध्यम से ट्रैफिक रूट करें। emulator Wi‑Fi proxy GUI को कॉन्फ़िगर करें या इसे लागू करने के लिए adb shell settings put global http_proxy 10.0.2.2:8080 का उपयोग करें; यदि direct routing विफल हो तो adb reverse tcp:8080 tcp:8080 या host-only VPN पर वापस जाएं।

  2. यदि app OS proxy settings को ignore करता है, तो sockets को Frida shim से redirect करें। frida4burp जैसे tools dart:io/BoringSSL socket creation को hook करते हैं ताकि outbound TCP sessions को आपके proxy पर मजबूर किया जा सके, भले ही HttpClient.findProxyFromEnvironment हार्डकोडेड हो या Wi‑Fi bypasses मौजूद हों। स्क्रिप्ट में proxy host/port सेट करें और इसे TLS bypass के साथ साथ चलाएँ:

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

Works on iOS via a Frida gadget or USB frida-server; chaining the socket redirect with the TLS bypass restores both routing and certificate acceptance for Burp/mitmproxy.

Once the CA is trusted at the OS layer and Frida quashes Flutter’s pinning logic (plus socket redirection if needed), Burp/mitmproxy regains full visibility for API fuzzing (BOLA, token tampering, etc.) without repacking the APK.

Offset-based hook of BoringSSL verification (no signature scan)

जब pattern-based scripts architectures के बीच fail कर जाते हैं (e.g., x86_64 vs ARM), तो libflutter.so के अंदर absolute address द्वारा सीधे BoringSSL chain verifier को hook करें। 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:
  • स्रोत: 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 referenced FUN_... 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 0x00100000 for 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);

नोट्स

  • Signature scans ARM पर सफल हो सकते हैं लेकिन x86_64 पर मिस कर सकते हैं क्योंकि opcode layout बदल जाता है; यह offset method architecture-agnostic है जब तक आप recalc the RVA.
  • यह bypass BoringSSL को किसी भी chain को accept करने के लिए मजबूर करता है, जिससे Flutter के अंदर pins/CA trust की परवाह किए बिना HTTPS MITM संभव हो जाता है।
  • यदि आप debugging के दौरान TLS blocking की पुष्टि करने के लिए traffic को force-route करते हैं, उदा.:
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>

…आपको फिर भी ऊपर दिया गया hook चाहिए होगा, क्योंकि सत्यापन libflutter.so के अंदर होता है, न कि Android के सिस्टम ट्रस्ट स्टोर में।

संदर्भ

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें