Android App Penetration Testing & Frida Hooks

Android RE Lab: Universal SSL Pinning Bypass with Frida – Hands-On Walkthrough

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: Unmasking Network Traffic in Android Apps

SSL Pinning is a critical security mechanism implemented by Android applications to prevent Man-in-the-Middle (MitM) attacks. It ensures that the application only communicates with a predefined, trusted server certificate or public key, even if a user’s device trusts a different certificate authority. While crucial for security, this mechanism poses a significant challenge for penetration testers, security researchers, and reverse engineers who need to inspect application network traffic for analysis or vulnerability assessment.

This hands-on guide will walk you through the process of bypassing SSL pinning universally on Android applications using Frida, a dynamic instrumentation toolkit. We’ll cover the setup, common pinning mechanisms, and powerful Frida scripts to ensure you can intercept traffic from almost any Android app.

Prerequisites for Your Android RE Lab

Before diving into the bypass, ensure you have the following tools and components set up:

  • Rooted Android Device or Emulator: A rooted device (e.g., Pixel with Magisk) or an emulator (e.g., Android Studio AVD, Genymotion) is essential. Frida requires root privileges to inject into target processes.
  • ADB (Android Debug Bridge): For interacting with your Android device/emulator.
  • Frida-server: The server component running on the Android device.
  • Frida-tools: The client components (Python package) on your host machine for interacting with frida-server.
  • Proxy Tool (e.g., Burp Suite, OWASP ZAP): To intercept and analyze HTTP/HTTPS traffic.
  • Proxy’s CA Certificate: The CA certificate from your proxy tool, installed on your Android device/emulator.
  • Python 3: For running Frida scripts.

Setting Up Your Environment

1. Install Frida-tools on Host Machine

pip3 install frida-tools

2. Install Frida-server on Android Device

Download the appropriate frida-server for your device’s architecture (e.g., arm64 for most modern devices or emulators) from the Frida releases page. Push it to your device and make it executable:

adb push frida-server-/data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"
adb shell "/data/local/tmp/frida-server &"

3. Configure Proxy & Install CA Certificate

Configure your host machine’s proxy (e.g., Burp Suite) to listen on a specific port (e.g., 8080) and accept connections from external devices. Forward this port to your Android device:

adb reverse tcp:8080 tcp:8080

Export your proxy’s CA certificate (e.g., cacert.der from Burp Suite) and install it on your Android device as a user-trusted certificate. Navigate to Android Settings > Security > Encryption & Credentials > Install a certificate > CA certificate, then locate and install your .der or .pem file.

Understanding SSL Pinning Implementations

SSL pinning can be implemented in several ways:

  • TrustManager Customization: Apps might provide their own X509TrustManager implementation to validate certificates.
  • OkHttp / Retrofit: Popular networking libraries like OkHttp offer certificate pinning features (CertificatePinner).
  • Network Security Configuration (NSC): Introduced in Android 7.0 (API level 24), NSC allows developers to declare network security settings, including pinning, in an XML file.
  • WebView / Custom Certificate Stores: Less common, but some apps might use custom certificate validation for WebViews or maintain their own certificate stores.

Our universal Frida script targets the underlying Android APIs responsible for certificate validation, aiming to disable pinning regardless of the specific library or framework used.

The Universal Frida SSL Pinning Bypass Approach

Frida’s strength lies in its ability to inject JavaScript into target processes and hook into native functions or Java methods. For SSL pinning, we leverage this to hook critical security-related methods and force them to trust any provided certificate (specifically, our proxy’s CA certificate).

The core idea is to hook methods like checkServerTrusted within X509TrustManager, effectively making them always return true, thus accepting any server certificate.

Step-by-Step Universal Bypass

1. Identify Target Application Package Name

You can find the package name using ADB:

adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'

Or by inspecting the app on the Play Store URL (e.g., com.example.app).

2. The Universal Frida Script

Create a JavaScript file, for example, frida-ssl-bypass.js, with the following content. This script combines various known bypasses for different Android versions and common libraries.

