Bypassing OkHttp3 Certificate Validation [Demo Included]

Bypassing OkHttp3 Certificate Validation [Demo Included]

Disclaimer:The technologies, ideas, and tools mentioned in this article are for educational purposes only and should be used for security-related learning and communication. No one is allowed to use them for illegal purposes or for profit; otherwise, the consequences will be borne by the user!If there are any infringements, please let me know, and I will delete and apologize immediately. Thank you!

If you have any questions about the article, feel free to message me on WeChat or leave a comment. I check daily.

Bypassing OkHttp3 Certificate Validation [Demo Included]

Word count: 707, reading time approximately 4 minutes

Introduction

Previously, a colleague asked if I had a test APK for the version of bypassing certificate validation I shared earlier. I mentioned I would write a demo, and today I have finally completed part of it. I will continue to update this based on feedback, and I welcome everyone to follow along.

APK Demo

I have created a simple demo, and here is the APK download link: Download APK

Bypassing OkHttp3 Certificate Validation [Demo Included]
bf66b716e39382a032809da408aa78c4.png

The first corresponds to the X509TrustManager certificate binding. The second corresponds to the CertificatePinner certificate binding.

CertificatePinner Certificate Binding

You can test this with the app.

Bypassing OkHttp3 Certificate Validation [Demo Included]
8b8c315fbf374a7d34c2c6399b25ed00.png

You can also use the test below; the Frida scripts are the same as below. Since I wrote the notes first and then this demo, I won’t change it.

Source of the case: Source APK

Source code: written in Kotlin

Bypassing OkHttp3 Certificate Validation [Demo Included]
ba43b07637699b040b44138d37ec51b2.png
    LaunchedEffect(savedFingerprint, sslPinningEnabled) {
        globalOkHttpClient = if (sslPinningEnabled && savedFingerprint.isNotEmpty()) {
            val host = URL(urlInput).host
            val certificatePinner = CertificatePinner.Builder()
                .add(host, savedFingerprint).build()
            Log.i("okhttp-client", "Generated ssl pinning client $host")
            OkHttpClient.Builder().certificatePinner(certificatePinner).build()// Certificate binding
        } else {
            Log.i("okhttp-client", "Client without ssl pinning")
            OkHttpClient.Builder().build()
        }
    }

By the way, the CertificatePinner.Builder().add performs the certificate binding for a CertificatePinner configured with www.baidu.com‘s certificate. When requesting www.baidu.com, certificate pinning checks will be performed; however, when requesting www.google.com, no certificate pinning checks will be performed, but regular SSL/TLS certificate validation will occur.

Requests to URLs outside the host configured in CertificatePinner will not perform certificate pinning checks but will conduct regular SSL/TLS certificate validation.

Frida Script

frida -H 192.168.1.9:27123 -f  com.frida_analykit.ssl_log_secret -l bypass_no_proxy.js
/**
 * Create an empty CertificatePinner
 */
function okhttp3_empty_CertificatePinner() {
    Java.perform(function () {
        const CertificatePinner = Java.use("okhttp3.CertificatePinner");
        const Builder = Java.use("okhttp3.CertificatePinner$Builder");

        Builder.build.overload().implementation = function () {
            console.log("[+] CertificatePinner build() intercepted");
            // Directly use Builder to create an empty CertificatePinner
            const emptyBuilder = Builder.$new();
            return emptyBuilder.build();
        }
    });
}
okhttp3_empty_CertificatePinner()
  • • Overriding the Builder.build method to return an empty build() when this method is called, instead of the build with a bound CertificatePinner.

X509TrustManager Certificate Binding

Principle

X509TrustManager is an interface in Java used to manage and validate X.509 certificates. When a client establishes an SSL/TLS connection with a server, the server sends its certificate chain to the client, and the client’s X509TrustManager is responsible for verifying whether these certificates are valid, issued by a trusted Certificate Authority (CA), and match the expected certificate.

Validation Code

First, load the CRT certificate for Baidu. Second, initiate a request to Bilibili.

Bypassing OkHttp3 Certificate Validation [Demo Included]
e80cb277e0c446299cbe819602e1ce91.png

Since the certificates are different, it will prompt that the certificate is incorrect.

Display

Bypassing OkHttp3 Certificate Validation [Demo Included]
787d0856c40e6f63e4e43d5ed82538fc.png

Detected incorrect certificate

Bypassing OkHttp3 Certificate Validation [Demo Included]
16afaa42a98fc97cbc67a45c676d7407.png

Frida Hook

function instead_factory() {
    Java.perform(function () {
        var TrustAllCerts = Java.registerClass({
            name: 'com.example.TrustAllCerts',
            implements: [Java.use('javax.net.ssl.X509TrustManager')],
            methods: {
                checkClientTrusted: function (chain, authType) {
                },
                checkServerTrusted: function (chain, authType) {
                },
                getAcceptedIssuers: function () {
                    return [];
                }
            }
        });

        var SSLContext = Java.use('javax.net.ssl.SSLContext');
        var context = SSLContext.getInstance("TLS");
        context.init(null, [TrustAllCerts.$new()], null);

        var OkHttpClientBuilder = Java.use('okhttp3.OkHttpClient$Builder');
        OkHttpClientBuilder.sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory', 'javax.net.ssl.X509TrustManager').implementation = function (sf, tm) {
            // Replace with a factory that trusts all certificates
            return this.sslSocketFactory(context.getSocketFactory(), TrustAllCerts.$new());
        };

    });
}

instead_factory()

You can see that the bypass was successful, and the request to Bilibili was made.

Bypassing OkHttp3 Certificate Validation [Demo Included]
f497a94ee5fe1839f711c1887fd30582.png

References

  • • OkHttp Certificate Binding Process SSL Pinning Analysis Link
  • • Android Security Protection — Volley/OkHttp SSL Pinning Link

Leave a Comment