Docs / Mobile & Frida / Kill cert pinning

Guide Mobile & Frida

Kill cert pinning & intercept mobile

~12 min · Android · Frida · Hunter Pro

The short version. A hardened Android app pins its server's certificate, so even a trusted proxy CA gets rejected and your History stays empty. Crusader can create a rootable Google APIs emulator, route it through your proxy, install the Crusader CA into the device's system trust store, and attach Frida — from Easy Mode with Create rootable emulator, or from the CLI with crusader mobile provision / configure / run. Then you run the Kill SSL pinning (Android and iOS, aggressive) script to hook out the app's pinning checks at runtime. Decrypted HTTPS lands in your proxy. Mobile is Hunter Pro, the automated flow is Android-only, and the aggressive script is detectable — so run it after passive recon confirms the app actually pins.

01Why pinning blocks your proxy

Pointing a phone or emulator at Crusader's proxy and trusting the Crusader CA is enough for most apps. A hardened app does more: it pins the expected server certificate (or its public key) inside the app, then refuses any TLS handshake that doesn't present exactly that leaf — even one your device trusts. The connection dies inside the app before a single request reaches your proxy, and History stays empty.

To intercept it you attack on two fronts at once. First, make the device trust Crusader: route its traffic through the proxy and install the Crusader root into the system store so the OS itself accepts the per-host leaf certs Crusader mints. Second, defeat the in-app check: attach Frida and hook the pinning logic at runtime so the app accepts your cert as if it matched. Crusader's Easy Mode does the first part as a pipeline; one Frida script does the second.

Authorized testing only. Decrypting and instrumenting a mobile app's traffic is intrusive — run this only against apps and back ends you own or are explicitly authorized to test.

02The two surfaces

Crusader gives you two ways into mobile, depending on whether you want a clean sandbox or you already have a device under control:

  • Easy Mode — a guided emulator wizard behind the Easy Mode button. Create rootable emulator downloads a rootable google_apis image if needed, creates and boots the AVD with -writable-system, roots it, configures the proxy + CA, and starts Frida. This is the path this guide follows.
  • Mobile tab — the Pro surface: a Frida script picker plus rooted-server and gadget workflows. You point it at a device or emulator you've already prepared and run scripts directly. Use it when you've outgrown the wizard or you're working a real rooted device.
  • CLI — the same setup is scriptable with crusader mobile provision, crusader mobile configure --device <serial>, crusader mobile install-app <apk|xapk|apks>, and crusader mobile run <package>.

The automated end-to-end flow — Easy Mode, the sandbox pipeline, ADB, frida-server, system-CA install, APK install — is Android only. iOS is supported as two Frida scripts you run manually against a jailbroken device; there is no iOS device manager and no guided iOS wizard.

Mobile and Frida are Hunter Pro (the MobileFrida feature), enforced at sandbox launch/configure, APK install, and mTLS export. The traffic-narration in Easy Mode Step 3 is Free; standing up the sandbox and running Frida are Pro.

03What you'll need

Pick the emulator path (the Easy Mode default) or a real device:

  • Emulator (recommended)Android Studio with the Android SDK. Use Create rootable emulator or crusader mobile provision [--api 34] [--name <avd>] so Crusader creates a rootable google_apis AVD and launches it with -writable-system. Stock Google Play emulator images refuse adb root and cannot receive the system CA this way.
  • Real device — must be rooted (Magisk or a userdebug build) for frida-server and the system-CA install. Without root you're limited to objection gadget repackaging, which is less reliable on hardened or anti-tamper apps.
  • Transport — USB / ADB.
  • Host tools — Android SDK platform-tools (adb) and the frida CLI (frida-tools). The gadget path additionally needs objection, apktool, java, and apksigner.

You don't have to install those by hand. Crusader can one-click install the host tools through your platform's package manager (winget / choco / scoop / brew / apt / pip / pipx) — it doesn't bundle them. frida-server and APKEditor.jar are downloaded on demand from their official GitHub releases.