Java.perform(function() {
	console.log("[*] Universal Android SSL Pinning Bypass Enabled");

	// Bypass TrustManager.checkServerTrusted
	var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
	var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');

	X509TrustManager.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String').implementation = function(chain, authType) {
		console.log('[+] Bypassing X509TrustManager.checkServerTrusted (1)');
		return;
	};

	X509TrustManager.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String').implementation = function(chain, authType, host) {
		console.log('[+] Bypassing X509TrustManager.checkServerTrusted (2)');
		return;
	};

	// For newer Android versions where TrustManagerImpl might be used
	TrustManagerImpl.checkTrusted.implementation = function(chain, authType, session, hostname) {
		console.log('[+] Bypassing TrustManagerImpl.checkTrusted');
		return Java.use('java.util.ArrayList').$new(); // Return empty list of trusted certs
	};

	// OkHttp3 bypass
	try {
		var CertificatePinner = Java.use('okhttp3.CertificatePinner');
		CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(hostname, certificates) {
			console.log('[+] Bypassing OkHttp3 CertificatePinner.check (1)');
			return;
		};
		CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(hostname, certificates) {
			console.log('[+] Bypassing OkHttp3 CertificatePinner.check (2)');
			return;
		};
	} catch (e) {
		console.log('[-] OkHttp3 CertificatePinner not found or bypass failed: ' + e.message);
	}

	// WebView pinning bypass (for some cases where it might be custom implemented)
	try {
		var WebViewClient = Java.use('android.webkit.WebViewClient');
		WebViewClient.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function(view, handler, error) {
			console.log('[+] Bypassing WebViewClient.onReceivedSslError');
			handler.proceed();
		};
	} catch (e) {
		console.log('[-] WebViewClient.onReceivedSslError not found or bypass failed: ' + e.message);
	}

	// For apps using Apache HttpClient (older apps)
	try {
		var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
		SSLSocketFactory.is;tSchemeTrusted.implementation = function(arg1) {
			console.log('[+] Bypassing SSLSocketFactory.isHostTrusted');
			return true;
		};
	} catch (e) {
		console.log('[-] Apache HttpClient SSLSocketFactory not found or bypass failed: ' + e.message);
	}
});

3. Execute Frida with the Script

Run the target application on your device. Then, execute Frida from your host machine, attaching to the running process:

frida -U -f [PACKAGE_NAME] -l frida-ssl-bypass.js --no-pause

Replace [PACKAGE_NAME] with the actual package name of your target application (e.g., com.example.app). The -f flag spawns the application; --no-pause ensures the app starts immediately after injection. If the app is already running, use -U -p [PID] -l frida-ssl-bypass.js or -U [PROCESS_NAME] -l frida-ssl-bypass.js.

4. Verify the Bypass

With Frida successfully injected and the script running, navigate through the application. You should now observe its network traffic flowing through your configured proxy (e.g., Burp Suite). Look for the console output from Frida (e.g., [+] Bypassing X509TrustManager.checkServerTrusted) on your host machine to confirm that the hooks are being triggered.

Troubleshooting Common Issues

  • Frida-server not running: Ensure frida-server is running on your device. Check adb logcat | grep frida.
  • Architecture mismatch: Download the correct frida-server for your device’s CPU architecture.
  • Application crashing: The Frida script might cause instability in some applications. Try a more targeted script if a universal one fails, or narrow down the hooks.
  • No traffic in proxy: Double-check your proxy settings, network configuration on the Android device, and adb reverse command. Ensure the CA certificate is correctly installed.
  • App detects Frida: Some applications implement Frida detection. You might need anti-Frida detection bypasses, which are beyond the scope of this universal SSL pinning guide but often involve modifying Frida’s core or using specialized tools.

Conclusion

Bypassing SSL pinning is a fundamental skill for anyone involved in Android application security testing or reverse engineering. With Frida, we gain immense power to dynamically modify app behavior at runtime, making complex security mechanisms like SSL pinning manageable. This universal script serves as a robust starting point, enabling you to inspect network traffic and uncover vulnerabilities that would otherwise remain hidden. Remember to use these techniques responsibly and only on applications for which you have explicit authorization 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