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
cf1033bbce
commit
51865b6f49
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 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](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/).
|
||||
|
||||
### 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.
|
||||
|
||||
Step | Command / File | Outcome
|
||||
----|----|----
|
||||
Get snapshot hash | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `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…`
|
||||
|
||||
Find [get_snapshot_hash.py here](https://github.com/Impact-I/reFlutter/blob/main/scripts/get_snapshot_hash.py).
|
||||
|
||||
### 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"`).
|
||||
3. **Rekompiluj** libflutter.so, wrzuć z powrotem do APK/IPA, podpisz, zainstaluj.
|
||||
4. **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
|
||||
- [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