DEV Community

Cover image for Bypassing Android SSL Pinning: A Journey with mitmproxy and APK-Mitm
vault vult
vault vult

Posted on

Bypassing Android SSL Pinning: A Journey with mitmproxy and APK-Mitm

Bypassing Android SSL Pinning: A Journey with mitmproxy and APK-Mitm

When you start reverse-engineering Web3 applications, you quickly realize that the web frontend is only half the story. Often, the most sensitive API endpoints are locked behind the mobile app.

If you want to intercept the traffic from an Android app to see how it communicates with the backend, the first tool you’ll reach for is a proxy like mitmproxy or Burp Suite.

But here is the problem: Modern apps don't want to be intercepted.

In this article, I’ll walk you through the methodology of intercepting Android traffic, hitting the dreaded SSL Pinning wall, and how to use apk-mitm to bypass it.

Phase 1: The Setup (mitmproxy)

Our journey starts by routing the Android device’s traffic through our machine. We fire up mitmproxy and configure the phone's Wi-Fi to use our local IP as the proxy.

To decrypt HTTPS traffic, we download the mitmproxy CA certificate to the device and install it. For older Android versions, this was enough. We could see every request in plain text.

However, when we opened our target app, the terminal spat out an error:
Client TLS handshake failed. The client does not trust the proxy's certificate.

Phase 2: The Wall (SSL Pinning)

Why did the app reject the proxy?

There are two reasons. First, starting with Android 7 (Nougat), Google changed the security model. Apps no longer trust user-installed CA certificates by default; they only trust system certificates.

Second, and more importantly, the app likely uses SSL Pinning. This is a security mechanism where the app is hardcoded to only accept a specific, cryptographic signature (the server's public key). Even if you install the proxy certificate to the system store, the app will reject it because it doesn't match the hardcoded pin.

So, how do we bypass this? We have to change the app itself.

Phase 3: Extracting the APK

We can't modify the app while it's installed. We need to pull the raw .apk file from the device to our computer.

Using Android Debug Bridge (adb), we connect our phone via USB (or wireless debugging) and locate the path of the installed package. We then pull the base APK to our local machine.

Once we have the app.apk file, we are ready to operate.

Phase 4: The Bypass (apk-mitm)

We could manually decompile the APK using apktool, hunt through the AndroidManifest.xml and smali code to find the pinning logic, modify it, and re-sign the app. But that takes hours.

Instead, we use a brilliant open-source tool called apk-mitm.

apk-mitm automates the entire process. You feed it the APK, and it:

  1. Decodes the APK.
  2. Applies a patch to the network security configuration (allowing user certificates).
  3. Attempts to disable common SSL pinning implementations (like OkHttp).
  4. Re-encodes and re-signs the APK.
# The tool runs automatically on the extracted file
npx apk-mitm app.apk
Enter fullscreen mode Exit fullscreen mode

Once the tool finishes, it spits out a new file: app-patched.apk.

Phase 5: The Catch (App Bundles)

Here is where modern Android development throws a curveball.

When we tried to install the patched APK onto the test device, the installation failed with: INSTALL_FAILED_MISSING_SPLIT.

This happens because modern Android apps are distributed as Android App Bundles (AAB), not single APKs. The base.apk we pulled from the phone is just the skeleton. It relies on "split APKs" for specific screen densities, architectures (ARM64, x86), and languages.

If you patch only the base APK, the app won't run. To fix this, you have to use a tool like SAI (Split APKs Installer) on the Android device to install the patched base APK alongside the original split dependencies.

The Lesson for Developers

SSL Pinning is a fantastic defense-in-depth mechanism. It stops 99% of casual attackers from using a proxy to read the traffic.

However, client-side security is never absolute. If an attacker has physical access to the device, they can extract the APK, remove the pinning, and re-sign it.

To truly secure your mobile app, you need more than just SSL pinning:

  1. Root/Jailbreak Detection: Stop the app from running on compromised devices.
  2. Tamper Detection: Verify the app's signature at runtime. If someone re-signs the app (like apk-mitm does), the app should refuse to launch.
  3. Code Obfuscation: Make it as difficult as possible for an attacker to find your pinning logic in the first place.

Intercepting mobile traffic is a puzzle, but with tools like mitmproxy and apk-mitm, the puzzle is solvable.

Top comments (0)