Android SSL Pinning

by
4 views 0e79a2a0...

Description

Android SSL Pinning is a Frida script powerful tool for bypassing SSL pinning in Android applications. It use the Frida framework to intercept and patch SSL pinning methods, enabling the analysis of encrypted network traffic.

How to Use

Download the script and run it with Frida CLI:

Download Script

Then run with Frida:

frida -U -f YOUR_PACKAGE_NAME -l android-ssl-pinning.js

Replace YOUR_PACKAGE_NAME with the target app's package name.

Source Code

JavaScript
/**@@@+++@@@@******************************************************************
 **
 ** Android SSL Pinning frida script v1.0 hyugogirubato
 **
 ** frida -D "DEVICE" -l "pinning.js" -f "PACKAGE"
 **
 ** Update: Dynamic error support.
 **
 ***@@@---@@@@******************************************************************
 */

// Custom params
const MODE = {
    SSLPeerUnverifiedException: true,
    HttpsURLConnection: true,
    SSLContext: true,
    TrustManagerImpl: true,
    OkHTTPv3: true,
    Trustkit: true,
    TitaniumPinningTrustManager: true,
    FabricPinningTrustManager: true,
    ConscryptOpenSSLSocketImpl: true,
    ConscryptOpenSSLEngineSocketImpl: true,
    ApacheOpenSSLSocketImpl: true,
    PhoneGapsslCertificateChecker: true,
    IBMMobileFirst: true,
    IBMWorkLight: true,
    ConscryptCertPinManager: true,
    NetsecurityCertPinManager: true,
    AndroidgapWorkLight: true,
    NettyFingerprintTrustManagerFactory: true,
    SquareupCertificatePinner: true,
    SquareupOkHostnameVerifier: true,
    AndroidWebViewClient: true,
    ApacheWebViewClient: true,
    BoyeAbstractVerifier: true,
    ApacheAbstractVerifier: true,
    Appmattus: true,
    ChromiumCronet: true,
    Flutter: true
};


let index = 0; // color index
const COLORS = {
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    blue: '\x1b[34m',
    magenta: '\x1b[35m',
    cyan: '\x1b[36m',
    reset: '\x1b[0m'
};

const randomColor = () => {
    const colorKeys = Object.keys(COLORS).filter(key => key !== "reset" && key !== "red");
    index = (index + 1) % colorKeys.length;
    return COLORS[colorKeys[index]];
}


const rudimentaryFix = (typeName) => {
    if (typeName === "boolean") {
        return true;
    } else if (typeName !== "void") {
        return null;
    }
}

const loadJava = (library) => {
    try {
        return Java.use(library);
    } catch (e) {
        return undefined;
    }
}


