- Download apktool from https://ibotpeaches.github.io/Apktool/
- Unpack apk file:
java -jar /home/expert/work/tools/apktool.jar d [email protected]
- Modify AndroidManifest.xml by adding
android:networkSecurityConfig="@xml/network_security_config"
attribute toapplication
element. - Create file /res/xml/network_security_config.xml with following content:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
- Build patched apk:
java -jar /home/expert/work/tools/apktool.jar b flixster -o flixster_patched.apk
- If you see error 'android:localeConfig in Manifest' see iBotPeaches/Apktool#2756 (comment)
- If you see followint error try running
java -jar /home/expert/work/tools/apktool.jar empty-framework-dir --force
or runb
command with parameter--use-aapt2
W: invalid resource directory name: /home/expert/Downloads/Zzzzzz/Zzzzzz_v0.0.0/res navigation
brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [/tmp/brut_util_Jar_5815054990385134498.tmp, p, --forced-package-id, 127, --min-sdk-version, 23, --target-sdk-version, 29, --version-code, 226000400, --version-name, 226.000.0, --no-version-vectors, -F, /tmp/APKTOOL14466004687895005947.tmp, -e, /tmp/APKTOOL4388243966604401097.tmp, -0, arsc, -I, /home/expert/.local/share/apktool/framework/1.apk, -S, /home/expert/Downloads/Zzzzzz/Zzzzzz_v0.0.0/res, -M, /home/expert/Downloads/Zzzzzz/Zzzzzz_v0.0.0/AndroidManifest.xml]
Generate keys to sign apk:keytool -genkey -alias keys -keystore keys -keyalg RSA -keysize 2048 -validity 10000 # password
Sign apk file:jarsigner -verbose -keystore keys /home/expert/Downloads/lancet/flixster_patched.apk keys
- Old method of signing with jarsigner produces apk that new version of Android refuses to install. Please use:
java -jar uber-apk-signer.jar --apks /path/to/apks
from here. - If necessary convert apk to jar for further analysis:
d2j-dex2jar.sh [email protected]
- To find what cyphers suites are supported by remote server calls:
nmap --script ssl-enum-ciphers -p 443 youtubei.googleapis.com
orsslscan youtubei.googleapis.com
- To check what cypher suites your client supports query https://www.howsmyssl.com/a/check
Problem with Flutter app is: it won’t trust a user installed root cert. This a problem for pentesting, and someone made a note on how to patch the binary (either directly or using Frida) to workaround this problem. Quoting TLDR of this blog post:
- Flutter uses Dart, which doesn’t use the system CA store
- Dart uses a list of CA’s that’s compiled into the application
- Dart is not proxy aware on Android, so use ProxyDroid with iptables
- Hook the session_verify_cert_chain function in x509.cc to disable chain validation
By recompiling the Flutter engine, this can be done easily. We just modify the source code as-is (third_party/boringssl/src/ssl/handshake.cc), without needing to find assembly byte patterns in the compiled code.
Luckily we don't have to do it manually. You can make Flutter app trust any certificate by doing the following:
- install adb
/home/expert/work/tools/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=/home/expert/work/tools/android-sdk/ --update
/home/expert/work/tools/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=/home/expert/work/tools/android-sdk/ --list
/home/expert/work/tools/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=/home/expert/work/tools/android-sdk/ "platform-tools"
export ANDROID_HOME=/home/expert/work/tools/android-sdk
export PATH="$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH"
- connect your android device and check its platform by calling
adb shell getprop ro.product.cpu.abi
. For me, it'sarm64-v8a
; - download Frida gadget
frida-gadget-VERSION-android-ARCH.so.xz
for your platform from here; - unpack your apk. you should see
/lib/arm64-v8a/libapp.so
and/lib/arm64-v8a/libflutter.so
; - unpack frida gadget file under name
/lib/arm64-v8a/libfrida-gadget.so
; - now you need to force Android app to initialize this library on start. Find entry point activity. It's usually somewhere like
/smali/com/company/product/app/MainActivity.smali
; - typically you'll see constructor like this
.method public constructor <init>()V
.locals 0
invoke-direct {p0}, Lio/flutter/embedding/android/e;-><init>()V
return-void
.end method
- add two new strings at the end of the method
.method public constructor <init>()V
.locals 0
invoke-direct {p0}, Lio/flutter/embedding/android/e;-><init>()V
const-string v0, "frida-gadget"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
return-void
.end method
- Repack and sign the .apk as always;
- Install it via adb by calling
adb install ./apks/patched-aligned-debugSigned.apk
; - Launch the app on the phone and make sure it's working;
- Install Frida tools via
pip install frida-tools
. In my case it was installed into/home/USERNAME/.local/bin/
; - Make sure frida is working by calling
frida-ps -Uai
. Note name of your app in the output; - Test that frida gadget is initialized by your Android app by trying to trace it via
frida-trace -U -i open APP_NAME
; - Checkout sources of https://github.com/NVISOsecurity/disable-flutter-tls-verification
- Launch TLS patcher via
frida -U -l disable-flutter-tls.js APP_NAME
; - From this moment you should be able to see HTTPS traffic in your sniffer app (Charles or mitm).
Decompiling Dart/Flutter apps is pretty hard right now. So if Android app uses tricky signature generation code for its API calls your only option is decompiling libapp.so
using tools like IDA Pro. I tried using Doldrums but looks like it needs update for every Dart release (version hashes are here).
Random articles about reverse engineering Flutter apps:
- https://blog.nviso.eu/2022/08/18/intercept-flutter-traffic-on-ios-and-android-http-https-dio-pinning/
- https://blog.nviso.eu/2020/05/20/intercepting-flutter-traffic-on-android-x64/
- https://tinyhack.com/category/reverse-engineering/
- https://blog.tst.sh/reverse-engineering-flutter-apps-part-1/
- https://blog.tst.sh/reverse-engineering-flutter-apps-part-2/
- https://www.guardsquare.com/blog/current-state-and-future-of-reversing-flutter-apps
- https://cryptax.medium.com/reversing-an-android-sample-which-uses-flutter-23c3ff04b847
- https://fadeevab.com/frida-gadget-injection-on-android-no-root-2-methods/
- https://github.com/Storyyeller/Krakatau
Thanks for these instructions!