79 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Flutter
{{#include ../../banners/hacktricks-training.md}}
# Flutter
Flutter — це **крос-платформений UI набір інструментів від Google**, який дозволяє розробникам писати єдину кодову базу на Dart, яку **Engine** (рідний C/C++) перетворює на машинний код, специфічний для платформ Android та iOS.
Engine об'єднує **Dart VM**, **BoringSSL**, Skia тощо, і постачається як спільна бібліотека **libflutter.so** (Android) або **Flutter.framework** (iOS). Вся фактична мережна діяльність (DNS, сокети, TLS) відбувається **всередині цієї бібліотеки**, *а не* в звичних шарах Java/Kotlin Swift/Obj-C. Це ізольоване проектування є причиною, чому звичайні Java-рівневі Frida хуки не працюють на Flutter додатках.
## Перехоплення HTTPS трафіку в Flutter
Це резюме цього [блог-посту](https://sensepost.com/blog/2025/intercepting-https-communication-in-flutter-going-full-hardcore-mode-with-frida/).
### Чому перехоплення HTTPS є складним у Flutter
* **Перевірка SSL/TLS знаходиться на два шари нижче** в BoringSSL, тому обхід Java SSL-пінінгу її не торкається.
* **BoringSSL використовує свій *власний* CA магазин** всередині libflutter.so; імпорт вашого Burp/ZAP CA в системний магазин Android нічого не змінює.
* Символи в libflutter.so **виключені та спотворені**, приховуючи функцію перевірки сертифіката від динамічних інструментів.
### Визначення точної стеки Flutter
Знання версії дозволяє вам відновити або зіставити правильні бінарні файли.
Крок | Команда / Файл | Результат
----|----|----
Отримати хеш знімка | ```bash\npython3 get_snapshot_hash.py libapp.so\n``` | `adb4292f3ec25…`
Сопоставити хеш → 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` достатньо, щоб обійти всю перевірку ланцюга сертифікатів.
* Така ж функція існує на кожній архітектурі ЦП; лише опкоди відрізняються.
### Варіант A Бінарне патчування з **reFlutter**
1. **Клонувати** точні джерела Engine та Dart для версії Flutter додатку.
2. **Regex-патч** двох гарячих точок:
* У `ssl_x509.cc`, примусити `return 1;`
* (Необов'язково) У `socket_android.cc`, жорстко закодувати проксі (`"10.0.2.2:8080"`).
3. **Перекомпілювати** libflutter.so, повернути його назад в APK/IPA, підписати, встановити.
4. **Попередньо патчовані збірки** для загальних версій постачаються в релізах reFlutter на GitHub, щоб заощадити години часу на збірку.
### Варіант B Живе хукування з **Frida** (шлях "хард-кор")
Оскільки символ виключений, ви скануєте завантажений модуль на предмет його перших байтів, а потім змінюєте значення повернення на льоту.
```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 байти функції з Ghidra, перетворіть на рядок шістнадцяткових чисел, розділених пробілами, і замініть `sig`.
* Зберігайте **один шаблон на кожен реліз Flutter**, зберігайте їх у шпаргалці для швидкого повторного використання.
### Примус трафіку через ваш проксі
Flutter сам по собі **ігнорує налаштування проксі пристрою**. Найпростіші варіанти:
* **Емулятор Android Studio:** Налаштування ▶ Проксі → вручну.
* **Фізичний пристрій:** злий Wi-Fi AP + спуфінг DNS, або редагування модуля 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/)
{{#include ../../banners/hacktricks-training.md}}