mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/flutter.md'] t
This commit is contained in:
parent
b764a68886
commit
4aec7a7572
75
src/mobile-pentesting/android-app-pentesting/flutter.md
Normal file
75
src/mobile-pentesting/android-app-pentesting/flutter.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# Flutter
|
||||||
|
|
||||||
|
{{#include ../../banners/hacktricks-training.md}}
|
||||||
|
|
||||||
|
# Flutter
|
||||||
|
Το Flutter είναι το **εργαλείο UI πολλαπλών πλατφορμών της Google** που επιτρέπει στους προγραμματιστές να γράφουν μια ενιαία βάση κώδικα Dart, την οποία ο **Engine** (native C/C++) μετατρέπει σε κωδικό μηχανής συγκεκριμένο για τις πλατφόρμες Android & iOS.
|
||||||
|
Ο Engine περιλαμβάνει μια **Dart VM**, **BoringSSL**, Skia, κ.λπ., και αποστέλλεται ως η κοινή βιβλιοθήκη **libflutter.so** (Android) ή **Flutter.framework** (iOS). Όλη η πραγματική δικτύωση (DNS, sockets, TLS) συμβαίνει **μέσα σε αυτή τη βιβλιοθήκη**, *όχι* στα συνήθη επίπεδα Java/Kotlin Swift/Obj-C. Αυτός ο απομονωμένος σχεδιασμός είναι ο λόγος που οι συνήθεις hooks σε επίπεδο Java αποτυγχάνουν σε εφαρμογές Flutter.
|
||||||
|
|
||||||
|
## Παρεμβολή HTTPS traffic στο Flutter
|
||||||
|
|
||||||
|
Αυτή είναι μια περίληψη αυτού του [blog post](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/).
|
||||||
|
|
||||||
|
### Γιατί η παρεμβολή HTTPS είναι δύσκολη στο Flutter
|
||||||
|
* **Η επαλήθευση SSL/TLS βρίσκεται δύο επίπεδα κάτω** στο BoringSSL, οπότε οι παρακάμψεις SSL-pinning της Java δεν την αγγίζουν.
|
||||||
|
* **Το BoringSSL χρησιμοποιεί το *δικό του* CA store** μέσα στο libflutter.so; η εισαγωγή του CA του Burp/ZAP στο σύστημα Android δεν αλλάζει τίποτα.
|
||||||
|
* Τα σύμβολα στο libflutter.so είναι **αφαιρεμένα & παραμορφωμένα**, κρύβοντας τη λειτουργία επαλήθευσης πιστοποιητικού από δυναμικά εργαλεία.
|
||||||
|
|
||||||
|
### Αναγνώριση της ακριβούς στοίβας Flutter
|
||||||
|
Γνωρίζοντας την έκδοση σας επιτρέπει να ξαναχτίσετε ή να ταιριάξετε τα σωστά δυαδικά αρχεία.
|
||||||
|
|
||||||
|
Βήμα | Εντολή / Αρχείο | Αποτέλεσμα
|
||||||
|
----|----|----
|
||||||
|
Λάβετε το hash στιγμιότυπου | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…`
|
||||||
|
Χάρτης hash → Engine | **enginehash** λίστα στο reFlutter | Flutter 3 · 7 · 12 + δέσμευση engine `1a65d409…`
|
||||||
|
Ανακτήστε τις εξαρτώμενες δεσμεύσεις | Αρχείο DEPS σε αυτή τη δέσμευση engine | • `dart_revision` → Dart v2 · 19 · 6<br>• `dart_boringssl_rev` → BoringSSL `87f316d7…`
|
||||||
|
|
||||||
|
Βρείτε [get_snapshot_hash.py εδώ](https://github.com/Impact-I/reFlutter/blob/main/scripts/get_snapshot_hash.py).
|
||||||
|
|
||||||
|
### Στόχος: `ssl_crypto_x509_session_verify_cert_chain()`
|
||||||
|
* Βρίσκεται στο **`ssl_x509.cc`** μέσα στο BoringSSL.
|
||||||
|
* **Επιστρέφει `bool`** – μια μόνο `true` αρκεί για να παρακάμψει ολόκληρη την επαλήθευση της αλυσίδας πιστοποιητικών.
|
||||||
|
* Η ίδια λειτουργία υπάρχει σε κάθε αρχιτεκτονική CPU; μόνο οι κωδικοί λειτουργιών διαφέρουν.
|
||||||
|
|
||||||
|
### Επιλογή A – Διόρθωση δυαδικών αρχείων με **reFlutter**
|
||||||
|
1. **Κλωνοποιήστε** τις ακριβείς πηγές Engine & Dart για την έκδοση Flutter της εφαρμογής.
|
||||||
|
2. **Regex-patch** δύο hotspots:
|
||||||
|
* Στο `ssl_x509.cc`, αναγκάστε `return 1;`
|
||||||
|
* (Προαιρετικά) Στο `socket_android.cc`, σκληροκωδικοποιήστε έναν proxy (`"10.0.2.2:8080"`).
|
||||||
|
3. **Επανασυγκεντρώστε** το libflutter.so, τοποθετήστε το ξανά στο APK/IPA, υπογράψτε, εγκαταστήστε.
|
||||||
|
4. **Προ-διορθωμένες εκδόσεις** για κοινές εκδόσεις αποστέλλονται στις εκδόσεις GitHub του reFlutter για να εξοικονομήσουν ώρες χρόνου κατασκευής.
|
||||||
|
|
||||||
|
### Επιλογή B – Ζωντανή σύνδεση με **Frida** (η “σκληρή” διαδρομή)
|
||||||
|
Επειδή το σύμβολο είναι αφαιρεμένο, σκανάρετε το φορτωμένο module για τα πρώτα του bytes, στη συνέχεια αλλάξτε την τιμή επιστροφής εν κινήσει.
|
||||||
|
```javascript
|
||||||
|
// 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"); }
|
||||||
|
});
|
||||||
|
```
|
||||||
|
Εκτέλεσέ το:
|
||||||
|
```bash
|
||||||
|
frida -U -f com.example.app -l bypass.js
|
||||||
|
```
|
||||||
|
*Συμβουλές μεταφοράς*
|
||||||
|
* Για **arm64-v8a** ή **armv7**, πάρε τα πρώτα ~32 bytes της συνάρτησης από το Ghidra, μετατροπή σε μια αλφαριθμητική συμβολοσειρά με κενά και αντικατάσταση του `sig`.
|
||||||
|
* Κράτησε **ένα μοτίβο ανά έκδοση Flutter**, αποθήκευσέ τα σε ένα cheat-sheet για γρήγορη επαναχρησιμοποίηση.
|
||||||
|
|
||||||
|
### Ανάγκαση κυκλοφορίας μέσω του proxy σου
|
||||||
|
Το Flutter **αγνοεί τις ρυθμίσεις proxy της συσκευής**. Ευκολότερες επιλογές:
|
||||||
|
* **Emulator Android Studio:** Ρυθμίσεις ▶ Proxy → χειροκίνητα.
|
||||||
|
* **Φυσική συσκευή:** κακόβουλο Wi-Fi AP + spoofing DNS, ή επεξεργασία του module Magisk `/etc/hosts`.
|
||||||
|
|
||||||
|
## Αναφορές
|
||||||
|
- [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/)
|
Loading…
x
Reference in New Issue
Block a user