├── README.md └── flutter_ssl_pinning_bypass.sh /README.md: -------------------------------------------------------------------------------- 1 | # Flutter APK SSL Certificate Validation Disabler 2 | 3 | This script disables SSL certificate validation in a Flutter application by modifying the APK file and injecting a Frida hook. This can be useful for testing purposes where you need to bypass SSL pinning. 4 | 5 | ## Prerequisites 6 | 7 | - `apktool`: Tool to decompile and recompile APK files. 8 | - `strings`: Command to extract printable strings from a binary. 9 | - `objdump`: Command to display information from object files. 10 | - `adb`: Android Debug Bridge, a versatile command-line tool for interacting with Android devices. 11 | - `frida`: Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. 12 | 13 | ## Usage 14 | 15 | ### Arguments 16 | 17 | 1. `APK_PATH`: Path to the APK file to be decompiled and modified. 18 | 2. `APKTOOL_PATH`: Path to the `apktool` JAR file. 19 | 3. `APP_PACKAGE_NAME`: Package name of the application to be tested. 20 | 21 | ### Example 22 | 23 | ```sh 24 | ./flutter_ssl_pinning_bypass.sh /path/to/app.apk /path/to/apktool.jar com.example.app 25 | ``` 26 | 27 | ## Script Details 28 | 29 | 1. **Setup and Variables:** 30 | - The script sets the options `-e` (exit on error) and `-x` (print commands). 31 | - Variables are initialized for paths and filenames. 32 | 33 | 2. **Decompile the APK:** 34 | - Uses `apktool` to decompile the APK to a temporary directory. 35 | 36 | 3. **Find SSL Client and Server Addresses:** 37 | - Extracts SSL client and server addresses from the `libflutter.so` file using `strings`. 38 | 39 | 4. **Disassemble the Shared Library:** 40 | - Disassembles the `libflutter.so` file to a text file. 41 | 42 | 5. **Calculate SSL Function Offset:** 43 | - Extracts the offset of the SSL function start address and converts it to a hexadecimal format. 44 | - Calculates the offset between the SSL function and the `JNI_OnLoad` function. 45 | 46 | 6. **Generate Frida Script:** 47 | - Creates a Frida script (`script.js`) to hook and disable SSL certificate validation. 48 | 49 | 7. **Download and Setup Frida Server:** 50 | - Downloads the Frida server for Android and sets it up on the device. 51 | 52 | 8. **Run Frida with the Script:** 53 | - Uses Frida to inject the script into the specified application. 54 | 55 | ## Notes 56 | 57 | - Ensure your Android device is connected and ADB is set up properly. 58 | - Running this script requires root access on the Android device. 59 | - This script is intended for testing and educational purposes only. Use responsibly. 60 | -------------------------------------------------------------------------------- /flutter_ssl_pinning_bypass.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | APK_PATH=$1 7 | APKTOOL_PATH=$2 8 | APP_PACKAGE_NAME=$3 9 | 10 | DECOMPILED_APK_PATH="/tmp/apk_decompiled" 11 | 12 | java -jar $APKTOOL_PATH d $APK_PATH -o $DECOMPILED_APK_PATH -f 13 | 14 | SO_FILE="${DECOMPILED_APK_PATH}/lib/x86_64/libflutter.so" 15 | 16 | SSL_CLIENT_ADDRESS=$(strings -a -t x ${SO_FILE} | grep -E "ssl_client" | awk -F' ' '{print $1}') 17 | SSL_SERVER_ADDRESS=$(strings -a -t x ${SO_FILE} | grep -E "ssl_server" | awk -F' ' '{print $1}') 18 | 19 | DISSASEMBLY_FILE_PATH="/tmp/disassembly.txt" 20 | 21 | (objdump -d $SO_FILE > $DISSASEMBLY_FILE_PATH) 22 | 23 | ssl_offset=$(grep -E "${SSL_CLIENT_ADDRESS}|${SSL_SERVER_ADDRESS}" $DISSASEMBLY_FILE_PATH | head -1| awk -F ' ' '{print $1}') 24 | echo $ssl_offset 25 | 26 | ssl_offset_hex="0x${ssl_offset%:}" 27 | ssl_function_start_offset="-0x10a" 28 | 29 | echo ${ssl_offset_hex} $ssl_function_start_offset 30 | 31 | ssl_function_start_address_decimal=$(($((ssl_offset_hex))+$((ssl_function_start_offset)))) 32 | ssl_function_start_address=$(printf "0x%x\n" $ssl_function_start_address_decimal) 33 | 34 | jni_onload_address=0x$(objdump -T ${SO_FILE} | tail -n 3 | awk -F' ' '{print $1}') 35 | 36 | ssl_function_offset_decimal=$(($((ssl_function_start_address))-$((jni_onload_address)))) 37 | ssl_function_offset=$(printf "0x%x\n" $ssl_function_offset_decimal) 38 | echo $ssl_function_offset 39 | 40 | cat < script.js 41 | function hook_ssl_crypto_x509_session_verify_cert_chain(address){ 42 | Interceptor.attach(address, { 43 | onEnter: function(args) { console.log("Disabling SSL certificate validation") }, 44 | onLeave: function(retval) { console.log("Retval: " + retval); retval.replace(0x1);} 45 | }); 46 | } 47 | function disable_certificate_validation(){ 48 | var m = Process.findModuleByName("libflutter.so"); 49 | console.log("libflutter.so loaded at ", m.base); 50 | var jni_onload_addr = m.enumerateExports()[0].address; 51 | console.log("jni_onload_address: ", jni_onload_addr); 52 | // Adding the offset between 53 | // ssl_crypto_x509_session_verify_cert_chain and JNI_Onload = $ssl_function_offset 54 | let addr = ptr(jni_onload_addr).add($ssl_function_offset); 55 | console.log("ssl_crypto_x509_session_verify_cert_chain_addr: ", addr); 56 | let buf = Memory.readByteArray(addr, 12); 57 | console.log(hexdump(buf, { offset: 0, length: 64, header: false, ansi: false})); 58 | hook_ssl_crypto_x509_session_verify_cert_chain(addr); 59 | 60 | } 61 | setTimeout(disable_certificate_validation, 1000) 62 | EOF 63 | 64 | curl -L -o frida-server.xz https://github.com/frida/frida/releases/download/16.3.3/frida-server-16.3.3-android-x86_64.xz 65 | unxz -f frida-server.xz 66 | adb root 67 | adb push frida-server /data/local/tmp/ 68 | adb shell "chmod 755 /data/local/tmp/frida-server" 69 | adb shell '/data/local/tmp/frida-server > /dev/null 2>&1 & echo $!' 70 | 71 | frida -U -f $APP_PACKAGE_NAME -l script.js 72 | --------------------------------------------------------------------------------