$npx -y skills add elementalsouls/Claude-BugHunter --skill apk-redteam-pipelineEnd-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 pr
| 1 | ## When to use this skill |
| 2 | |
| 3 | Trigger when: |
| 4 | - Recon surfaces 1+ mobile apps under the target's developer name (Play Store dev page) |
| 5 | - A web app hosts `*.apk` files directly (e.g. `Recruitz.apk` found on a subdomain during one engagement) |
| 6 | - APK package IDs leaked via stealer logs (e.g. `com.<brand>.app`, `com.<brand>.<sub-brand>` patterns in stealer dump format) |
| 7 | - Customer-facing app, dealer/partner portal, or employee mobile companion app is in scope |
| 8 | - Bug bounty program lists Android in scope |
| 9 | |
| 10 | DO NOT use for: |
| 11 | - iOS-only targets (different pipeline — IPA reverse, MobSF, frida-ios-dump) |
| 12 | - React Native / Flutter web apps already covered by JS bundle analysis |
| 13 | - Server-side only assessments |
| 14 | |
| 15 | --- |
| 16 | |
| 17 | ## Stage 0 — Inventory all org-owned apps |
| 18 | |
| 19 | ### Play Store developer-page scrape |
| 20 | ```bash |
| 21 | # Find developer page from the target's brand name |
| 22 | curl -sk -A "Mozilla/5.0" "https://play.google.com/store/apps/developer?id=<Brand+Name>" -o /tmp/dev.html |
| 23 | |
| 24 | # Extract package IDs |
| 25 | grep -oE 'id=[a-zA-Z0-9._]+' /tmp/dev.html | sort -u |
| 26 | ``` |
| 27 | |
| 28 | Example output (anonymized — 7 packages typical for a multi-brand conglomerate): |
| 29 | ``` |
| 30 | com.events.<brand>build |
| 31 | com.<corp>.<sub-brand-1> |
| 32 | com.<corp>.<sub-brand-2> |
| 33 | com.<corp>.<flagship> |
| 34 | com.<corp>.<product-line-1> |
| 35 | com.<corp>.<product-line-2> |
| 36 | com.<corp>.<sub-brand-3> |
| 37 | ``` |
| 38 | |
| 39 | ### Cross-reference with stealer logs |
| 40 | Stealer-log format includes package names like `*@com.<corp>.<app>` — extract these from `creds_userpass.txt` if you have a leaked dump. |
| 41 | |
| 42 | ### Brand permutation guesses (multi-brand conglomerate patterns) |
| 43 | ``` |
| 44 | com.<brand>.app |
| 45 | com.<brand>.mobile |
| 46 | com.<brand>.android |
| 47 | com.<brand>connect.app |
| 48 | in.<brand>.dealer |
| 49 | in.co.<brand>.app |
| 50 | ``` |
| 51 | |
| 52 | --- |
| 53 | |
| 54 | ## Stage 1 — APK acquisition |
| 55 | |
| 56 | ### Primary: APKPure direct (no auth required) |
| 57 | ```bash |
| 58 | # Follow 302 redirects to actual download |
| 59 | curl -sk -L --max-time 60 \ |
| 60 | "https://d.apkpure.net/b/APK/<package_id>?version=latest" \ |
| 61 | -o "<package_id>.apk" |
| 62 | |
| 63 | # Or via the legacy d-XX.winudf.com mirror chain (we saw this work) |
| 64 | ``` |
| 65 | |
| 66 | ### Secondary: APKMirror search |
| 67 | ```bash |
| 68 | curl -sk -A "Mozilla/5.0" "https://www.apkmirror.com/?post_type=app_release&searchtype=apk&s=<brand>" \ |
| 69 | | grep -oE 'href="[^"]+\.apk[^"]*"' | sort -u |
| 70 | ``` |
| 71 | |
| 72 | ### Tertiary: APKPure web search |
| 73 | ```bash |
| 74 | curl -sk "https://apkpure.com/search?q=<brand>" | grep -oE 'data-dt-app="[^"]+"' |
| 75 | ``` |
| 76 | |
| 77 | ### XAPK vs APK |
| 78 | - `.xapk` = a zip containing multiple split APKs (base + config.armeabi-v7a + config.en + etc.) |
| 79 | - Unzip outer first, then unzip the inner `base.apk` or `<package>.apk` |
| 80 | - 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` |
| 81 | |
| 82 | ```bash |
| 83 | # Standard unzip (works for clean APK) |
| 84 | unzip -o <package>.apk -d extracted_<package>/ |
| 85 | |
| 86 | # For truncated/repaired XAPK |
| 87 | 7z x -y <package>.apk -o"extracted_<package>" |
| 88 | |
| 89 | # For nested XAPK |
| 90 | for inner in extracted_<package>/*.apk; do |
| 91 | mkdir -p "extracted_<package>/$(basename "$inner" .apk)" |
| 92 | unzip -o "$inner" -d "extracted_<package>/$(basename "$inner" .apk)" |
| 93 | done |
| 94 | ``` |
| 95 | |
| 96 | --- |
| 97 | |
| 98 | ## Stage 2 — DEX decompilation (jadx) |
| 99 | |
| 100 | ```bash |
| 101 | # Install |
| 102 | brew install jadx # macOS |
| 103 | # or |
| 104 | wget https://github.com/skylot/jadx/releases/latest/download/jadx-1.5.x.zip |
| 105 | |
| 106 | # Decompile |
| 107 | jadx -d decompiled_<package>/ <package>.apk |
| 108 | |
| 109 | # For XAPK that contains multiple APKs |
| 110 | for inner in extracted_<package>/*.apk; do |
| 111 | jadx -d decompiled_<package>_$(basename "$inner" .apk)/ "$inner" |
| 112 | done |
| 113 | ``` |
| 114 | |
| 115 | For a fast "strings only" pass without full decompilation: |
| 116 | ```bash |
| 117 | find extracted_<package> -name "classes*.dex" -exec strings -8 {} \; > strings_<package>.txt |
| 118 | ``` |
| 119 | |
| 120 | --- |
| 121 | |
| 122 | ## Stage 3 — Secret grep (the 60-pattern catalog) |
| 123 | |
| 124 | ```bash |
| 125 | # URL grep — owned-domain references |
| 126 | grep -oE 'https?://[a-zA-Z0-9.-]+\.(target1|target2|target3)\.(com|io|net|in)[a-zA-Z0-9./_?=&%-]*' strings_<package>.txt | sort -u |
| 127 | |
| 128 | # Internal IP / port URLs |
| 129 | grep -oE 'https?://(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)[0-9.]+(:[0-9]+)?[a-zA-Z0-9./_?=&-]*' strings_<package>.txt |
| 130 | |
| 131 | # Cloud credentials |
| 132 | grep -oE 'AKIA[A-Z0-9]{16}' # AWS Access Key |
| 133 | grep -oE 'aws_secret_access_key[\s:=]+[A-Za-z0-9/+=]{40}' # AWS Secret |
| 134 | grep -oE 'AIza[A-Za-z0-9_-]{35}' # Google API key |
| 135 | grep -oE 'ya29\.[ |