Flutter

Reading time: 3 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Flutter

Flutter to cross-platformowy zestaw narzędzi UI Google, który pozwala deweloperom pisać jedną bazę kodu w Dart, którą Engine (natywny C/C++) przekształca w specyficzny dla platformy kod maszynowy dla Androida i iOS. Engine łączy Dart VM, BoringSSL, Skia itp. i jest dostarczany jako wspólna biblioteka libflutter.so (Android) lub Flutter.framework (iOS). Cała rzeczywista komunikacja sieciowa (DNS, gniazda, TLS) odbywa się wewnątrz tej biblioteki, a nie w zwykłych warstwach Java/Kotlin Swift/Obj-C. Taki izolowany projekt jest powodem, dla którego zwykłe haki na poziomie Java nie działają w aplikacjach Flutter.

Przechwytywanie ruchu HTTPS w Flutter

To jest podsumowanie tego blog postu.

Dlaczego przechwytywanie HTTPS jest trudne w Flutter

  • Weryfikacja SSL/TLS znajduje się dwa poziomy niżej w BoringSSL, więc obejścia SSL-pinningu w Java go nie dotykają.
  • BoringSSL używa swojego własnego magazynu CA wewnątrz libflutter.so; importowanie swojego CA Burp/ZAP do systemowego magazynu Androida nic nie zmienia.
  • Symbole w libflutter.so są usunięte i zniekształcone, ukrywając funkcję weryfikacji certyfikatu przed dynamicznymi narzędziami.

Zidentyfikuj dokładny stos Flutter

Znajomość wersji pozwala na odbudowanie lub dopasowanie odpowiednich binariów.

StepCommand / FileOutcome
Get snapshot hashbash\npython3 get_snapshot_hash.py libapp.so\nadb4292f3ec25…
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.

Cel: ssl_crypto_x509_session_verify_cert_chain()

  • Znajduje się w ssl_x509.cc wewnątrz BoringSSL.
  • Zwraca bool – pojedyncze true wystarczy, aby obejść całą kontrolę łańcucha certyfikatów.
  • Ta sama funkcja istnieje na każdej architekturze CPU; różnią się tylko kody operacyjne.

Opcja A – Łatanie binarne z reFlutter

  1. Sklonuj dokładne źródła Engine i Dart dla wersji Flutter aplikacji.
  2. Regex-patch dwa gorące punkty:
  • W ssl_x509.cc, wymuś return 1;
  • (Opcjonalnie) W socket_android.cc, twardo zakoduj proxy ("10.0.2.2:8080").
  1. Rekompiluj libflutter.so, wrzuć z powrotem do APK/IPA, podpisz, zainstaluj.
  2. Wstępnie załatane wersje dla popularnych wersji są dostarczane w wydaniach reFlutter na GitHubie, aby zaoszczędzić godziny czasu budowy.

Opcja B – Żywe hakowanie z Frida (ścieżka "hard-core")

Ponieważ symbol jest usunięty, skanujesz wzór załadowanego modułu w poszukiwaniu jego pierwszych bajtów, a następnie zmieniasz wartość zwracaną w locie.

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

Przeprowadź to:

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

Porady dotyczące przenoszenia

  • Dla arm64-v8a lub armv7, pobierz pierwsze ~32 bajty funkcji z Ghidra, przekształć na ciąg szesnastkowy oddzielony spacjami i zastąp sig.
  • Zachowaj jeden wzór na każdą wersję Fluttera, przechowuj je w ściągawce dla szybkiego ponownego użycia.

Wymuszanie ruchu przez swój proxy

Flutter sam w sobie ignoruje ustawienia proxy urządzenia. Najprostsze opcje:

  • Emulator Android Studio: Ustawienia ▶ Proxy → ręczne.
  • Urządzenie fizyczne: złośliwy punkt dostępu Wi-Fi + spoofing DNS, lub edytowanie modułu Magisk /etc/hosts.

Odniesienia