ToolUsed forSource
adbDevice transport, install, proxy + CA setupCrusader one-click (platform-tools)
fridaRunning the pinning hook scriptCrusader one-click (frida-tools)
frida-serverOn-device agent the script attaches toDownloaded on demand (GitHub)
objection, apktool, java, apksignerNon-root gadget repackagingCrusader one-click

04Step 1 — Set up the sandbox

Open Easy Mode. The hero reads "Let's see what your app is doing." Step 1 is "Phone sandbox", with a status badge that moves through NEEDS SETUPALMOST READYREADYRUNNING as you go.

If you don't have a rootable lab yet, click Create rootable emulator. It installs or reuses the SDK pieces, downloads a rootable google_apis image if missing, creates the AVD, boots it with -writable-system, runs adb root, and then configures CA + proxy + Frida. If you already have a rootable AVD or device, use Launch sandbox and Set up the sandbox.

# CLI equivalent for a clean Android lab
crusader mobile provision --api 34 --name Crusader_Rootable_API34
crusader mobile devices
crusader mobile configure --device <serial> --port 8080
crusader mobile install-app ./target.apk --device <serial>
crusader mobile run com.example.app --device <serial>

Set up the sandbox is the heart of it. Behind one button it runs the full pipeline:

  1. Wait for the emulator to finish booting.
  2. Set the emulator's global HTTP proxy to 10.0.2.2:<port>10.0.2.2 is the emulator's alias for your host loopback, and <port> is your Crusader proxy port.
  3. Install the Crusader CA into the device's system trust store.
  4. Install and start frida-server on the device.
  5. Run a health check across all of the above.

While it works, the status line reads "Setting up frida-server, trusting CA, routing through proxy…". When it settles on READY / RUNNING, the device is proxied through Crusader, trusts your CA at the system level, and has Frida running — everything the bypass needs.

The system-CA install needs root. On the emulator that's the rootable google_apis image plus -writable-system; on a real device it's Magisk/userdebug. Crusader writes the classic store at /system/etc/security/cacerts/<hash>.0. On Android 14+ / API 34, where the runtime trust store lives inside the Conscrypt APEX, Crusader shadows /apex/com.android.conscrypt/cacerts and restarts zygote. That overlay is tmpfs, so re-run Set up the sandbox or crusader mobile configure after an emulator reboot.

05Step 2 — Load the test app

Step 2 of Easy Mode is "Pick a test app". Drop your own build into the zone marked "Or pick your own APK/XAPK/APKS", or start with one of the linked sample targets — OWASP Juice Shop, Damn Vulnerable Bank, InsecureBankv2, DIVA (linked for download, not bundled).

Crusader accepts .apk, .xapk, and .apks. The split-bundle formats (.xapk / .apks) are unzipped and cached, then installed with adb install or install-multiple as appropriate.

Before it installs, an ABI preflight checks the app's native libraries against the device. An app built only for armeabi-v7a won't run on an x86_64 / arm64 emulator, so Crusader stops with DEVICE MISMATCH instead of a cryptic adb failure. It also classifies the common install errors directly — NO_MATCHING_ABIS, INSTALL_FAILED_MISSING_SPLIT, VERSION_DOWNGRADE, TEST_ONLY, and more.

If you hit DEVICE MISMATCH, create an AVD whose ABI matches the app (commonly an arm64-v8a image for arm-only builds) and re-run the install. The preflight is telling you the binary can't execute on this device — no bypass will fix that.

06Step 3 — Run the pinning bypass

With the sandbox ready and the app installed, defeat the in-app pinning check. There is no single literal "one click" button for this — the one-click experience is Set up the sandbox (proxy + CA + frida) followed by running the pinning script from the picker.

