
Framework di reverse engineering per Flutter

Questo framework aiuta nel reverse engineering di app Flutter utilizzando la versione patchata della libreria Flutter già compilata e pronta per il reimpacchettamento dell'app. Questa libreria ha il processo di deserializzazione degli snapshot modificato per consentire di eseguire analisi dinamiche in modo conveniente.
Caratteristiche principali:
socket.cc è patchato per il monitoraggio e l'intercettazione del traffico;dart.cc è modificato per stampare classi, funzioni e alcuni campi;Dockerfile appositamente realizzato.# Linux, Windows, MacOS
pip3 install reflutter
impact@f:~$ reflutter main.apk
Inserisci l'IP del tuo Burp Suite: <input_ip>
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
Il file apk risultante: ./release.RE.apk
Firma il file apk
Configura il server proxy Burp Suite in ascolto su *:8083
Proxy Tab -> Options -> Proxy Listeners -> Edit -> Binding Tab
Quindi abilita il proxy invisibile nella scheda Request Handling
Support Invisible Proxying -> true
impact@f:~$ reflutter main.ipa
Devi specificare l'IP del tuo server proxy Burp Suite situato nella stessa rete del dispositivo con l'app Flutter. Successivamente, configura il Proxy in BurpSuite -> Listener Proxy -> Options tab
8083All interfacesTrue
Non è necessario installare certificati. Su un dispositivo Android, non è necessario l'accesso root. reFlutter permette anche di bypassare alcune implementazioni di certificate pinning di Flutter.
L'apk risultante deve essere allineato e firmato. Io uso uber-apk-signer
java -jar uber-apk-signer.jar --allowResign -a release.RE.apk.
Per vedere quale codice viene caricato tramite DartVM, devi eseguire l'applicazione sul dispositivo. Nota che devi trovare manualmente a cosa corrisponde _kDartIsolateSnapshotInstructions (es. 0xB000) usando una ricerca binaria. reFlutter scrive il dump nella cartella root dell'applicazione e imposta i permessi 777 al file e alla cartella. Puoi estrarre il file con il comando adb
impact@f:~$ adb -d shell "cat /data/data/<NOME_PACCHETTO>/dump.dart" > dump.dart
Library:'package:anyapp/navigation/DeepLinkImpl.dart' Class: Navigation extends Object {
String* DeepUrl = anyapp://evil.com/ ;
Function 'Navigation.': constructor. (dynamic, dynamic, dynamic, dynamic) => NavigationInteractor {
Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000009270
}
Function 'initDeepLinkHandle':. (dynamic) => Future<void>* {
Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000412fe8
}
Function '_navigateDeepLink@547106886':. (dynamic, dynamic, {dynamic navigator}) => void {
Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000002638
}
}
Library:'package:anyapp/auth/navigation/AuthAccount.dart' Class: AuthAccount extends Account {
PlainNotificationToken* _instance = sentinel;
Function 'getAuthToken':. (dynamic, dynamic, dynamic, dynamic) => Future<AccessToken*>* {
Code Offset: _kDartIsolateSnapshotInstructions + 0x00000000003ee548
}
Function 'checkEmail':. (dynamic, dynamic) => Future<bool*>* {
Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000448a08
}
Function 'validateRestoreCode':. (dynamic, dynamic, dynamic) => Future<bool*>* {
Code Offset: _kDartIsolateSnapshotInstructions + 0x0000000000412c34
}
Function 'sendSmsRestorePassword':. (dynamic, dynamic) => Future<bool*>* {
Code Offset: _kDartIsolateSnapshotInstructions + 0x00000000003efb88
}
}
Usa il file IPA creato dopo l'esecuzione del comando reflutter main.ipa. Per vedere quale codice viene caricato tramite DartVM, devi eseguire l'applicazione sul dispositivo. reFlutter stampa il suo output nei log della console in XCode con il tag reflutter.

App.framework e libapp.so all'interno dell'archivio zipI motori sono compilati usando reFlutter in Github Actions per compilare la versione desiderata; commit e hash degli snapshot sono presi da questa tabella.
L'hash dello snapshot è estratto da storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip
Se desideri implementare le tue patch, la modifica manuale del codice Flutter è supportata utilizzando un Docker appositamente realizzato.
sudo docker pull ptswarm/reflutter
# Linux, Windows
ESEMPIO COMPILAZIONE ANDROID ARM64:
sudo docker run -e WAIT=300 -e x64=0 -e arm=0 -e HASH_PATCH=<Snapshot_Hash> -e COMMIT=<Engine_commit> --rm -iv${PWD}:/t ptswarm/reflutter
FLAGS:
-e x64=0 <disabilita la compilazione per architettura x64, usa per ridurre i tempi di compilazione>
-e arm=0 <disabilita la compilazione per architettura arm, usa per ridurre i tempi di compilazione>
-e WAIT=300 <la quantità di tempo in secondi necessaria per modificare il codice sorgente>
-e HASH_PATCH=[Snapshot_Hash] <qui devi specificare l'hash dello snapshot che corrisponde meglio alla riga engine_commit della tabella enginehash.csv. Viene usato per la corretta ricerca delle patch in reFlutter e per una compilazione riuscita>
-e COMMIT=[Engine_commit] <qui specifica il commit per la tua versione del motore, prendilo dalla tabella enginehash.csv o dal repository flutter/engine>