
Flutter 엔진 라이브러리를 패치하여, 루트나 인증서 설치 없이 Android 및 iOS 앱에서 런타임 리버스 엔지니어링, 트래픽 가로채기, SSL 고정 우회를 가능하게 합니다.

블로그에서 더 알아보기: https://swarm.ptsecurity.com/fork-bomb-for-flutter/
이 프레임워크는 이미 컴파일되어 앱 리패킹이 가능한 패치된 버전의 Flutter 라이브러리를 사용하여 Flutter 앱 리버스 엔지니어링을 지원합니다. 이 라이브러리는 스냅샷 역직렬화 과정이 수정되어 있어 편리한 방식으로 동적 분석을 수행할 수 있습니다.
주요 기능:
socket.cc가 트래픽 모니터링 및 가로채기를 위해 패치됨;dart.cc가 클래스, 함수 및 일부 필드를 출력하도록 수정됨;Dockerfile을 사용하여 수동 Flutter 코드 변경이 지원됨.# Linux, Windows, MacOS
pip3 install reflutter==0.8.6
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
impact@f:~$ reflutter main.ipa
옵션:
-p, --patch-dump — 덤프 모드: 시작 시 dump.dart(클래스/메서드/오프셋)를 출력하도록 엔진을 패치하고, 프록시 지침 대신 frida.js 힌트를 출력합니다.-n, --no-interact — Burp IP를 묻지 않음(127.0.0.1을 암시); CI에서 구형 엔진에 유용합니다.-b <Snapshot_Hash>, --build-engine — 엔진 빌드 모드: 스냅샷 해시에 대한 엔진 커밋을 출력하고 (flutter/flutter 체크아웃 내에서 실행될 때) reFlutter 소스 패치를 적용합니다. scripts/local-release를 참조하세요.Flutter 애플리케이션이 설치된 기기와 동일한 네트워크에 위치한 Burp Suite 프록시 서버의 IP를 지정해야 합니다. 그런 다음 BurpSuite -> Listener Proxy -> Options tab에서 프록시를 구성하세요:
8083All interfacesTrue
Android의 경우 인증서 설치나 루트 권한이 필요하지 않습니다. reFlutter는 일부 Flutter 인증서 피닝 구현을 우회하는 것도 가능하게 합니다.
⚠️ 참고: Flutter 3.24.x (스냅샷 해시
80a49c7111088100a233b2ae788e1f48)까지의 엔진은 여전히 하드코딩된 프록시 IP를 포함하고 있으며 제자리에서 패치됩니다. 3.27.x부터는 하드코딩된 IP가 제거되었으므로, 대신 기기에서 직접 프록시를 구성하세요.
ADB를 사용하여 기기의 프록시를 구성하세요:
adb -s <device> shell "settings put global http_proxy <proxy_ip:port>"
APK에 서명하고, 정렬하고, 설치하세요. 선택적으로 TunProxy를 구성하여 트래픽을 Burp Suite를 통해 라우팅할 수 있습니다.
IPA에 서명하고 설치하세요. Potatso를 구성하여 Burp Suite 프록시 서버를 사용하도록 설정하세요.
결과 apk는 정렬되고 서명되어야 합니다. 권장 도구는 uber-apk-signer입니다:
java -jar uber-apk-signer.jar --allowResign -a release.RE.apk
기기에서 앱을 실행하세요. 이진 검색을 통해 _kDartIsolateSnapshotInstructions를 확인하세요. reFlutter는 덤프 파일을 앱의 루트 폴더에 작성하고 777 권한을 설정합니다. 다음을 사용하여 가져오세요:
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/ ;
...
reflutter main.ipa를 실행한 후 기기에서 앱을 실행하세요. 덤프 파일 경로가 Xcode 콘솔 로그에 출력됩니다:
Current working dir: /private/var/mobile/Containers/Data/Application/<UUID>/dump.dart
기기에서 파일을 가져오세요.

frida-tools==13.7.1
frida==16.7.19
Frida 스크립트에서 덤프 오프셋을 사용하세요:
frida -U -f <package> -l frida.js
_kDartIsolateSnapshotInstructions를 찾으려면:
readelf -Ws libapp.so
Value 필드를 찾으세요.
App.framework 및 libapp.so 감지 개선엔진은 enginehash.csv의 데이터를 기반으로 scripts/local-release (macOS; iOS 및 Android arm64/arm/x64용 v2 + v3를 빌드하고, 모든 패치가 적용되었는지 확인하고, 릴리스 자산을 업로드함)로 빌드됩니다. 스냅샷 해시에 대한 엔진 커밋은 reflutter -b <Snapshot_Hash>를 통해 확인됩니다. 스냅샷 해시는 다음에서 가져옵니다:
https://storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip
Docker를 사용하여 수동 Flutter 코드 패칭이 지원됩니다:
git clone https://github.com/Impact-I/reFlutter && cd reFlutter
docker build -t reflutter -f Dockerfile .
다음으로 실행:
docker run -it -v "$(pwd):/t" -e HASH_PATCH=<Snapshot_Hash> -e COMMIT=<Engine_commit> reflutter
예시:
docker run -it -v "$(pwd):/t" -e HASH_PATCH=aa64af18e7d086041ac127cc4bc50c5e -e COMMIT=d44b5a94c976fbb65815374f61ab5392a220b084 reflutter
docker run -e WAIT=300 -e x64=0 -e arm=0 -e HASH_PATCH=<Snapshot_Hash> -e COMMIT=<Engine_commit> --rm -iv${PWD}:/t reflutter
플래그:
-e x64=0: x64 빌드 비활성화-e arm64=0: arm64 빌드 비활성화-e arm=0: arm32 빌드 비활성화-e WAIT=300: 빌드 전 소스 수정 시간(초)-e HASH_PATCH: enginehash.csv의 스냅샷 해시-e COMMIT: 엔진 커밋 해시