setTimeout(function () {
    console.log("---");
    console.log("Capturing Android app...");
    if (Java.available) {
        console.log("[*] Java available");
        Java.perform(function () {

                if (MODE.SSLPeerUnverifiedException) {
                    const colorKey = randomColor();
                    try {
                        const UnverifiedCertError = Java.use("javax.net.ssl.SSLPeerUnverifiedException");
                        UnverifiedCertError.$init.implementation = function (str) {
                            console.log(`${COLORS.red}[!] Unexpected SSLPeerUnverifiedException occurred, trying to patch it dynamically...${COLORS.reset}`);

                            let className, methodName, callingMethod, returnTypeName;
                            try {
                                const stackTrace = Java.use("java.lang.Thread").currentThread().getStackTrace();
                                const exceptionStackIndex = stackTrace.findIndex(stack =>
                                    stack.getClassName() === "javax.net.ssl.SSLPeerUnverifiedException"
                                );

                                if (exceptionStackIndex === -1) {
                                    console.log(`${COLORS.yellow}[-] SSLPeerUnverifiedException not found in the stack trace.${COLORS.reset}`);
                                    return this.$init(str);
                                }

                                // Retrieve the method raising the SSLPeerUnverifiedException
                                const callingFunctionStack = stackTrace[exceptionStackIndex + 1];
                                className = callingFunctionStack.getClassName();
                                methodName = callingFunctionStack.getMethodName();
                                const callingClass = Java.use(className);
                                callingMethod = callingClass[methodName];

                                // Skip it when already patched by Frida
                                if (callingMethod.implementation) {
                                    return;
                                }

                                // Trying to patch the uncommon SSL Pinning method via implementation
                                returnTypeName = callingMethod.returnType.type;
                                callingMethod.implementation = function () {
                                    rudimentaryFix(returnTypeName);
                                };
                                console.log(`${colorKey}  --> SSLPeerUnverifiedException [${className}.${methodName}]${COLORS.reset}`);
                            } catch (e) {
                                // Dynamic patching via implementation does not works, then trying via function overloading
                                console.log(`${COLORS.red}[!] The uncommon SSL Pinning method has more than one overload${COLORS.reset}`);
                                if (String(e).includes(".overload")) {
                                    const splittedList = String(e).split(".overload");
                                    for (let i = 2; i < splittedList.length; i++) {
                                        const extractedOverload = splittedList[i].trim().split("(")[1].slice(0, -1).replaceAll("'", "");
                                        // Check if extractedOverload has multiple arguments
                                        if (extractedOverload.includes(",")) {
                                            // Go here if overloaded method has multiple arguments (NOTE: max 6 args are covered here)
                                            const argList = extractedOverload.split(", ");

                                            // Overload the method based on the number of arguments
                                            callingMethod.overload(...argList).implementation = function (...args) {
                                                rudimentaryFix(returnTypeName);
                                            };
                                            // Go here if overloaded method has a single argument
                                        } else {
                                            callingMethod.overload(extractedOverload).implementation = function (a) {
                                                rudimentaryFix(returnTypeName);
                                            };
                                        }
                                    }
                                    console.log(`${colorKey}  --> SSLPeerUnverifiedException [${className}.${methodName}]${COLORS.reset}`);
                                } else {
                                    console.log(`${COLORS.red}[!] Failed to dynamically patch SSLPeerUnverifiedException ${e}${COLORS.reset}`);
                                }
                            }
                            return this.$init(str);
                        }
                    } catch (e) {
                        console.log(`${COLORS.red}[!] Failed to dynamically patch SSLPeerUnverifiedException ${e}${COLORS.reset}`);
                    }
                }

                if (MODE.HttpsURLConnection) {
                    const colorKey = randomColor();
                    const HttpsURLConnection = loadJava("javax.net.ssl.HttpsURLConnection");
                    try {
                        HttpsURLConnection.setDefaultHostnameVerifier.implementation = function (hostnameVerifier) {
                            console.log(`${colorKey}  --> HttpsURLConnection [DefaultHostnameVerifier]${COLORS.reset}`);
                        };
                        console.log("[+] HttpsURLConnection [DefaultHostnameVerifier]");
                    } catch (e) {
                        console.log("[ ] HttpsURLConnection [DefaultHostnameVerifier]");
                    }

                    try {
                        HttpsURLConnection.setSSLSocketFactory.implementation = function (SSLSocketFactory) {
                            console.log(`${colorKey}  --> HttpsURLConnection [SSLSocketFactory]${COLORS.reset}`);
                        };
                        console.log("[+] HttpsURLConnection [SSLSocketFactory]");
                    } catch (e) {
                        console.log("[ ] HttpsURLConnection [SSLSocketFactory]");
                    }

                    try {
                        HttpsURLConnection.setHostnameVerifier.implementation = function (hostnameVerifier) {
                            console.log(`${colorKey}  --> HttpsURLConnection [HostnameVerifier]${COLORS.reset}`);
                        };
                        console.log("[+] HttpsURLConnection [HostnameVerifier]");
                    } catch (e) {
                        console.log("[ ] HttpsURLConnection [HostnameVerifier]");
                    }

                }

                if (MODE.SSLContext) {
                    // TrustManager (Android < 7)
                    const colorKey = randomColor();
                    try {
                        const X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
                        const SSLContext = Java.use("javax.net.ssl.SSLContext");

                        const TrustManager = Java.registerClass({
                            // Implement a custom TrustManager
                            name: "dev.asd.test.TrustManager",
                            implements: [X509TrustManager],
                            methods: {
                                checkClientTrusted: function (chain, authType) {
                                },
                                checkServerTrusted: function (chain, authType) {
                                },
                                getAcceptedIssuers: function () {
                                    return [];
                                }
                            }
                        });

                        // Prepare the TrustManager array to pass to SSLContext.init()
                        const TrustManagers = [TrustManager.$new()];
                        // Get a handle on the init() on the SSLContext class
                        const SSLContext_init = SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom");
                        // Override the init method, specifying the custom TrustManager
                        SSLContext_init.implementation = function (keyManager, trustManager, secureRandom) {
                            console.log(`${colorKey}  --> TrustManager [SSLContext] (Android < 7)${COLORS.reset}`);
                            SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
                        };
                        console.log("[+] TrustManager [SSLContext] (Android < 7)");
                    } catch (e) {
                        console.log("[ ] TrustManager [SSLContext] (Android < 7)");
                    }
                }

                if (MODE.TrustManagerImpl) {
                    // TrustManagerImpl (Android > 7)
                    const colorKey = randomColor();
                    const TrustManagerImpl = loadJava("com.android.org.conscrypt.TrustManagerImpl");
                    try {
                        const ArrayList = Java.use("java.util.ArrayList");
                        TrustManagerImpl.checkTrustedRecursive.implementation = function (certs, ocspData, tlsSctData, host, clientAuth, untrustedChain, trustAnchorChain, used) {
                            console.log(`${colorKey}  --> TrustManagerImpl [TrustedRecursive] (Android > 7): ${host}${COLORS.reset}`);
                            return ArrayList.$new();
                        };
                        console.log("[+] TrustManagerImpl [TrustedRecursive] (Android > 7)");
                    } catch (e) {
                        console.log("[ ] TrustManagerImpl [TrustedRecursive] (Android > 7)");
                    }

                    try {
                        TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
                            console.log(`${colorKey}  --> TrustManagerImpl [verifyChain] (Android > 7): ${host}${COLORS.reset}`);
                            return untrustedChain;
                        };
                        console.log("[+] TrustManagerImpl [verifyChain] (Android > 7)");
                    } catch (e) {
                        console.log("[ ] TrustManagerImpl [verifyChain] (Android > 7)");
                    }
                }

                if (MODE.OkHTTPv3) {
                    const colorKey = randomColor();
                    const CertificatePinner = loadJava("okhttp3.CertificatePinner");
                    try {
                        CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function (a, b) {
                            console.log(`${colorKey}  --> OkHTTPv3 [List]: ${a}${COLORS.reset}`);
                        };
                        console.log("[+] OkHTTPv3 [List]");
                    } catch (e) {
                        console.log("[ ] OkHTTPv3 [List]");
                    }

                    try {
                        CertificatePinner.check.overload("java.lang.String", "java.security.cert.Certificate").implementation = function (a, b) {
                            console.log(`${colorKey}  --> OkHTTPv3 [Certificate]: ${a}${COLORS.reset}`);
                        };
                        console.log("[+] OkHTTPv3 [Certificate]");
                    } catch (e) {
                        console.log("[ ] OkHTTPv3 [Certificate]");
                    }

                    try {
                        CertificatePinner.check.overload("java.lang.String", "[Ljava.security.cert.Certificate;").implementation = function (a, b) {
                            console.log(`${colorKey}  --> OkHTTPv3 [Array]: ${a}${COLORS.reset}`);
                        };
                        console.log("[+] OkHTTPv3 [Array]");
                    } catch (e) {
                        console.log("[ ] OkHTTPv3 [Array]");
                    }

                    try {
                        CertificatePinner.check$okhttp.overload("java.lang.String", "kotlin.jvm.functions.Function0").implementation = function (a, b) {
                            console.log(`${colorKey}  --> OkHTTPv3 [Function]: ${a}${COLORS.reset}`);
                        };
                        console.log("[+] OkHTTPv3 [Function]");
                    } catch (e) {
                        console.log("[ ] OkHTTPv3 [Function]");
                    }
                }

                if (MODE.Trustkit) {
                    const colorKey = randomColor();
                    const OkHostnameVerifier = loadJava("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");
                    const PinningTrustManager = loadJava("com.datatheorem.android.trustkit.pinning.PinningTrustManager");
                    try {
                        OkHostnameVerifier.verify.overload("java.lang.String", "javax.net.ssl.SSLSession").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Trustkit OkHostnameVerifier [SSLSession]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Trustkit OkHostnameVerifier [SSLSession]");
                    } catch (e) {
                        console.log("[ ] Trustkit OkHostnameVerifier [SSLSession]");
                    }

                    try {
                        OkHostnameVerifier.verify.overload("java.lang.String", "java.security.cert.X509Certificate").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Trustkit OkHostnameVerifier [X509Certificate]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Trustkit OkHostnameVerifier [X509Certificate]");
                    } catch (e) {
                        console.log("[ ] Trustkit OkHostnameVerifier [X509Certificate]");
                    }

                    try {
                        PinningTrustManager.checkServerTrusted.overload("[Ljava.security.cert.X509Certificate;", "java.lang.String").implementation = function (chain, authType) {
                            console.log(`${colorKey}  --> Trustkit PinningTrustManager${COLORS.reset}`);
                        };
                        console.log("[+] Trustkit PinningTrustManager");
                    } catch (e) {
                        console.log("[ ] Trustkit PinningTrustManager");
                    }
                }

                if (MODE.TitaniumPinningTrustManager) {
                    const colorKey = randomColor();
                    const PinningTrustManager = loadJava("appcelerator.https.PinningTrustManager");
                    try {
                        PinningTrustManager.checkServerTrusted.implementation = function (chain, authType) {
                            console.log(`${colorKey}  --> Titanium [PinningTrustManager]${COLORS.reset}`);
                        };
                        console.log("[+] Titanium [PinningTrustManager]");
                    } catch (e) {
                        console.log("[ ] Titanium [PinningTrustManager]");
                    }
                }

                if (MODE.FabricPinningTrustManager) {
                    const colorKey = randomColor();
                    const PinningTrustManager = loadJava("io.fabric.sdk.android.services.network.PinningTrustManager");
                    try {
                        PinningTrustManager.checkServerTrusted.implementation = function (chain, authType) {
                            console.log(`${colorKey}  --> Fabric [PinningTrustManager]${COLORS.reset}`);
                        };
                        console.log("[+] Fabric [PinningTrustManager]");
                    } catch (e) {
                        console.log("[ ] Fabric [PinningTrustManager]");
                    }
                }

                if (MODE.ConscryptOpenSSLSocketImpl) {
                    const colorKey = randomColor();
                    const OpenSSLSocketImpl = loadJava("com.android.org.conscrypt.OpenSSLSocketImpl");
                    try {
                        OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) {
                            console.log(`${colorKey}  --> Conscrypt [OpenSSLSocketImpl] (Refs)${COLORS.reset}`);
                        };
                        console.log("[+] Conscrypt [OpenSSLSocketImpl] (Refs)");
                    } catch (e) {
                        console.log("[ ] Conscrypt [OpenSSLSocketImpl] (Refs)");
                    }

                    try {
                        OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certChain, authMethod) {
                            console.log(`${colorKey}  --> Conscrypt [OpenSSLSocketImpl] (Chain)${COLORS.reset}`);
                        };
                        console.log("[+] Conscrypt [OpenSSLSocketImpl] (Chain)");
                    } catch (e) {
                        console.log("[ ] Conscrypt [OpenSSLSocketImpl] (Chain)");
                    }
                }

                if (MODE.ConscryptOpenSSLEngineSocketImpl) {
                    const colorKey = randomColor();
                    const OpenSSLEngineSocketImpl = loadJava("com.android.org.conscrypt.OpenSSLEngineSocketImpl");
                    try {
                        OpenSSLEngineSocketImpl.verifyCertificateChain.overload("[Ljava.lang.Long;", "java.lang.String").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Conscrypt [OpenSSLEngineSocketImpl]: ${b}${COLORS.reset}`);
                        };
                        console.log("[+] Conscrypt [OpenSSLEngineSocketImpl]");
                    } catch (e) {
                        console.log("[ ] Conscrypt [OpenSSLEngineSocketImpl]");
                    }
                }

                if (MODE.ApacheOpenSSLSocketImpl) {
                    const colorKey = randomColor();
                    const OpenSSLSocketImpl = loadJava("org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl");
                    try {
                        OpenSSLSocketImpl.verifyCertificateChain.implementation = function (asn1DerEncodedCertificateChain, authMethod) {
                            console.log(`${colorKey}  --> Apache [OpenSSLSocketImpl]${COLORS.reset}`);
                        };
                        console.log("[+] Apache [OpenSSLSocketImpl]");
                    } catch (e) {
                        console.log("[ ] Apache [OpenSSLSocketImpl]");
                    }
                }

                if (MODE.PhoneGapsslCertificateChecker) {
                    const colorKey = randomColor();
                    const sslCertificateChecker = loadJava("nl.xservices.plugins.sslCertificateChecker");
                    try {
                        sslCertificateChecker.execute.overload("java.lang.String", "org.json.JSONArray", "org.apache.cordova.CallbackContext").implementation = function (a, b, c) {
                            console.log(`${colorKey}  --> PhoneGap [sslCertificateChecker]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] PhoneGap [sslCertificateChecker]");
                    } catch (e) {
                        console.log("[ ] PhoneGap [sslCertificateChecker]");
                    }
                }

                if (MODE.IBMMobileFirst) {
                    const colorKey = randomColor();
                    const MobileFirst = loadJava("com.worklight.wlclient.api.WLClient");
                    try {
                        MobileFirst.getInstance().pinTrustedCertificatePublicKey.overload("java.lang.String").implementation = function (cert) {
                            console.log(`${colorKey}  --> IBM [MobileFirst] (String): ${cert}${COLORS.reset}`);
                        };
                        console.log("[+] IBM [MobileFirst] (String)");
                    } catch (e) {
                        console.log("[ ] IBM [MobileFirst] (String)");
                    }

                    try {
                        MobileFirst.getInstance().pinTrustedCertificatePublicKey.overload("[Ljava.lang.String;").implementation = function (cert) {
                            console.log(`${colorKey}  --> IBM [MobileFirst] (Array): ${cert}${COLORS.reset}`);
                        };
                        console.log("[+] IBM [MobileFirst] (Array)");
                    } catch (e) {
                        console.log("[ ] IBM [MobileFirst] (Array)");
                    }
                }

                if (MODE.IBMWorkLight) {
                    const colorKey = randomColor();
                    const WorkLight = loadJava("com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning");
                    try {
                        WorkLight.verify.overload("java.lang.String", "javax.net.ssl.SSLSocket").implementation = function (a, b) {
                            console.log(`${colorKey}  --> IBM [WorkLight] (SSLSocket): ${a}${COLORS.reset}`);
                        };
                        console.log("[+] IBM [WorkLight] (SSLSocket)");
                    } catch (e) {
                        console.log("[ ] IBM [WorkLight] (SSLSocket)");
                    }

                    try {
                        WorkLight.verify.overload("java.lang.String", "java.security.cert.X509Certificate").implementation = function (a, b) {
                            console.log(`${colorKey}  --> IBM [WorkLight] (X509Certificate): ${a}${COLORS.reset}`);
                        };
                        console.log("[+] IBM [WorkLight] (X509Certificate)");
                    } catch (e) {
                        console.log("[ ] IBM [WorkLight] (X509Certificate)");
                    }

                    try {
                        WorkLight.verify.overload("java.lang.String", "[Ljava.lang.String;", "[Ljava.lang.String;").implementation = function (a, b) {
                            console.log(`${colorKey}  --> IBM [WorkLight] (String): ${a}${COLORS.reset}`);
                        };
                        console.log("[+] IBM [WorkLight] (String)");
                    } catch (e) {
                        console.log("[ ] IBM [WorkLight] (String)");
                    }

                    try {
                        WorkLight.verify.overload("java.lang.String", "javax.net.ssl.SSLSession").implementation = function (a, b) {
                            console.log(`${colorKey}  --> IBM [WorkLight] (SSLSession): ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] IBM [WorkLight] (SSLSession)");
                    } catch (e) {
                        console.log("[ ] IBM [WorkLight] (SSLSession)");
                    }
                }

                if (MODE.ConscryptCertPinManager) {
                    const colorKey = randomColor();
                    const CertPinManager = loadJava("com.android.org.conscrypt.CertPinManager");
                    try {
                        CertPinManager.checkChainPinning.overload("java.lang.String", "java.util.List").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Conscrypt [CertPinManager] (List): ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Conscrypt [CertPinManager] (List)");
                    } catch (e) {
                        console.log("[ ] Conscrypt [CertPinManager] (List)");
                    }

                    try {
                        CertPinManager.isChainValid.overload("java.lang.String", "java.util.List").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Conscrypt [CertPinManager] (Legacy): ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Conscrypt [CertPinManager] (Legacy)");
                    } catch (e) {
                        console.log("[ ] Conscrypt [CertPinManager] (Legacy)");
                    }
                }

                if (MODE.NetsecurityCertPinManager) {
                    const colorKey = randomColor();
                    const CertPinManager = loadJava("com.commonsware.cwac.netsecurity.conscrypt.CertPinManager");
                    try {
                        CertPinManager.isChainValid.overload("java.lang.String", "java.util.List").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Netsecurity [CertPinManager]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Netsecurity [CertPinManager]");
                    } catch (e) {
                        console.log("[ ] Netsecurity [CertPinManager]");
                    }
                }

                if (MODE.AndroidgapWorkLight) {
                    const colorKey = randomColor();
                    const Worklight = loadJava("com.worklight.androidgap.plugin.WLCertificatePinningPlugin");
                    try {
                        Worklight.execute.overload("java.lang.String", "org.json.JSONArray", "org.apache.cordova.CallbackContext").implementation = function (a, b, c) {
                            console.log(`${colorKey}  --> Android [WorkLight]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Android [WorkLight]");
                    } catch (e) {
                        console.log("[ ] Android [WorkLight]");
                    }
                }

                if (MODE.NettyFingerprintTrustManagerFactory) {
                    const colorKey = randomColor();
                    const FingerprintTrustManagerFactory = loadJava("io.netty.handler.ssl.util.FingerprintTrustManagerFactory");
                    try {
                        FingerprintTrustManagerFactory.checkTrusted.implementation = function (type, chain) {
                            console.log(`${colorKey}  --> Netty [FingerprintTrustManagerFactory]${COLORS.reset}`);
                        };
                        console.log("[+] Netty [FingerprintTrustManagerFactory]");
                    } catch (e) {
                        console.log("[ ] Netty [FingerprintTrustManagerFactory]");
                    }
                }

                if (MODE.SquareupCertificatePinner) {
                    // OkHTTP < v3
                    const colorKey = randomColor();
                    const CertificatePinner = loadJava("com.squareup.okhttp.CertificatePinner");
                    try {
                        CertificatePinner.check.overload("java.lang.String", "java.security.cert.Certificate").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Squareup [CertificatePinner] (Certificate): ${a}${COLORS.reset}`);
                        };
                        console.log("[+] Squareup [CertificatePinner] (Certificate)");
                    } catch (e) {
                        console.log("[ ] Squareup [CertificatePinner] (Certificate)");
                    }

                    try {
                        CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Squareup [CertificatePinner] (List): ${a}${COLORS.reset}`);
                        };
                        console.log("[+] Squareup [CertificatePinner] (List)");
                    } catch (e) {
                        console.log("[ ] Squareup [CertificatePinner] (List)");
                    }
                }

                if (MODE.SquareupOkHostnameVerifier) {
                    // OkHTTP v3
                    const colorKey = randomColor();
                    const OkHostnameVerifier = loadJava("com.squareup.okhttp.internal.tls.OkHostnameVerifier");
                    try {
                        OkHostnameVerifier.verify.overload("java.lang.String", "java.security.cert.X509Certificate").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Squareup [OkHostnameVerifier] (X509Certificate): ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Squareup [OkHostnameVerifier] (X509Certificate)");
                    } catch (e) {
                        console.log("[ ] Squareup [OkHostnameVerifier] (X509Certificate)");
                    }

                    try {
                        OkHostnameVerifier.verify.overload("java.lang.String", "javax.net.ssl.SSLSession").implementation = function (a, b) {
                            console.log(`${colorKey}  --> Squareup [OkHostnameVerifier] (SSLSession): ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Squareup [OkHostnameVerifier] (SSLSession)");
                    } catch (e) {
                        console.log("[ ] Squareup [OkHostnameVerifier] (SSLSession)");
                    }
                }

                if (MODE.AndroidWebViewClient) {
                    const colorKey = randomColor();
                    const WebViewClient = loadJava("android.webkit.WebViewClient");

                    try {
                        WebViewClient.onReceivedSslError.overload("android.webkit.WebView", "android.webkit.SslErrorHandler", "android.net.http.SslError").implementation = function (obj1, obj2, obj3) {
                            console.log(`${colorKey}  --> Android [WebViewClient] (SslErrorHandler)${COLORS.reset}`);
                        };
                        console.log("[+] Android [WebViewClient] (SslErrorHandler)");
                    } catch (e) {
                        console.log("[ ] Android [WebViewClient] (SslErrorHandler)");
                    }

                    try {
                        WebViewClient.onReceivedSslError.overload("android.webkit.WebView", "android.webkit.WebResourceRequest", "android.webkit.WebResourceError").implementation = function (obj1, obj2, obj3) {
                            console.log(`${colorKey}  --> Android [WebViewClient] (SSLWebResourceError)${COLORS.reset}`);
                        };
                        console.log("[+] Android [WebViewClient] (SSLWebResourceError)");
                    } catch (e) {
                        console.log("[ ] Android [WebViewClient] (SSLWebResourceError)");
                    }

                    try {
                        WebViewClient.onReceivedError.overload("android.webkit.WebView", "int", "java.lang.String", "java.lang.String").implementation = function (obj1, obj2, obj3, obj4) {
                            console.log(`${colorKey}  --> Android [WebViewClient] (String)${COLORS.reset}`);
                        };
                        console.log("[+] Android [WebViewClient] (String)");
                    } catch (e) {
                        console.log("[ ] Android [WebViewClient] (String)");
                    }

                    try {
                        WebViewClient.onReceivedError.overload("android.webkit.WebView", "android.webkit.WebResourceRequest", "android.webkit.WebResourceError").implementation = function (obj1, obj2, obj3) {
                            console.log(`${colorKey}  --> Android [WebViewClient] (WebResourceError)${COLORS.reset}`);
                        };
                        console.log("[+] Android [WebViewClient] (WebResourceError)");
                    } catch (e) {
                        console.log("[ ] Android [WebViewClient] (WebResourceError)");
                    }
                }

                if (MODE.ApacheWebViewClient) {
                    const colorKey = randomColor();
                    const CordovaWebViewClient = loadJava("org.apache.cordova.CordovaWebViewClient");
                    try {
                        CordovaWebViewClient.onReceivedSslError.overload("android.webkit.WebView", "android.webkit.SslErrorHandler", "android.net.http.SslError").implementation = function (obj1, obj2, obj3) {
                            console.log(`${colorKey}  --> Apache [WebViewClient]${COLORS.reset}`);
                            obj3.proceed();
                        };
                        console.log("[+] Apache [WebViewClient]");
                    } catch (e) {
                        console.log("[ ] Apache [WebViewClient]");
                    }
                }

                if (MODE.BoyeAbstractVerifier) {
                    const colorKey = randomColor();
                    const AbstractVerifier = loadJava("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
                    try {
                        AbstractVerifier.verify.implementation = function (host, ssl) {
                            console.log(`${colorKey}  --> Boye [AbstractVerifier]: ${host}${COLORS.reset}`);
                        };
                        console.log("[+] Boye [AbstractVerifier]");
                    } catch (e) {
                        console.log("[ ] Boye [AbstractVerifier]");
                    }
                }

                if (MODE.ApacheAbstractVerifier) {
                    const colorKey = randomColor();
                    const AbstractVerifier = loadJava("org.apache.http.conn.ssl.AbstractVerifier");
                    try {
                        AbstractVerifier.verify.implementation = function (a, b, c, d) {
                            console.log(`${colorKey}  --> Apache [AbstractVerifier]: ${a}${COLORS.reset}`);
                        };
                        console.log("[+] Apache [AbstractVerifier]");
                    } catch (e) {
                        console.log("[ ] Apache [AbstractVerifier]");
                    }
                }

                if (MODE.Appmattus) {
                    const colorKey = randomColor();
                    const Transparency = loadJava("com.appmattus.certificatetransparency.internal.verifier.CertificateTransparencyInterceptor");
                    try {
                        Transparency.intercept.implementation = function (a) {
                            console.log(`${colorKey}  --> Appmattus [Transparency]${COLORS.reset}`);
                            return a.proceed(a.request());
                        };
                        console.log("[+] Appmattus [Transparency]");
                    } catch (e) {
                        console.log("[ ] Appmattus [Transparency]");
                    }
                }

                if (MODE.ChromiumCronet) {
                    const colorKey = randomColor();
                    const CronetEngineBuilderImpl = loadJava("org.chromium.net.impl.CronetEngineBuilderImpl");
                    try {
                        CronetEngineBuilderImpl.enablePublicKeyPinningBypassForLocalTrustAnchors.overload("boolean").implementation = function (a) {
                            console.log(`${colorKey}  --> Chromium [CronetEngineBuilderImpl] (LocalTrustAnchors)${COLORS.reset}`);
                            return CronetEngineBuilderImpl.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);
                        };
                        console.log("[+] Chromium [CronetEngineBuilderImpl] (LocalTrustAnchors)");
                    } catch (e) {
                        console.log("[ ] Chromium [CronetEngineBuilderImpl] (LocalTrustAnchors)");
                    }

                    try {
                        CronetEngineBuilderImpl.addPublicKeyPins.overload("java.lang.String", "java.util.Set", "boolean", "java.util.Date").implementation = function (hostName, pinsSha256, includeSubdomains, expirationDate) {
                            console.log(`${colorKey}  --> Chromium [CronetEngineBuilderImpl] (PublicKey): ${hostName}${COLORS.reset}`);
                            return CronetEngineBuilderImpl.addPublicKeyPins.call(this, hostName, pinsSha256, includeSubdomains, expirationDate);
                        };
                        console.log("[+] Chromium [CronetEngineBuilderImpl] (PublicKey)");
                    } catch (e) {
                        console.log("[ ] Chromium [CronetEngineBuilderImpl] (PublicKey)");
                    }
                }

                if (MODE.Flutter) {
                    const colorKey = randomColor();
                    const HttpCertificatePinning = loadJava("diefferson.http_certificate_pinning.HttpCertificatePinning");
                    const SslPinningPlugin = loadJava("com.macif.plugin.sslpinningplugin.SslPinningPlugin");
                    try {
                        HttpCertificatePinning.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function (a, b, c, d, e) {
                            console.log(`${colorKey}  --> Flutter [HttpCertificatePinning]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Flutter [HttpCertificatePinning]");
                    } catch (e) {
                        console.log("[ ] Flutter [HttpCertificatePinning]");
                    }

                    try {
                        SslPinningPlugin.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function (a, b, c, d, e) {
                            console.log(`${colorKey}  --> Flutter [SslPinningPlugin]: ${a}${COLORS.reset}`);
                            return true;
                        };
                        console.log("[+] Flutter [SslPinningPlugin]");
                    } catch (e) {
                        console.log("[ ] Flutter [SslPinningPlugin]");
                    }
                }

            }
        );
    } else {
        console.log(`${COLORS.red}[!] Java unavailable${COLORS.reset}`);
    }

    console.log("Capturing setup completed");
    console.log("---");
}, 0);
Share this script:
Twitter LinkedIn

Comments

Login or Sign up to leave a comment.
Loading comments...