agentsclimarketplace

Android mitm setup

Skill abedegno/reverse-engineering-companion/plugins/reverse-engineering-companion/skills/android-mitm-setup

Companion skills for mobile/web reverse engineering — pairs with android-reverse-engineering-skill

Install
npx -y skills add abedegno/reverse-engineering-companion --skill android-mitm-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Intercept a mobile Android app's HTTPS traffic on Android 7+ where TLS pinning is in force. Walks through rootable emulator selection, mitmproxy CA installation into the system trust store, proxy routing, and Frida-based pinning bypass. Use when you need to see what an Android app is sending over the wire — for security research, API documentation, or interoperability work.

SKILL.md

9.7 KB, ~2.4k tokens by cl100k_base, as published. Nobody here has run it

Android MITM Setup

Intercepting a mobile app's HTTPS traffic on a modern Android device requires four things working together: a rootable emulator (so you can write to the system trust store), mitmproxy on the host (decoding and re-issuing the TLS), a CA certificate the device actually trusts (system store, not user store, since Android 7+), and a Frida-injected runtime hook that disables the app's TLS-pinning logic. None of these pieces is hard; together they're the half-day-of-stack-overflow that this skill collapses into a checklist.

This skill is the dynamic counterpart to the static decompilation skill in android-reverse-engineering. Use both: jadx reads the APK, this gets you the wire traffic.

When this skill applies

  • Target is an Android app on API 24+ (Android 7+, where user-store CAs stopped being trusted for app traffic by default).
  • The app uses HTTPS — most do.
  • The app pins certificates (OkHttp CertificatePinner, TrustManager, or platform default after Android 7).
  • You have legal grounds to inspect the app's traffic (own software, written permission, disclosure programme, interoperability under applicable law).

If the app doesn't pin, you can skip the Frida step. If it uses gRPC or QUIC, mitmproxy 9+ has experimental support but you may need extra config.

Workflow

Phase 1: Pick a rootable emulator image

Use the Android Studio emulator (avdmanager / emulator) with a system image flavour that allows adb root. The flavour matters:

  • Google APIs (e.g. system-images;android-34;google_apis;arm64-v8a) — rootable, includes Play Services so most apps work.
  • Google Play (google_apis_playstore) — not rootable; Play Integrity / SafetyNet hardened. Spending an afternoon discovering this is a rite of passage.
  • AOSP / default — rootable but no Play Services; some apps refuse to start.

Create the AVD once:

avdmanager create avd \
    --name Pixel_API_34_GoogleAPIs \
    --package "system-images;android-34;google_apis;arm64-v8a" \
    --device pixel_6

Boot with a writable system partition so /system edits stick:

emulator -avd Pixel_API_34_GoogleAPIs -writable-system

If you want to use a physical device, you need a userdebug Android build (custom ROM like LineageOS) or Magisk on a stock build. The Magisk path is documented elsewhere; the emulator is faster to set up and easier to throw away.

Phase 2: Generate the mitmproxy CA and install it into the system store

Start mitmproxy once on the host so it generates ~/.mitmproxy/:

mitmproxy -p 8080
# Press q to quit — the cert files now exist in ~/.mitmproxy/
ls ~/.mitmproxy/
#   mitmproxy-ca-cert.cer  mitmproxy-ca-cert.pem  mitmproxy-ca.p12  ...

Compute the cert's old-style subject hash. Android's system CA directory uses <hash>.0 as the filename:

HASH=$(openssl x509 -inform PEM -subject_hash_old -in ~/.mitmproxy/mitmproxy-ca-cert.cer | head -1)
echo "$HASH"

Push the cert into the system store. On Android 10+ this requires -writable-system (see Phase 1) AND adb remount:

adb root
adb remount
adb push ~/.mitmproxy/mitmproxy-ca-cert.cer /system/etc/security/cacerts/${HASH}.0
adb shell chmod 644 /system/etc/security/cacerts/${HASH}.0
adb reboot

On Android 14+ the system CA directory moved to an APEX (/apex/com.android.conscrypt/cacerts/). mitmproxy documents the current path; check their docs if the steps above don't take.

After reboot, verify:

adb shell ls /system/etc/security/cacerts/ | grep "$HASH"
adb shell settings list global | grep cacerts   # sanity

Phase 3: Route emulator traffic through mitmproxy

Set the global proxy on the emulator to the host bridge alias 10.0.2.2:8080:

adb shell settings put global http_proxy 10.0.2.2:8080

Start mitmproxy on the host:

mitmproxy -p 8080

Open Chrome on the emulator and visit https://example.com — you should see the flow in mitmproxy and the page should load (TLS now terminates at mitmproxy with the new CA the device trusts).

