Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions src/mobile-pentesting/android-app-pentesting/flutter.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

{{#include ../../banners/hacktricks-training.md}}

# Flutter
Flutter is **Google’s cross-platform UI toolkit** that lets developers write a single Dart code-base which the **Engine** (native C/C++) turns into platform-specific machine code for Android & iOS.
The Engine bundles a **Dart VM**, **BoringSSL**, Skia, etc., and ships as the shared library **libflutter.so** (Android) or **Flutter.framework** (iOS). All actual networking (DNS, sockets, TLS) happens **inside this library**, *not* in the usual Java/Kotlin Swift/Obj-C layers. That siloed design is why the usual Java-level Frida hooks fail on Flutter apps.

Expand All @@ -20,7 +19,7 @@ Knowing the version lets you re-build or pattern-match the right binaries.

Step | Command / File | Outcome
----|----|----
Get snapshot hash | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…`
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<br>• `dart_boringssl_rev` → BoringSSL `87f316d7…`

Expand Down Expand Up @@ -75,9 +74,46 @@ Flutter itself **ignores device proxy settings**. Easiest options:
* **Android Studio emulator:** Settings ▶ Proxy → manual.
* **Physical device:** evil Wi-Fi AP + DNS spoofing, or Magisk module editing `/etc/hosts`.

### 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:

```javascript
// 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);
```

Notes
- Recompute the offset for every target build and CPU architecture; compiler/codegen differences break hardcoded signatures.
- This bypass causes BoringSSL to accept any chain, enabling HTTPS MITM regardless of pins/CA trust inside Flutter.
- If you force-route traffic during debugging to confirm TLS blocking, e.g.:

```bash
iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination <Burp_IP>:<Burp_Port>
```

…you will still need the hook above, since verification happens inside libflutter.so, not Android’s system trust store.

## References
- [https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/](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](https://m4kr0x.medium.com/flutter-tls-bypass-how-to-intercept-https-traffic-when-all-other-frida-scripts-fail-bd3d04489088)
- [BoringSSL ssl_x509.cc (ssl_crypto_x509_session_verify_cert_chain)](https://github.com/google/boringssl/blob/main/ssl/ssl_x509.cc#L238)


{{#include ../../banners/hacktricks-training.md}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
## LESS Code Injection leading to SSRF & Local File Read
# LESS Code Injection leading to SSRF & Local File Read

{{#include ../../../banners/hacktricks-training.md}}

LESS is a popular CSS pre-processor that adds variables, mixins, functions and the powerful `@import` directive. During compilation the LESS engine will **fetch the resources referenced in `@import`** statements and embed ("inline") their contents into the resulting CSS when the `(inline)` option is used.

Expand Down Expand Up @@ -59,4 +61,5 @@ curl -sk "${TARGET}rest/v10/css/preview?baseUrl=1&lm=${INJ}" | \

* [SugarCRM ≤ 14.0.0 (css/preview) LESS Code Injection Vulnerability](https://karmainsecurity.com/KIS-2025-04)
* [SugarCRM Security Advisory SA-2024-059](https://support.sugarcrm.com/resources/security/sugarcrm-sa-2024-059/)
* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258)
* [CVE-2024-58258](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-58258)
{{#include ../../../banners/hacktricks-training.md}}