6.5 KiB
Flutter
{{#include ../../banners/hacktricks-training.md}}
Flutter
Το Flutter είναι το εργαλείο διεπαφής χρήστη πολλαπλών πλατφορμών της 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 είναι δύσκολη στο 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• dart_boringssl_rev → BoringSSL 87f316d7… |
Βρείτε get_snapshot_hash.py εδώ.
Στόχος: ssl_crypto_x509_session_verify_cert_chain()
- Βρίσκεται στο
ssl_x509.ccμέσα στο BoringSSL. - Επιστρέφει
bool– μια μόνοtrueείναι αρκετή για να παρακάμψει ολόκληρη την επαλήθευση αλυσίδας πιστοποιητικών. - Η ίδια λειτουργία υπάρχει σε κάθε αρχιτεκτονική CPU; μόνο οι κωδικοί λειτουργιών διαφέρουν.
Επιλογή A – Δυαδική διόρθωση με reFlutter
- Κλωνοποιήστε τις ακριβείς πηγές Engine & Dart για την έκδοση Flutter της εφαρμογής.
- Regex-patch δύο hotspots:
- Στο
ssl_x509.cc, αναγκάστεreturn 1; - (Προαιρετικά) Στο
socket_android.cc, σκληροκωδικοποιήστε έναν proxy ("10.0.2.2:8080").
- Επανασυγκεντρώστε το libflutter.so, τοποθετήστε το πίσω στο APK/IPA, υπογράψτε, εγκαταστήστε.
- Προ-διορθωμένες εκδόσεις για κοινές εκδόσεις αποστέλλονται στις εκδόσεις GitHub του reFlutter για να εξοικονομήσουν ώρες χρόνου κατασκευής.
Επιλογή B – Ζωντανή σύνδεση με Frida (η “σκληρή” διαδρομή)
Επειδή το σύμβολο είναι αφαιρεμένο, σκανάρετε το φορτωμένο module για τα πρώτα του bytes, στη συνέχεια αλλάξτε την τιμή επιστροφής εν κινήσει.
// 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"); }
});
Λάβετε το:
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 + DNS spoofing, ή επεξεργασία του module Magisk
/etc/hosts.
Αναφορές
{{#include ../../banners/hacktricks-training.md}}