Android App Penetration Testing & Frida Hooks

Reverse Engineering Lab: Deconstructing OkHttp3 SSL Pinning for Frida Bypass Success

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction to SSL Pinning and OkHttp3

SSL Pinning is a critical security mechanism implemented by applications to prevent Man-in-the-Middle (MITM) attacks. Instead of relying solely on the device’s trust store, applications ‘pin’ specific certificates or public keys that they expect to see when communicating with their servers. If the presented certificate during a TLS handshake doesn’t match one of the pinned items, the connection is immediately terminated. While robust for security, this poses a significant challenge for penetration testers and reverse engineers who need to intercept and analyze application traffic.

OkHttp3 is a popular HTTP client for Android and Java applications, renowned for its efficiency and features, including built-in SSL pinning capabilities via its CertificatePinner class. Bypassing OkHttp3’s SSL pinning often requires a deeper understanding of its implementation details, as generic Frida SSL bypass scripts might not always succeed.

Understanding OkHttp3’s CertificatePinner

OkHttp3 implements SSL pinning using the okhttp3.CertificatePinner class. Developers instantiate this class, add specific certificate hashes (usually SHA-256 of the public key), and then configure their OkHttpClient to use this pinner. When a network request is made, the CertificatePinner intercepts the connection and verifies the server’s certificate against its list of pinned hashes.

How OkHttp3 Pinning Works in Code

A typical OkHttp3 pinning setup looks like this in Java:

public final class MyOkHttpClient {  private static OkHttpClient client;  static {    String hostname = "example.com";    String sha256_1 = "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";    String sha256_2 = "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=";    CertificatePinner certificatePinner = new CertificatePinner.Builder()        .add(hostname, sha256_1, sha256_2)        .build();    client = new OkHttpClient.Builder()        .certificatePinner(certificatePinner)        .build();  }  public static OkHttpClient getClient() {    return client;  }}

The crucial method for pinning enforcement is okhttp3.CertificatePinner#check(String hostname, List peerCertificates). This method is invoked during the TLS handshake to validate the peer’s certificate chain against the configured pins.

Why Standard Frida Bypasses Often Fail

Many common Frida SSL pinning bypass scripts target Android’s default TrustManager implementations (e.g., javax.net.ssl.X509TrustManager, android.security.net.config.NetworkSecurityTrustManager). While effective for apps relying solely on the system’s trust mechanisms, these scripts often fall short when an application implements custom pinning using libraries like OkHttp3.

OkHttp3’s CertificatePinner performs its checks at a higher abstraction layer, often before the request even reaches the underlying Java/Android SSL/TLS implementation that the standard bypasses hook. Therefore, to effectively bypass OkHttp3 pinning, we must specifically target the CertificatePinner‘s validation logic.

Reverse Engineering Strategy: Locating the Pinning Logic

1. Dynamic Analysis with Frida

The first step is to confirm that OkHttp3 is indeed being used and to pinpoint the exact method responsible for the pinning check. Frida’s dynamic instrumentation capabilities are ideal for this.

We can start by hooking the constructor of CertificatePinner and its critical check method to observe when and how they are called.

Java.perform(function () {    console.log("[+] Starting OkHttp3 CertificatePinner Bypass...");    try {        var CertificatePinner = Java.use("okhttp3.CertificatePinner");        // Hooking the constructor to confirm instantiation        CertificatePinner.$init.overload("okhttp3.CertificatePinner$Builder").implementation = function (builder) {            console.log("[+] new CertificatePinner created!");            return this.$init(builder);        };        // Hooking the check method to bypass pinning        CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function (hostname, peerCertificates) {            console.warn("[!] OkHttp3 CertificatePinner.check called for: " + hostname);            // You can log certificates here if needed            // for (var i = 0; i < peerCertificates.size(); i++) {            //     var cert = peerCertificates.get(i);            //     console.log("    Cert: " + cert.getSubjectDN().getName());            // }            console.warn("[+] Bypassing CertificatePinner.check for " + hostname);            // Simply return, effectively disabling the check            return;        };        console.log("[+] OkHttp3 CertificatePinner hooks applied.");    } catch (e) {        console.error("[!] Error hooking CertificatePinner: " + e.message);    }});

Execute this script with Frida:

frida -U -f [YOUR_APP_PACKAGE_NAME] -l okhttp3_bypass.js --no-pause

Monitor your Frida output. When the application attempts to make an OkHttp3 network request, you should see the `[!] OkHttp3 CertificatePinner.check called for:` message, indicating a successful hook.

2. Static Analysis with Jadx-GUI

If dynamic analysis is challenging, or to confirm findings, use a decompiler like Jadx-GUI. Load the application’s APK and search for okhttp3.CertificatePinner. This will help you identify where CertificatePinner instances are created and configured within the application’s code, potentially revealing custom logic or specific hostnames being pinned.

Frida Bypass Technique: Overriding CertificatePinner.check()

The most direct and reliable method to bypass OkHttp3 SSL pinning is to override the CertificatePinner.check() method. By replacing its original implementation with an empty function, we prevent any certificate validation from occurring, effectively allowing any certificate (including your proxy’s forged certificate) to pass.

Step-by-Step Implementation

1. Prerequisites

  • A rooted Android device or emulator.
  • Frida server running on the device.
  • Frida client installed on your workstation.
  • ADB (Android Debug Bridge) setup.
  • A proxy tool like Burp Suite or OWASP ZAP, with its CA certificate installed on the Android device.

2. Prepare Your Frida Script

Save the Frida script provided above (the one that hooks CertificatePinner.check) as `okhttp3_bypass.js`.

3. Configure Your Proxy

Set up Burp Suite (or your preferred proxy) to listen on a specific port (e.g., 8080) and configure your Android device’s Wi-Fi proxy settings to point to your workstation’s IP and Burp’s port.

# Example adb command to set global proxy (requires root or specific permissions)adb shell settings put global http_proxy YOUR_WORKSTATION_IP:8080

Ensure your proxy’s CA certificate is installed and trusted on the Android device. For Android 7.0+ devices, you may need to add network security configuration or move the CA certificate to the system trust store.

4. Execute the Frida Script

Open your terminal and run the Frida command:

frida -U -f [YOUR_APP_PACKAGE_NAME] -l okhttp3_bypass.js --no-pause

Replace [YOUR_APP_PACKAGE_NAME] with the actual package name of the target application (e.g., com.example.app).

  • -U: Connects to a USB device.
  • -f [PACKAGE_NAME]: Spawns and attaches to the specified application.
  • -l okhttp3_bypass.js: Loads your Frida script.
  • --no-pause: Starts the application immediately after injection without waiting for user input.

5. Verify the Bypass

Now, interact with the application. Make network requests that previously failed due to SSL pinning. Monitor your Burp Suite (or proxy) interface. You should now see the application’s traffic flowing through your proxy, indicating a successful SSL pinning bypass.

Conclusion

Bypassing OkHttp3 SSL pinning requires a targeted approach that directly addresses the CertificatePinner class. By leveraging Frida to dynamically override the check() method, penetration testers can effectively disable this security mechanism and gain visibility into encrypted application traffic. This technique highlights the power of dynamic instrumentation in Android app security assessments. Always remember to use these techniques ethically and only on applications you have explicit permission to test.

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner