Research on Reverse Technology of fluent app

Introduction to Flutter

Flutter is a mobile application development framework launched and open-source by Google, focusing on cross platform, high fidelity and high performance. Developers can develop apps through Dart language, and a set of code can run on iOS and Android platforms at the same time. Flutter provides rich components and interfaces, and developers can quickly add native extensions to flutter. At the same time, fluent also uses the native engine to render the view.

"Actual combat of Flutter"

Flutter grab

  1. Disable Flutter SSL

Principle: Hook session_verify_cert_chain returns 0x1

function hook_ssl_verify_result(address){
  Interceptor.attach(address, {
    onEnter: function(args) {
    },

    onLeave: function(retval){
      retval.replace(0x1);
      console.log('Retval: ' + retval + " Done...");
    }
  });
}
/**
 *  frida -U xxx -l hook_ssl_verify_result.js 
 *  You need to actively call this function disablePinning()
 */
function disablePinning(){
  var m = Process.findModuleByName('libflutter.so');
  // 32-bit so
  var pattern = '2d e9 f0 4f a3 b0 81 46 50 20 10 70'
  // 64 bit so
  // var pattern = "FF 03 05 D1 FD 7B 0F A9 9A E3 05 94 08 0A 80 52 48 00 00 39 16 54 40 F9 56 07 00 B4 C8 02 40 F9 08 07 00 B4";
  var res = Memory.scan(m.base, m.size, pattern, {
    onMatch: function(address, size) {
      hook_ssl_verify_result(address.add(0x01));
    },

    onError: function(reason){
      console.log('[!] There was an error scanning memory');
    },

    onComplete: function(){
      console.log('[*] DisablePinning All done ...');
    }

  });
}
  1. Traffic proxy forwarding

    Drony.apk

    Slide right to enter settings - > select network WiFi - > set host name and port
    (Note: there is no need to modify Wi Fi configuration manually)

    ->Filter default value: select filter all - > Edit filter rule (+, local agent connect all, select application, save)

  2. Packet capture analysis

    Burp - > proxy - > Options - > Add - > host and port
    Note: you need to install the burp certificate into the system certificate

Fluent reverse analysis

tool

darter:Dart snapshot parser

Doldrums
Parse libapp So class symbols, function offset values, etc., without specific code, can only be used for auxiliary analysis

Android

IOS

  1. Reverse analysis auxiliary script

Frida_Hook_Ios_Flutter.js

  1. backward analysis

Fluent compiles Dart language into native arm code. For details, please refer to Deeply understand the compilation principle and optimization of fluentFluent machine code generation gen_snapshot.
Use MachOView to view the final app from dart code The symbol table in the framework is as follows, which does not contain useful business function information.

At the same time, the author has not found a reverse tool for fluent app, the reverse ecology is not perfect, and it is difficult to reverse for fluent app. stay Shuttle app reverse In this article, taking the Hello world code block as an example, the author analyzes Dart sdk, snapshot analysis and RawOject, which provides ideas for the reverse of fluent app.

In view of the current challenges of reverse shuttle, it is difficult to analyze its business code logic. Therefore, when meeting the general development specifications, the consideration of additional security measures for Dart can be postponed, but it needs continuous attention.

At the same time, in the process of analyzing the Flutter architecture, the author found that the useful information related to the application can be peeped through the Flutter Plugin, so we need to pay attention to the rational use of the channel.

Flutter Plugin

Flutter Plugin is the primary communication channel between fulter and.
On the fluent side, the MethodChannel API can send messages corresponding to method calls.
On the host platform iOS, FlutterMethodChannel iOS API You can receive method calls and return results to call iOS native code. Such as the keychain used to store sensitive data( flutter_secure_storage ), authentication related functions TouchID and FaceID( local_auth ), apple login( flutter_apple_sign_in Plugin),SSL Pinning(ssl_pinning_plugin )Wait for Plugin.

Because the FlutterMethodChannel is implemented by OC, you can hook the call of this class in the way of hook OC, so as to obtain possible useful information at runtime.

Flutter Plugin hook

Check the Flutter

When the APP is running, the application will load the required modules, listed by the author's demo app. The loaded modules are:

/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Runner
/Library/MobileSubstrate/MobileSubstrate.dylib
/usr/lib/libsqlite3.dylib
/System/Library/Frameworks/AVFoundation.framework/AVFoundation
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/FMDB.framework/FMDB
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/Flutter.framework/Flutter
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/MTBBarcodeScanner.framework/MTBBarcodeScanner
/System/Library/Frameworks/QuartzCore.framework/QuartzCore
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/ai_barcode.framework/ai_barcode
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/device_info.framework/device_info
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/flutter_custom_dialog.framework/flutter_custom_dialog
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/flutter_secure_storage.framework/flutter_secure_storage
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/package_info.framework/package_info
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/path_provider.framework/path_provider
/private/var/containers/Bundle/Application/70288CAB-186A-453E-8FBA-B00FEF608CC0/Runner.app/Frameworks/sqflite.framework/sqflite

In frames / fluent Framework / flutermmodule is the entry point. By checking whether the module is loaded, we can judge whether the application adopts Flutter technology.

function hasFlutter() {
    var modules = Process.enumerateModules()
    for (var i = 0; i < modules.length; i++) {
        var oneModule = modules[i]
        if (oneModule.path.endsWith('flutter')) {
            return true
        }
    }
    return false
}

hook plugin

The following codes are used Frida Frame, hook.

//code from https://gist.github.com/AICDEV/630feed7583561ec9f9421976e836f90

// https://api.flutter.dev/objcdoc/Classes/FlutterMethodChannel.html#/c:objc(cs)FlutterMethodChannel(im)invokeMethod:arguments:
function traceFlutterMethodCall() {
    var className = "FlutterMethodCall"
    var methodName = "+ methodCallWithMethodName:arguments:"
    var hook = ObjC.classes[className][methodName];

    try {
        Interceptor.attach(hook.implementation, {
            onEnter: function (args) {
                this.className = ObjC.Object(args[0]).toString();
                this.methodName = ObjC.selectorAsString(args[1]);
                console.log(this.className + ":" + this.methodName);
                console.log("method: " + ObjC.Object(args[2]).toString());
                console.log("args: " + ObjC.Object(args[3]).toString());
            }
        })
    } catch (err) {
        console.log("error in trace FlutterMethodCall");
        console.log(err);
    }
}

Flutter methodcall is the class name and "+ methodCallWithMethodName:arguments:" is the method name. This information can be found on the Official documents Found in; It can also be obtained by traversing all flutter related functions through frida tool; It can also be viewed using tools such as MachOView.

In the Demo app, the author uses flutter_secure_storage Plugin implements the write operation to keychain. The code is as follows:

SecureStorage.set("key", "AF4ItDx/2aUDKDk/s+Mdi3aGUJ0wTmMRBvMzMEg/yor6dGiQUEPDypQx5vNnfa+/")

Through frida hook FlutterMethodCall, the output is as follows:

FlutterMethodCall:methodCallWithMethodName:arguments:
method: write
args: {
    key = "key";
    options = "<null>";
    value = "AF4ItDx/2aUDKDk/s+Mdi3aGUJ0wTmMRBvMzMEg/yor6dGiQUEPDypQx5vNnfa+/";
}

reference resources

Flutter_iOS_ security

Keywords: Flutter

Added by fxmzb123 on Mon, 24 Jan 2022 22:36:50 +0200