
Flutter 리버스 엔지니어링 프레임워크

이 프레임워크는 이미 컴파일되어 앱 리패킹에 사용할 준비가 된 패치된 Flutter 라이브러리를 사용하여 Flutter 앱 리버스 엔지니어링을 돕습니다. 이 라이브러리는 스냅샷 역직렬화 프로세스가 수정되어 편리하게 동적 분석을 수행할 수 있습니다.
주요 기능:
socket.cc가 트래픽 모니터링 및 가로채기를 위해 패치됨;dart.cc가 클래스, 함수 및 일부 필드를 출력하도록 수정됨;Dockerfile을 사용하여 수동 Flutter 코드 변경이 지원됩니다.# Linux, Windows, MacOS
pip3 install reflutter
impact@f:~$ reflutter main.apk
Please enter your Burp Suite IP: <input_ip>
SnapshotHash: 8ee4ef7a67df9845fba331734198a953
The resulting apk file: ./release.RE.apk
Please sign the apk file
Configure Burp Suite proxy server to listen on *:8083
Proxy Tab -> Options -> Proxy Listeners -> Edit -> Binding Tab
Then enable invisible proxying in Request Handling Tab
Support Invisible Proxying -> true
impact@f:~$ reflutter main.ipa
Flutter 애플리케이션이 설치된 기기와 동일한 네트워크에 있는 Burp Suite 프록시 서버의 IP를 지정해야 합니다. 그런 다음 BurpSuite -> Listener Proxy -> Options 탭에서 프록시를 구성해야 합니다.
8083모든 인터페이스True
인증서를 설치할 필요가 없습니다. Android 기기에서는 루트 액세스도 필요하지 않습니다. reFlutter는 일부 Flutter 인증서 핀닝 구현을 우회할 수도 있습니다.
결과 APK는 정렬 및 서명되어야 합니다. uber-apk-signer를 사용합니다.
java -jar uber-apk-signer.jar --allowResign -a release.RE.apk.
DartVM을 통해 로드되는 코드를 확인하려면 기기에서 애플리케이션을 실행해야 합니다. 바이너리 검색을 사용하여 _kDartIsolateSnapshotInstructions(예: 0xB000)이 무엇인지 수동으로 찾아야 합니다. reFlutter는 덤프를 애플리케이션의 루트 폴더에 쓰고 파일과 폴더에 777 권한을 설정합니다. adb 명령으로 파일을 가져올 수 있습니다.
impact@f:~$ adb -d shell "cat /data/data/<PACKAGE_NAME>/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
}
}
reflutter main.ipa 명령 실행 후 생성된 IPA 파일을 사용합니다. DartVM을 통해 로드되는 코드를 확인하려면 기기에서 애플리케이션을 실행해야 합니다. reFlutter는 XCode의 콘솔 로그에 reflutter 태그로 출력합니다.

App.framework 및 libapp.so 감지 개선엔진은 Github Actions의 reFlutter를 사용하여 빌드되며, 원하는 버전, 커밋 및 스냅샷 해시는 이 테이블에서 사용됩니다.
스냅샷의 해시는 storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip에서 추출됩니다.
자체 패치를 구현하려면 특수 제작된 Docker를 사용하여 수동 Flutter 코드 변경이 지원됩니다.
sudo docker pull ptswarm/reflutter
# Linux, Windows
EXAMPLE BUILD 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 <disables building for x64 archiitechture, use to reduce building time>
-e arm=0 <disables building for arm archiitechture, use to reduce building time>
-e WAIT=300 <the amount of time in seconds you need to edit source code>
-e HASH_PATCH=[Snapshot_Hash] <here you need to specify snapshot hash which matches the engine_commit line of enginehash.csv table best. It is used for proper patch search in reFlutter and for successfull compilation>
-e COMMIT=[Engine_commit] <here you specify commit for your engine version, take it from enginehash.csv table or from flutter/engine repo>