End-to-end Android APK red-team pipeline — automated APK acquisition (Play Store + apkpure + apkmirror fallback), jadx decompilation, secret/URL/JWT/Firebase grep, pinned-cert extraction, exported-component enumeration, Frida runtime instrumentation templates, intent-injection probes. Built from an authorized external red-team engagement where 7 APKs were pulled manually, 4 download attempts truncated, and a hardcoded JWT + 30 internal API endpoints were recovered from one of the apps. Use when target has a mobile app catalogue (Play Store developer page), when you find an APK URL hosted on a web server, or when post-recon mentions "mobile app" in scope.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
End-to-end Android APK red-team pipeline — automated APK acquisition (Play Store + apkpure + apkmirror fallback), jadx decompilation, secret/URL/JWT/Firebase grep, pinned-cert extraction, exported-component enumeration, Frida runtime instrumentation templates, intent-injection probes. Built from an authorized external red-team engagement where 7 APKs were pulled manually, 4 download attempts truncated, and a hardcoded JWT + 30 internal API endpoints were recovered from one of the apps. Use when target has a mobile app catalogue (Play Store developer page), when you find an APK URL hosted on a web server, or when post-recon mentions "mobile app" in scope.
# Follow 302 redirects to actual download
curl -sk -L --max-time 60 --connect-timeout 10 \
"https://d.apkpure.net/b/APK/<package_id>?version=latest" \
-o "<package_id>.apk"# Or via the legacy d-XX.app-mirror.example.com mirror chain (we saw this work)
.xapk = a zip containing multiple split APKs (base + config.armeabi-v7a + config.en + etc.)
Unzip outer first, then unzip the inner base.apk or <package>.apk
Some apkpure downloads return truncated XAPK with missing EOCD signature — symptom of CDN rate-limiting; rotate IP and retry, OR use 7z x which is more lenient than unzip
# Standard unzip (works for clean APK)
unzip -o <package>.apk -d extracted_<package>/
# For truncated/repaired XAPK
7z x -y <package>.apk -o"extracted_<package>"# For nested XAPKfor inner in extracted_<package>/*.apk; domkdir -p "extracted_<package>/$(basename "$inner" .apk)"
unzip -o "$inner" -d "extracted_<package>/$(basename "$inner" .apk)"done
Stage 2 — DEX decompilation (jadx)
# Install
brew install jadx # macOS# or
wget https://github.com/skylot/jadx/releases/latest/download/jadx-1.5.x.zip
# Decompile
jadx -d decompiled_<package>/ <package>.apk
# For XAPK that contains multiple APKsfor inner in extracted_<package>/*.apk; do
jadx -d decompiled_<package>_$(basename"$inner" .apk)/ "$inner"done
For a fast "strings only" pass without full decompilation:
Real-world example finding (anonymized — from an authorized engagement)
# Customer-facing APK shipped a hardcoded URL of this shape:
https://api.<client>.example/<path-token>/<resource-token>?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.<payload>.<sig>
# Decoded JWT payload: {"sid":<int>,"iat":<unix-ts>,"exp":<unix-ts>}
# Expired ~8 years earlier — but path tokens + 30 /v1/* endpoints still useful intel
Stage 4 — Pinned certificate extraction
# Find .cer / .der / .pem files in assets/
find extracted_<package>/assets -iname "*.cer" -o -iname "*.der" -o -iname "*.pem" -o -iname "*.crt" 2>/dev/null
# Or in network_security_config.xml
find extracted_<package> -name "network_security_config.xml" -execcat {} \;
# For each cert, extract subject + SAN (might reveal new internal API hosts)for cert in $(find extracted_<package>/assets -iname "*.cer"); doecho"=== $cert ==="
openssl x509 -in"$cert" -noout -subject -issuer -dates 2>/dev/null
openssl x509 -in"$cert" -noout -text 2>/dev/null | grep -E 'Subject:|DNS:|Issuer:|Validity'done
Real-world example
A customer-facing APK from an authorized engagement contained assets/api_<service>_<domain>_com.cer — revealed the existence of an api.<service>.<domain>.example asset that had NOT surfaced in passive recon.
Stage 5 — Exported component enumeration
AndroidManifest.xml lists components. Exported ones (especially with android:exported="true" or implicit-export via intent-filter) can be triggered by other apps — potential intent-injection attack surface.
# Decode binary AndroidManifest if needed
apktool d <package>.apk -o decoded_<package>/ # apktool decodes binary manifest# Or read directly from jadx outputcat decompiled_<package>/resources/AndroidManifest.xml | grep -E '<(activity|service|receiver|provider)' | head -50
# Filter exported
grep -E 'android:exported="true"' decompiled_<package>/resources/AndroidManifest.xml
For each exported component, check:
Does it accept extras that flow into a WebView (intent → WebView → XSS / file://)
Does it accept URI extras (potential SSRF via deep link)
Does it pass extras to other Activities (intent redirection)
For deeper API discovery once pinning is bypassed.
# Run mitmproxy on host
mitmproxy --listen-port 8080
# Configure Android device proxy to host:8080# Install mitmproxy CA cert on device:# - Pull from http://mitm.it on the device, or# - Push to /system/etc/security/cacerts/ on rooted device# Use the Frida pinning bypass script while traffic flows through mitmproxy# All API calls visible in mitmproxy UI
Decision tree — what to do with what you find
Finding
Next move
Active JWT (not expired)
Test against the API host — does it grant access? Try sid manipulation
Expired JWT
Inspect path tokens / API endpoint structure — useful intel for post-VPN
AWS access key
Use awscli to test: aws sts get-caller-identity — many leaked keys still have permissions
Firebase project_id + web_api_key
Test public Firestore/RTDB/Storage read
Google API key (AIza*)
Test against https://www.googleapis.com/customsearch/v1 etc. — see what API the key activates
Hardcoded HTTP URLs (http://)
Possible MITM via downgrade if cert pinning is missing
Pinned cert for internal host
New asset discovery — that host is real
Exported Activity with WebView
Test intent-injection → URL-loading abuse
Stack-trace artifacts (Stack Overflow URLs)
Identify the developer's questions → infer architecture
Hardcoded credentials
Spray immediately (respect any caps from related skills)
Pitfalls
Don't grep only for "password" — most secrets have specific high-signal patterns (AKIA, AIza, eyJ, etc.). Generic word grep produces too much noise.
Don't skip XAPK split APKs — config.armeabi splits and config. splits sometimes contain different code paths.
Don't trust expired JWTs as "dead intel" — the path structure, endpoint list, and signing algorithm are still useful. The 8-year-expired-JWT example above shows this.
Don't reverse only the latest version — older APK versions (via APKMirror version history) sometimes have secrets removed in newer versions but still active server-side.
Don't ignore Firebase even if app looks "simple" — Firebase rules misconfigurations (public read on Firestore) are extremely common.
Don't run Frida on a production device — use rooted emulator or test device only.
APKPure CDN rate-limiting — truncated downloads with missing EOCD are common. Rotate IP (VPN hop) and retry; 7z x is more lenient than unzip for partially-downloaded archives.
Large APKs can OOM jadx — for APKs >100 MB, increase jadx heap with -Xmx4g or fall back to strings-only pass first.
Keystore/SQLite files in assets/ — overlooked because they don't match regex secret patterns. Manually review assets/ directory tree for .db, .sqlite, .jks, .bks, .p12 files.
ProGuard/R8 obfuscation — most APKs are obfuscated; secret patterns survive renaming, but class names don't. Don't dismiss an APK because method names are a.b.c.d.
Multi-dex APKs — some secrets live in classes2.dex onward; don't stop after classes.dex.
Play Store developer pages may list inactive/beta apps — cross-reference with download counts and last-updated dates; stale apps may have been archived but still expose secrets.
Verification
Run this self-test to confirm the pipeline works end-to-end:
Acquisition test — download any publicly-available APK and verify the file is a valid ZIP:
download-apk() {
local pkg="$1"
curl -sk -L --max-time 60 --connect-timeout 10 "https://d.apkpure.net/b/APK/$pkg?version=latest" -o "/tmp/$pkg.apk"
file "/tmp/$pkg.apk"# should report: Zip archive data / Java archive data
}
download-apk org.example.testapp
Decompilation test — apktool decodes the binary manifest:
apktool d /tmp/org.example.testapp.apk -o /tmp/testapp_decoded/
ls /tmp/testapp_decoded/AndroidManifest.xml 2>/dev/null && echo"PASS: manifest decoded" || echo"FAIL: apktool not installed or APK corrupted"
Secret grep test — confirm patterns match known test values:
If all 5 tests pass, the pipeline is operational. Test 1 (acquisition) may fail due to APKPure CDN blocking — this does not block the rest of the workflow; fall back to APKMirror or direct APK URL.
Tooling install (one-time)
brew install jadx p7zip
pip install --break-system-packages frida-tools objection
# Genymotion or AVD for rooted Android emulator
For APK download convenience, can add a download-apk shell function:
Finding: Hardcoded JWT + 30+ Internal API Endpoints in a customer-facing APK
Subject: Hardcoded artifacts in legacy mobile build reveal internal API surface
Observations: Decompilation of com.<client>.<app> revealed embedded JWT (expired ~8 years earlier) and 30+ /v1/* endpoint paths against api2.<client>.example (internal-only externally)
Description: APK ships with developer build artifacts. Path tokens are security-by-obscurity; API endpoint inventory is reconnaissance-grade.
Impact: Post-VPN-foothold (via cred compromise), attacker has full API surface map without binary reverse. HS256 secret recovery (via SSRF/LFI) would yield arbitrary token forging.
Recommendation: rotate HS256 secret, migrate to RS256, remove hardcoded URLs from builds, audit all org APKs.
cloud-iam-deep — APK secret extraction frequently yields live AWS/GCP/Azure credentials. Chain primitive: jadx string-grep produces AWS Access Key ID + Secret → cloud-iam-deepaws sts get-caller-identity → role/policy enumeration → IAM privilege-escalation path (one of 24 documented AWS escalation patterns) → cloud-plane takeover. Same flow applies to GCP service-account JSON and Azure shared-access-signature tokens extracted from APK resources.
hunt-api-misconfig — APK endpoint inventory hands you the API surface for free; mass-assignment, JWT, and CORS bugs are typical. Chain primitive: APK reveals /v1/users/me and /v1/admin/users → hunt-api-misconfig mass-assignment probes ({is_admin:true}) against /v1/users/me → admin role escalation → access to /v1/admin/users.
hunt-rce — Hardcoded JWT signing secrets (HS256) extracted from APK enable arbitrary token forging. Chain primitive: APK strings yield HS256 secret → forge admin token → access admin API → if API has eval/template/sink → hunt-rce to server. Also: exported components with intent-injection sinks can reach Runtime.exec if app is local-installed.
offensive-osint — APK is one node in the broader org recon graph; pair with breach corpora and cert transparency. Chain primitive: APK reveals internal API hostname api2.example.com → offensive-osint certificate-transparency lookup → discover sibling subdomains → expanded attack surface.
redteam-report-template — APK findings need clear "what the binary leaks" framing because client engineers often dismiss mobile-static findings as "obfuscation problem." Chain primitive: validated finding (token/URL/secret extracted) → triage-validation 7-Question Gate (specifically: "does this credential still authenticate today?") → redteam-report-template packaging with explicit binary version + extraction reproduction steps.