To revert proxy:

adb shell settings put global http_proxy :0

Phase 4: Bypass TLS pinning with Frida

For most apps using OkHttp CertificatePinner or platform TrustManager, the default-trust path will now show pinning errors in the app: the app trusts the system CA store (Phase 2) but rejects any cert not matching its hardcoded pin.

The fix is to hook the pinning check at runtime. Steps:

# 1. Download frida-server matching your emulator architecture from
#    https://github.com/frida/frida/releases
#    (e.g. frida-server-16.x.x-android-arm64.xz)

# 2. Push and launch
adb push frida-server-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell "/data/local/tmp/frida-server &"

# 3. Install Frida tooling on the host
pipx install frida-tools     # or: pip install frida-tools

# 4. Verify connection
frida-ps -U | head

Then inject a pin-bypass script. Don't paste hook source into this skill — pinning bypass scripts evolve fast and Codeshare keeps them up to date. The canonical starting points:

Launch the app with the script:

frida -U -f com.example.app -l unpinning.js --no-pause

If the standard scripts don't take, the app has likely been R8-shrunk and the class/method signatures the script targets are now obfuscated to single-letter names. Typical resolution:

  1. Decompile the APK (android-reverse-engineering plugin) and search for CertificatePinner / checkServerTrusted / okhttp3 patterns.
  2. Identify the obfuscated class/method that calls them.
  3. Write a targeted hook on that specific class. See references/tls-pinning-bypass.md for the structure (not the source — pinning bypass for a specific APK should not be in a public repo).

Phase 5: Capture and document the contract

With traffic flowing through mitmproxy you should now see:

  • Auth flows (Auth0, OAuth, SAML) — the IdP host plus PKCE / state / nonce / audience.
  • Backend BFF / API gateway calls (Azure APIM, AWS API Gateway, CloudFront).
  • Feature-flag / experimentation calls (LaunchDarkly, Optimizely).
  • Telemetry (Firebase, Sentry, Datadog RUM).
  • WebSocket upgrades (game servers, real-time channels).

Save flows for replay:

mitmdump -p 8080 -w session.flows         # record
mitmdump -nr session.flows                # replay
mitmdump -nr session.flows -f "~u /api/"  # filter

This is the input to mobile-auth-replay if you want to drive the same contract from a desktop tool.

Common pitfalls

  • "Google Play" image instead of "Google APIs". Cannot adb root. Re-create the AVD.
  • Forgot -writable-system at boot. /system is read-only; cert push fails. Re-boot with the flag.
  • CA installed in user store via Settings → Security. Doesn't work on Android 7+ for app traffic. Must be system store.
  • Auth host fronted by a TLS-fingerprint WAF (Akamai, Cloudflare Bot Management). Irrelevant on the emulator itself — the real app's TLS stack passes. It matters in mobile-auth-replay where you replay from desktop. Note it now, address it there.
  • gRPC traffic shows as binary garbage. mitmproxy can decode gRPC with the --set http2_force_decode_for_gprc=true flag and a .proto (if you have one). Otherwise you'll see HTTP/2 envelopes with protobuf bodies — read them with protoc --decode_raw per message.

References

Pairs with

Scope reminder

These techniques produce traffic captures that can include credentials, tokens, PII, and other sensitive data even from your own account. Treat them like passwords: don't paste into bug reports, don't commit session.flows files to public repos, redact before sharing. If you're disclosing a finding to a vendor, send the redacted reproduction steps, not the raw flows.

Gives 0 of the 12 instructions most project setup skills give in ~2.4k tokens

Counted across 999 of the 1,637 authors here whose files we hold, read 2026-08-06

  • ask one question at a timein 29 of 999, across 28 files
  • detect the package manager from lockfilesin 28 of 999, across 9 files
  • present findings to the userin 25 of 999, across 4 files
  • explore current repo statein 24 of 999, across 3 files
  • update the agent skills block in place if it existsin 24 of 999, across 3 files
  • install husky lint-staged and prettierin 23 of 999, across 4 files
  • create the lintstagedrc filein 22 of 999, across 3 files
  • commit all changed filesin 22 of 999, across 3 files
  • run lint-staged to verify it worksin 22 of 999, across 3 files
  • initialize huskyin 21 of 999, across 2 files
  • create the husky pre-commit filein 21 of 999, across 2 files
  • create a prettierrc file if missingin 21 of 999, across 2 files

Said here and by no other author read

  • select a rootable google apis emulator image
  • boot the emulator with a writable system partition
  • generate the mitmproxy ca certificate
  • compute the certificate subject hash
  • push the certificate to the system trust store
  • route emulator traffic through the proxy

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.