diff --git a/src/mobile-pentesting/android-app-pentesting/flutter.md b/src/mobile-pentesting/android-app-pentesting/flutter.md new file mode 100644 index 000000000..3e11a3565 --- /dev/null +++ b/src/mobile-pentesting/android-app-pentesting/flutter.md @@ -0,0 +1,74 @@ +# Flutter + +{{#include ../../banners/hacktricks-training.md}} + +# Flutter +Flutter, geliştiricilerin tek bir Dart kod tabanı yazmasına olanak tanıyan **Google'ın çoklu platform UI araç takımıdır**; bu kod tabanı, **Engine** (yerel C/C++) tarafından Android ve iOS için platforma özgü makine koduna dönüştürülür. Engine, **Dart VM**, **BoringSSL**, Skia vb. bileşenleri bir araya getirir ve **libflutter.so** (Android) veya **Flutter.framework** (iOS) olarak paylaşılan kütüphane olarak gönderilir. Tüm gerçek ağ iletişimi (DNS, soketler, TLS) **bu kütüphane içinde** gerçekleşir, *normal Java/Kotlin Swift/Obj-C katmanlarında* değil. Bu izole tasarım, normal Java düzeyindeki Frida kancalarının Flutter uygulamalarında başarısız olmasının nedenidir. + +## Flutter'da HTTPS trafiğini yakalamak + +Bu, bu [blog yazısının](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/) bir özetidir. + +### Neden HTTPS müdahalesi Flutter'da zordur +* **SSL/TLS doğrulaması iki katman aşağıda** BoringSSL'de yer alır, bu nedenle Java SSL-pinning atlamaları buna dokunmaz. +* **BoringSSL, libflutter.so içinde kendi CA deposunu** kullanır; Burp/ZAP CA'nızı Android'in sistem deposuna aktarmak hiçbir şeyi değiştirmez. +* libflutter.so'daki semboller **kaldırılmış ve bozulmuş**, dinamik araçlardan sertifika doğrulama işlevini gizler. + +### Tam Flutter yığınını parmak iziyle tanımlama +Sürümü bilmek, doğru ikili dosyaları yeniden oluşturmanıza veya desen eşleştirmenize olanak tanır. + +Adım | Komut / Dosya | Sonuç +----|----|---- +Anlık görüntü hash'ini al | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…` +Hash'ı → Engine ile eşleştir | reFlutter'daki **enginehash** listesi | Flutter 3 · 7 · 12 + engine commit `1a65d409…` +Bağımlı commit'leri çek | O engine commit'indeki DEPS dosyası | • `dart_revision` → Dart v2 · 19 · 6
• `dart_boringssl_rev` → BoringSSL `87f316d7…` + +[get_snapshot_hash.py burada](https://github.com/Impact-I/reFlutter/blob/main/scripts/get_snapshot_hash.py) bulun. + +### Hedef: `ssl_crypto_x509_session_verify_cert_chain()` +* **BoringSSL** içinde **`ssl_x509.cc`** dosyasında yer alır. +* **`bool` döner** – tüm sertifika zinciri kontrolünü atlamak için tek bir `true` yeterlidir. +* Aynı işlev her CPU mimarisinde mevcuttur; yalnızca opcode'lar farklıdır. + +### Seçenek A – **reFlutter** ile İkili yamanın +1. Uygulamanın Flutter sürümü için tam Engine ve Dart kaynaklarını **klonlayın**. +2. İki sıcak noktayı **Regex-yamanız**: +* `ssl_x509.cc` içinde, `return 1;` zorlayın. +* (İsteğe bağlı) `socket_android.cc` içinde, bir proxy'yi sabit kodlayın (`"10.0.2.2:8080"`). +3. libflutter.so'yu **yeniden derleyin**, APK/IPA'ya geri bırakın, imzalayın, yükleyin. +4. Yaygın sürümler için **önceden yamanmış derlemeler**, saatlerce derleme süresinden tasarruf etmek için reFlutter GitHub sürümlerinde gönderilmektedir. + +### Seçenek B – **Frida** ile Canlı kanca (“sert yol”) +Sembol kaldırıldığı için, yüklü modülün ilk baytlarını desen taraması yaparak bulur, ardından döndürme değerini anlık olarak değiştirirsiniz. +```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"); } +}); +``` +Çalıştır: +```bash +frida -U -f com.example.app -l bypass.js +``` +*Porting tips* +* **arm64-v8a** veya **armv7** için, Ghidra'dan fonksiyonun ilk ~32 baytını alın, boşlukla ayrılmış bir hex dizesine dönüştürün ve `sig` ile değiştirin. +* **Her Flutter sürümü için bir desen** saklayın, hızlı yeniden kullanım için bir kopya kağıdında depolayın. + +### Trafiği proxy'niz üzerinden zorlamak +Flutter kendisi **cihaz proxy ayarlarını** göz ardı eder. En kolay seçenekler: +* **Android Studio emülatörü:** Ayarlar ▶ Proxy → manuel. +* **Fiziksel cihaz:** kötü niyetli Wi-Fi AP + DNS sahtekarlığı veya Magisk modülü ile `/etc/hosts` düzenleme. + +## 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/)