Lucene search

K
kitploitKitPloitKITPLOIT:7762549450716884798
HistoryJan 17, 2022 - 8:30 p.m.

reFlutter - Flutter Reverse Engineering Framework

2022-01-1720:30:00
www.kitploit.com
266
reflutter
reverse engineering
flutter
dynamic analysis
traffic interception
android
ios
manual patches
burp suite
certificate pinning

AI Score

7.5

Confidence

High

This framework helps with Flutter apps reverse engineering using the patched version of the Flutter library which is already compiled and ready for app repacking. This library has snapshot deserialization process modified to allow you perform dynamic analysis in a convenient way.

Key features:

  • socket.cc is patched for traffic monitoring and interception;
  • dart.cc is modified to print classes, functions and some fields;
  • contains minor changes for successfull compilation;
  • if you would like to implement your own patches, there is manual Flutter code change is supported using specially crafted Dockerfile

Supported engines

  • Android: arm64, arm32;
  • iOS: arm64;
  • Release: Stable, Beta

Install

# Linux, Windows, MacOS  
pip3 install reflutter  

Usage

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">

impact@f:~$ reflutter main.apk  
  
Please enter your Burp Suite IP: &lt;input_ip&gt;  
  
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 -&gt; Options -&gt; Proxy Listeners -&gt; Edit -&gt; Binding Tab  
  
Then enable invisible proxying in Request Handling Tab  
Support Invisible Proxying -&gt; true  
  
impact@f:~$ reflutter main.ipa

Traffic interception

You need to specify the IP of your Burp Suite Proxy Server located in the same network where the device with the flutter application is. Next, you should configure the Proxy in BurpSuite -&gt; Listener Proxy -&gt; Options tab

  • Add port: 8083
  • Bind to address: All interfaces
  • Request handling: Support invisible proxying = True

You don’t need to install any certificates. On an Android device, you don’t need root access as well. reFlutter also allows to bypass some of the flutter certificate pinning implementations.

Usage on Android

The resulting apk must be aligned and signed. I use uber-apk-signer java -jar uber-apk-signer.jar --allowResign -a release.RE.apk. To see which code is loaded through DartVM, you need to run the application on the device. reFlutter prints its output in logcat with the reflutter tag

impact@f:~$ adb logcat -e reflutter | sed 's/.*DartVM//' &gt;&gt; reflutter.txt

code output

Library:'package:anyapp/navigation/DeepLinkImpl.dart' Class: Navigation extends Object {    
  
String* DeepUrl = anyapp://evil.com/ ;  
  
 Function 'Navigation.': constructor. (dynamic, dynamic, dynamic, dynamic) =&gt; NavigationInteractor {   
    
                   }  
      
 Function 'initDeepLinkHandle':. (dynamic) =&gt; Future&lt;void&gt;* {   
    
                   }  
      
 Function '_navigateDeepLink@547106886':. (dynamic, dynamic, {dynamic navigator}) =&gt; void {   
  
                   }  
   
       }  
   
Library:'package:anyapp/auth/navigation/AuthAccount.dart' Class: AuthAccount extends Account {  
  
PlainNotificationToken* _instance = sentinel;  
   
 Function 'getAuthToken':. (dynamic, dynamic, dynamic, dynamic) =&gt; Future&lt;AccessToken*&gt;* {   
  
                   }  
    
 Function 'checkEmail':. (dynamic, dynamic) =&gt; Future&lt;bool*&gt;* {   
   
                   }&lt;   br/&gt;  
 Function 'validateRestoreCode':. (dynamic, dynamic, dynamic) =&gt; Future&lt;bool*&gt;* {   
   
                   }  
  
 Function 'sendSmsRestorePassword':. (dynamic, dynamic) =&gt; Future&lt;bool*&gt;* {   
  
                   }  
       }

Usage on iOS

Use the IPA file created after the execution of reflutter main.ipa command. To see which code is loaded through DartVM, you need to run the application on the device. reFlutter prints its output in console logs in XCode with the reflutter tag.

To Do

  • Display absolute code offset for functions;
  • Extract more strings and fields;
  • Add socket patch;
  • Extend engine support to Debug using Fork and Github Actions;
  • Improve detection of App.framework and libapp.so inside zip archive

Build Engine

The engines are built using reFlutter in Github Actions to build the desired version, commits and snapshot hashes are used from this table. The hash of the snapshot is extracted from storage.googleapis.com/flutter_infra_release/flutter/&lt;hash&gt;/android-arm64-release/linux-x64.zip

release

Custom Build

If you would like to implement your own patches, manual Flutter code change is supported using specially crafted Docker

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=&lt;Snapshot_Hash&gt; -e COMMIT=&lt;Engine_commit&gt; --rm -iv${PWD}:/t ptswarm/reflutter  
  
FLAGS:  
    -e x64=0                         &lt;disables building for x64 archiitechture, use to reduce building time&gt;  
    -e arm=0                         &lt;disables building for arm archiitechture, use to reduce building time&gt;  
    -e WAIT=300                      &lt;the amount of time in seconds you need to edit source code&gt;  
    -e HASH_PATCH=[Snapshot_Hash]    &lt;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&gt;  
    -e COMMIT=[Engine   _commit]        &lt;here you specify commit for your engine version, take it from enginehash.csv table or from flutter/engine repo&gt;  

Download reFlutter

AI Score

7.5

Confidence

High