Open the Mobile script picker and run "Kill SSL pinning (Android and iOS, aggressive)" (id android-pinning-killer). It's a Frida hook script — run via frida … -l <script> against the running app, not a gadget. It neutralizes pinning across the stack:

  • Android (Java) — OkHttp, Conscrypt, the platform TrustManager, WebView, and NetworkSecurityConfig.
  • Native — BoringSSL / OpenSSL, and Cronet.
  • iOSSecTrust, AFNetworking, Alamofire, and TrustKit.

Crucially, it preserves KeyManagers, so client-certificate authentication (mTLS) still works while pinning is disabled — you don't break a mutual-TLS app by bypassing its server pinning.

Once the script reports its hooks are in place, drive the app — log in, pull a screen, trigger a network call. The previously pinned HTTPS now negotiates against Crusader's leaf cert, and the requests land in your History. From there it's ordinary Crusader: scope it, send interesting requests to Repeater, run the scanner over the captured traffic.

All traffic is captured to History regardless of interception mode — intercept only decides whether requests pause. So you don't need Hold on to see the app's calls; turn it on only when you want to edit a request in flight.

07Detectability & limits

The aggressive script is powerful but loud. Know its edges before you lean on it:

  • It's detectable (High). The script's detectability rating is High, and apps with anti-tamper or runtime-integrity checks will notice the hooks and may crash, log you out, or silently degrade. Run it after passive recon has confirmed the app actually pins — don't reach for the most invasive tool first.
  • System-CA install needs root. Google Play emulator images do not allow adb root; use Crusader's rootable google_apis provisioner or a real rooted/userdebug device. On Android 14+ the Conscrypt APEX overlay is temporary, so rerun configuration after reboot.
  • iOS is manual. On iOS there's no device manager and no guided pipeline: you run the two Frida scripts yourself on a jailbroken device.
  • Non-root Android is weaker. Without root you fall back to objection gadget repackaging, which hardened and anti-tamper apps catch more readily than a clean frida-server attach.
  • Some paths are out of reach. Crusader does not handle Cloudflare device attestation or native-only Cronet mTLS paths — treat those as unsupported.

Sequence matters: passive recon to confirm pinning, then Set up the sandbox, then the bypass script. Leading with the aggressive hook on an anti-tamper app usually just tips your hand.

08Troubleshooting

No traffic in History after the bypass

Confirm the sandbox pipeline actually finished — the badge should be RUNNING and the status should have cleared "Setting up frida-server, trusting CA, routing through proxy…". If the proxy route or system CA didn't stick, even a perfect Frida hook produces nothing. Re-run Set up the sandbox and watch the health check.

App still rejects the connection

The pinning hook may not be covering this app's mechanism, or an anti-tamper check disabled it. Re-confirm pinning with passive recon, make sure the system CA is trusted (not just a user CA), and remember the script is detectable (High) — an integrity-checked app can defeat it.

System CA "installed" but not trusted

First confirm the device is actually rootable: stock Google Play emulator images refuse adb root, so use Create rootable emulator or crusader mobile provision. On Android 14+ Crusader shadows the Conscrypt APEX trust store and restarts zygote; because that overlay is tmpfs, rerun Set up the sandbox / crusader mobile configure after the emulator reboots. If Crusader used the Magisk-module fallback on a real device, reboot the device for it to take effect.

Install fails with DEVICE MISMATCH

The ABI preflight blocked an app whose native code doesn't match the device — e.g. an armeabi-v7a-only split against an x86_64/arm64 emulator. Use an AVD with a matching ABI image. Other install errors are classified too (NO_MATCHING_ABIS, INSTALL_FAILED_MISSING_SPLIT, VERSION_DOWNGRADE, TEST_ONLY).

The app needs a client certificate

If the app does mutual TLS, the pinning script preserves KeyManagers so mTLS keeps working — but to replay those requests yourself you need the client cert. That's a separate flow; see Extract mTLS client certs.

Want a guide that isn't here yet? Email [email protected].