
อ่านเพิ่มเติมเกี่ยวกับบล็อก: https://swarm.ptsecurity.com/fork-bomb-for-flutter/
เฟรมเวิร์กนี้ช่วยให้แอพพลิเคชั่นย้อนกลับทางวิศวกรรมโดยใช้ไลบรารี Flutter เวอร์ชันแพทช์ซึ่งรวบรวมแล้วและพร้อมสำหรับการบรรจุแอป ไลบรารีนี้มีกระบวนการ deserialization snapshot ที่แก้ไขเพื่อให้คุณทำการวิเคราะห์แบบไดนามิกในวิธีที่สะดวก
คุณสมบัติที่สำคัญ:
socket.cc ได้รับการแก้ไขสำหรับการตรวจสอบการจราจรและการสกัดกั้นdart.cc ได้รับการแก้ไขเพื่อพิมพ์คลาสฟังก์ชั่นและบางฟิลด์Dockerfile ที่สร้างขึ้นเป็นพิเศษ # Linux, Windows, MacOS
pip3 install reflutter==0.8.0
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 คุณต้องระบุ IP ของพร็อกซีเซิร์ฟเวอร์ Burp Suite ของคุณที่อยู่ในเครือข่ายเดียวกันกับที่อุปกรณ์ที่มีแอปพลิเคชัน Flutter ถัดไปคุณควรกำหนดค่าพร็อกซีใน BurpSuite -> Listener Proxy -> Options tab
8083All interfacesTrue 
คุณไม่จำเป็นต้องติดตั้งใบรับรองใด ๆ บนอุปกรณ์ 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
}
} ใช้ไฟล์ IPA ที่สร้างขึ้นหลังจากการดำเนินการของคำสั่ง reflutter main.ipa หากต้องการดูว่ารหัสใดที่โหลดผ่าน DARTVM คุณต้องเรียกใช้แอปพลิเคชันบนอุปกรณ์ Reflutter จะพิมพ์พา ธ ไฟล์ Dump ไปยังบันทึกคอนโซล XCode ด้วยแท็ก reflutter Current working dir: /private/var/mobile/Containers/Data/Application/<UUID>/dump.dart ถัดไปคุณจะต้องดึงไฟล์จากอุปกรณ์

การชดเชยผลลัพธ์จากการถ่ายโอนข้อมูลสามารถใช้ในสคริปต์ Frida
frida -U -f <package> -l frida.js
เพื่อให้ได้ค่าสำหรับ _kDartIsolateSnapshotInstructions คุณสามารถใช้ readelf -Ws libapp.so ค่าที่คุณต้องการในฟิลด์ Value อยู่ที่ไหน
App.framework และ libapp.so ภายใน zip archive เครื่องยนต์ถูกสร้างขึ้นโดยใช้ reflutter ในการกระทำของ GitHub เพื่อสร้างเวอร์ชันที่ต้องการการกระทำและแฮชสแน็ปช็อตถูกใช้จากตารางนี้ แฮชของสแน็ปช็อตถูกสกัดจาก storage.googleapis.com/flutter_infra_release/flutter/<hash>/android-arm64-release/linux-x64.zip

หากคุณต้องการใช้แพตช์ของคุณเองการเปลี่ยนแปลงรหัสการกระพือปีกด้วยตนเองได้รับการสนับสนุนโดยใช้นักเทียบท่าที่สร้างขึ้นเป็นพิเศษ
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ตัวอย่างสร้าง Android ARM64:
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 รอ = 300
-e hash_patch = [snapshot_hash]
-e commit = [engine_commit] <ที่นี่คุณระบุ commit สำหรับเวอร์ชันเครื่องยนต์ของคุณนำมาจาก table enginehash.csv หรือจาก flutter/repo repo> repo>