[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F7XE5BPDPXJ3WQ0XRJS4K0":3,"skill-same:01M6F7XE5BPDPXJ3WQ0XRJS4K0":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":22,"commitSha":57,"skillDirectory":58,"forksCount":59,"repositoryHtmlUrl":60,"repositoryHomepageUrl":6,"ownerHtmlUrl":61,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":62,"install":63,"resources":76},"01M6F7XE5BPDPXJ3WQ0XRJS4K0","ios-redteam-pipeline",null,"End-to-end iOS red-team pipeline","boisenoise\u002Fskills-collections","boisenoise","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F193180?v=4","01M6CDBDQK6BDN55ZMA6B6PKBM","01M6CDBDVSJ3JPTBYN26FZ7TZK",12,"MIT","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-ios-redteam-pipeline\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"RedTeam","ios redteam pipeline","ios","pipeline","main","2026","for","relevant","helper","offensive","team pipeline","scripts","scope","red","end","commands","testing","community","only","team","Tools","owasp","red-team","license","research","security","github","2026-11-10 10:12:30",false,"---\nname: ios-redteam-pipeline\ndescription: End-to-end iOS red-team pipeline\ncategory: security\nrisk: offensive\nsource: https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter\nsource_repo: elementalsouls\u002FClaude-BugHunter\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires explicit written authorization for a target scope plus the\n  relevant testing tools for this technique. Docs-only; helper scripts and commands\n  not bundled.\nsources: public_research, frida_docs, objection_docs, owasp_mastg\nreport_count: 0\n---\n> **⚠️ AUTHORIZED USE ONLY**\n> This skill is for educational purposes or authorized security assessments only.\n> You must have explicit, written permission from the system owner before using this tool.\n> Misuse of this tool is illegal and strictly prohibited.\n\n> **Mandatory confirmation gate**\n> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:\n> 1. Ask the user to state the exact target URL, IP, account, or resource.\n> 2. Ask the user to confirm written authorization and the permitted scope.\n> 3. Show the exact command(s) and explain their expected effect.\n> 4. Wait for explicit confirmation in the current conversation.\n>\n> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.\n\n## When to use this skill\n\nTrigger when:\n- Recon surfaces 1+ apps under the target's Apple Developer \u002F App Store publisher page\n- A TestFlight public link or enterprise\u002Fad-hoc `.ipa`\u002F`manifest.plist` (OTA install) is found\n- Customer-facing app, dealer\u002Fpartner portal, or employee mobile companion app ships on iOS\n- Bug bounty program lists iOS in scope\n- `apk-redteam-pipeline` already found Android endpoints\u002Fsecrets — the iOS build often ships a *different* backend version worth diffing (see `hunt-shadow-api`)\n\nDO NOT use for:\n- Android-only targets — that's `apk-redteam-pipeline`\n- A task limited to web bundles with no authorized iOS scope; React Native\u002FFlutter native bridges, entitlements and platform storage still need iOS-specific review when in scope\n- Server-side only assessments with no mobile client in scope\n\n---\n\nUse a dedicated authorized test device\u002Faccount and private evidence directory. Establish whether app binary, backend, credential validation, TLS instrumentation and test-CA\u002Fprofile changes are each in scope; record\u002Fremove test profiles and artifacts afterward. Never use discovered keys merely because they exist: public Firebase config is not automatically a secret, and network access needs separate target confirmation. Create a virtual environment before Python installs, pin\u002Freview tools\u002Fscripts and check installed --help; legacy flags such as --no-pause and objection subcommands may differ. No universal TLS hook guarantees coverage across all stacks.\n\n## Stage 0 — Inventory all org-owned iOS apps\n\n```bash\n# App Store search API (no auth, no scraping needed)\ncurl -s \"https:\u002F\u002Fitunes.apple.com\u002Fsearch?term=\u003Cbrand>&country=us&entity=software&limit=50\" | python3 -m json.tool\n\n# Pull the full metadata for a known bundle ID (once you have one)\ncurl -s \"https:\u002F\u002Fitunes.apple.com\u002Flookup?bundleId=com.\u003Cbrand>.app&country=us\"\n```\n\nExtract: `trackId`, `bundleId`, `sellerName` (developer account — pivot to find sibling apps), `version`,\n`releaseNotes` (changelogs often reference deprecated\u002Fremoved API behavior — feeds `hunt-shadow-api`).\n\nCross-reference sibling-app bundle IDs surfaced from Android APK inventories (same\nmulti-brand conglomerate usually reuses `com.\u003Ccorp>.\u003Csub-brand>` naming on both platforms).\n\n---\n\n## Stage 1 — IPA acquisition\n\n### Primary: from a real device you control (no jailbreak needed for a purchased\u002Ffree app)\n```bash\n# Obtain an owner-provided test IPA\u002Fbuild when possible. Installing\u002Flisting apps does not\n# itself export a decryptable IPA; Configurator\u002FXcode extraction depends on supported workflow.\n# Or via libimobiledevice:\nbrew install libimobiledevice ideviceinstaller\nideviceinstaller -l              # list installed apps + bundle IDs\n```\n\n### Secondary: TestFlight (if the program distributes betas publicly)\nOpen the public TestFlight link, install via the TestFlight app, then extract as above.\nTestFlight builds are frequently LESS hardened than App Store releases (debug logging left on,\nstaging API hosts hardcoded) — compare channel\u002Fbuild\u002Fversion; a beta finding does not establish production exposure.\n\n### Tertiary: enterprise \u002F ad-hoc distribution (OTA install)\n```bash\n# itms-services:\u002F\u002F links embed a manifest.plist with a direct .ipa URL\ncurl -s \"https:\u002F\u002F\u003Ctarget>\u002Fmanifest.plist\" | plutil -convert xml1 -o - -\n# Look for \u003Ckey>software-package\u003C\u002Fkey> — that URL is a directly downloadable, unencrypted IPA\ncurl --fail --show-error --proto =https --proto-redir =https --max-time 120 \"\u003Capproved-software-package-url>\" -o target.ipa\n```\nEnterprise\u002Fad-hoc IPAs are **not FairPlay-encrypted** — no jailbreak or decryption tooling needed,\nunlike an App Store binary pulled from a device.\n\n### Decrypting an App-Store-sourced binary (only if extracted from a jailbroken device)\nApp Store binaries are FairPlay-encrypted at rest; a binary copied off a jailbroken device\nneeds runtime decryption (`frida-ios-dump`, `bagbak`, or `flexdecrypt`) before static tools can\nread it meaningfully:\n```bash\npython -m pip install frida-tools\n# with frida-server running on the jailbroken device and the app in foreground:\npython3 dump.py \u003Cbundle_id>          # frida-ios-dump — outputs a decrypted .ipa\n```\n\n---\n\n## Stage 2 — Unpack and static analysis\n\n```bash\n# An IPA is just a zip\nunzip -l target.ipa  # inspect archive paths\u002Fsize first; reject traversal\u002Fsymlinks\u002Foversized entries\n# Extract only in a fresh private directory with an archive tool that enforces containment.\nunzip target.ipa -d extracted_target\u002F\ncd extracted_target\u002FPayload\u002F*.app\n\n# Info.plist — bundle ID, URL schemes, ATS config, entitlements hint\nplutil -convert xml1 -o - Info.plist\n\n# Entitlements — codesign reads the .app bundle (or the Mach-O binary), NOT Info.plist\ncodesign -d --entitlements :- . 2>\u002Fdev\u002Fnull || \\\n  security cms -D -i embedded.mobileprovision | plutil -convert xml1 -o - -\n\n# class-dump for Objective-C symbol\u002Fclass recovery (compiled binary, not the .app bundle)\nbrew install class-dump\nclass-dump -H \u003CAppBinaryName> -o headers\u002F\n\n# Swift binaries: class-dump won't show much — use Hopper, Ghidra, or `nm`\u002F`strings` instead\nnm -a \u003CAppBinaryName> | grep -i swift | head -50\nstrings -a \u003CAppBinaryName> > strings_target.txt\n```\n\nFor a fast triage pass without a disassembler, the strings dump alone usually surfaces most of\nwhat Stage 3 is looking for.\n\n---\n\n## Stage 3 — Secret grep (same catalog as apk-redteam-pipeline, iOS-specific sources added)\n\n```bash\n# URL grep — owned-domain references\ngrep -oE 'https?:\u002F\u002F[a-zA-Z0-9.-]+\\.(target1|target2|target3)\\.(com|io|net)[a-zA-Z0-9.\u002F_?=&%-]*' strings_target.txt | sort -u\n\n# Cloud credentials (same 60-pattern catalog as Android — reuse verbatim)\ngrep -oE 'AKIA[A-Z0-9]{16}' strings_target.txt          # candidate ID, not proof of valid credential\ngrep -oE 'AIza[A-Za-z0-9_-]{35}' strings_target.txt     # may be public\u002Frestricted app configuration\ngrep -oE 'eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*' strings_target.txt   # JWT\n\n# iOS-specific: GoogleService-Info.plist (Firebase config bundled per-platform)\nfind . -iname \"GoogleService-Info.plist\" -exec plutil -convert xml1 -o - {} \\;\n# Look for API_KEY, PROJECT_ID, STORAGE_BUCKET, GCM_SENDER_ID, GOOGLE_APP_ID — same Firebase\n# public-read tests as apk-redteam-pipeline Stage 6.\n\n# iOS-specific: hardcoded config plists shipped in the bundle\nfind . -iname '*.plist' ! -iname 'Info.plist' -exec sh -c 'for p do printf \"=== %s ===\\n\" \"$p\"; plutil -convert xml1 -o - \"$p\"; done' sh {} +\n\n# App Transport Security exceptions (Info.plist) — tells you if arbitrary\u002Finsecure loads are allowed\nplutil -extract NSAppTransportSecurity xml1 -o - Info.plist 2>\u002Fdev\u002Fnull\n```\n\n### Keychain items left in a backup (if you have a device backup, encrypted or not)\n```bash\npython -m pip install iphone_backup_decrypt   # for encrypted local backups\n# keychain-dumper (run ON a jailbroken device) for live keychain contents:\n.\u002Fkeychain-dumper -e   # -e also decodes entitlements per item, showing which app owns which secret\n```\n\n---\n\n## Stage 4 — App Transport Security (ATS) misconfig + certificate-pinning bypass\n\n### Check for blanket ATS disablement (the single most common iOS network misconfig)\n```bash\nplutil -extract NSAppTransportSecurity xml1 -o - Info.plist\n```\nRed flags in the output:\n- `NSAllowsArbitraryLoads = true` at the top level — HTTP (cleartext) allowed anywhere, app-wide.\n- Per-domain `NSExceptionAllowsInsecureHTTPLoads = true` for a domain that carries auth tokens.\n- `NSAllowsArbitraryLoadsInWebContent = true` — WKWebView traffic exempted, common blind spot.\n\nA blanket ATS exception + a network position (rogue AP, ARP spoof, malicious VPN profile) =\nplaintext credential\u002Ftoken interception without touching pinning at all.\n\n### Certificate-pinning bypass (when pinning IS present and correctly configured)\n```bash\npython -m pip install frida-tools objection\nobjection --gadget \u003Cbundle_id> explore\n# inside objection:\nios sslpinning disable\n```\nIf you want a Frida script instead, don't hand-roll one — use a maintained universal bypass\n(e.g. the widely-used `frida-ios-pinning`\u002F`ios-ssl-bypass` community scripts). Modern iOS TLS goes\nthrough **BoringSSL**, so a reliable universal hook targets `SSL_CTX_set_custom_verify` \u002F\n`SSL_get_psk_identity` at the native layer and forces the verify callback to return \"OK\" — this\ncatches `URLSession`, `AFNetworking`, `Alamofire`, and `TrustKit` at once, which per-delegate\nObjective-C hooks (like the deprecated `NSURLConnection` delegate) miss:\n```bash\n# Pull a maintained universal BoringSSL-layer bypass and run it:\nfrida -U -f \u003Cbundle_id> -l ios-ssl-bypass.js --no-pause\n```\nIn practice, prefer **SSL Kill Switch 2** (jailbroken device, installs as a tweak) or\n**objection's `ios sslpinning disable`** over any hand-rolled script — both cover the common\npinning implementations (`NSURLSession`, `AFNetworking`, `TrustKit`) without per-app tuning.\n\n---\n\n## Stage 5 — URL scheme \u002F Universal Link enumeration\n\n```bash\n# Custom URL schemes (CFBundleURLTypes) — anything can invoke these via Safari\u002Fanother app\nplutil -extract CFBundleURLTypes xml1 -o - Info.plist\n\n# Universal Links \u002F Associated Domains (applinks:) — requires a matching apple-app-site-association\ncodesign -d --entitlements :- .  # associated-domains belongs to signed entitlements, not Info.plist\ncurl -s \"https:\u002F\u002F\u003Cdomain>\u002F.well-known\u002Fapple-app-site-association\" | python3 -m json.tool\n```\n\nFor each custom scheme found (e.g. `myapp:\u002F\u002F`):\n- Trigger it from Safari\u002FNotes and observe what the app does with parameters:\n  `myapp:\u002F\u002Freset-password?token=x&redirect=https:\u002F\u002Fevil.com` — does the app trust an\n  attacker-supplied `redirect`\u002F`url`\u002F`callback` param and load it in a WebView (open-redirect →\n  WebView-XSS chain) or use it to bypass an auth screen?\n- If the scheme is also registered by another app on the device (scheme squatting), a malicious\n  app can intercept traffic intended for the legitimate app — check `CFBundleURLName` uniqueness.\n- Failed Universal Link association normally leaves an HTTPS web link; any custom-scheme fallback is application-specific and must be observed, not assumed.\n\n---\n\n## Stage 6 — Runtime instrumentation (Frida \u002F objection)\n\nUse an authorized compatible test environment. Frida supports jailbroken devices and debuggable apps without jailbreak (Gadget\u002Fdeveloper setup); support depends on the build\u002Fdevice.\n\n```bash\n# Setup\npython -m pip install frida-tools objection\n# Install frida-server on the jailbroken device via Cydia\u002FSileo (frida repo), matching the\n# host frida-tools version exactly — version skew is the #1 cause of \"failed to attach\" errors.\n\n# Full interactive exploration\nobjection --gadget \u003Cbundle_id> explore\n# Inside objection:\nios hooking watch class \u003CClassName>\nios hooking watch class_method \u003CClass>.\u003Cmethod> --dump-args --dump-return\nios keychain dump\nios plist dump\nios cookies get\n```\n\n### Network traffic capture (once pinning is bypassed)\n```bash\nmitmproxy --listen-port 8080\n# Set the device Wi-Fi proxy to host:8080, install the mitmproxy CA via http:\u002F\u002Fmitm.it on-device\n# (Settings > General > VPN & Device Management > trust the cert, then enable full trust under\n# Certificate Trust Settings — iOS requires this second step, unlike Android)\n```\n\n---\n\n## Decision tree — what to do with what you find\n\n| Finding | Next move |\n|---|---|\n| `NSAllowsArbitraryLoads = true` | Confirm a token\u002Fcredential actually transits HTTP — needs a network position to exploit, but is a real finding on its own (config-level, no MITM needed to report) |\n| Hardcoded JWT \u002F API key in strings dump | Same as Android — test against the API host, chain into `hunt-api-misconfig` |\n| GoogleService-Info.plist present | Test public Firestore\u002FRTDB\u002FStorage read (identical to apk-redteam-pipeline Stage 6) |\n| Custom URL scheme accepts a `redirect`\u002F`url` param | Test open-redirect → WebView-load chain; check for scheme squatting by other installed apps |\n| Universal Link AASA missing\u002Fmisconfigured | Confirm scheme fallback still carries the same injectable params |\n| Entitlements show `keychain-access-groups` shared with other apps | Cross-app Keychain read — a compromised sibling app reads this app's secrets |\n| Older API version referenced vs. what the current web app calls | Hand off to `hunt-shadow-api` for version-diffing |\n\n---\n\n## Anti-patterns\n\n- **Don't assume App Store = FairPlay-encrypted requires jailbreak** — TestFlight and enterprise\u002Fad-hoc\n  builds are frequently NOT encrypted and need no decryption step at all. Always check distribution\n  channel before reaching for `frida-ios-dump`.\n- **Don't skip Swift binaries because class-dump shows nothing** — `strings` and `nm` still work; a\n  proper Swift-aware disassembler (Hopper, Ghidra with Swift demangling) recovers the rest.\n- **Don't stop at \"pinning is present\" as a finding** — pinning is a mitigation, not a vulnerability;\n  the finding is what you can do once it's bypassed (or the ATS misconfig that makes it moot).\n- **Don't ignore WKWebView-loaded content** — `NSAllowsArbitraryLoadsInWebContent` is a distinct,\n  frequently-overlooked exception from the top-level ATS setting.\n- **Don't run Frida instrumentation against a personal\u002Fproduction Apple ID device** — use a\n  dedicated jailbroken test device or Corellium instance.\n\n---\n\n## Tooling install (one-time)\n\n```bash\nbrew install libimobiledevice ideviceinstaller class-dump\npython -m pip install frida-tools objection iphone_backup_decrypt\n# Jailbroken test device (checkra1n\u002Fpalera1n) or a Corellium virtual iOS device for runtime work\n# frida-server installed on-device via the Frida Cydia\u002FSileo repo\n```\n\n---\n\n## Related Skills & Chains\n\n- **`apk-redteam-pipeline`** — the Android counterpart; run both when a target ships on both\n  platforms. Sibling bundle IDs and shared backend endpoints frequently surface cross-platform.\n- **`hunt-shadow-api`** — mobile builds (iOS and Android alike) often hardcode an older API\n  version than the current web app. Chain: IPA reveals `\u002Fv1\u002F*` endpoints → `hunt-shadow-api`\n  diffs `\u002Fv1\u002F` against the current `\u002Fv3\u002F` for auth\u002Fvalidation regressions.\n- **`cloud-iam-deep`** — IPA secret extraction frequently yields live AWS\u002FGCP\u002FAzure credentials\n  or Firebase configs. Chain: strings-grep produces an AWS key → `cloud-iam-deep` privilege\n  analysis.\n- **`hunt-api-misconfig`** — hardcoded JWTs\u002FAPI keys extracted here feed directly into JWT\n  algorithm-confusion and mass-assignment testing there.\n- **`evidence-hygiene`** — extracted Keychain items and secrets need redaction before report\n  inclusion.\n- **`offensive-osint`** — App Store developer-page enumeration is part of the broader org recon\n  graph; pair with certificate-transparency lookups for the same brand.\n\n## Limitations\n\n- Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command.\n- Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed.\n- Validate every finding (see `triage-validation`) before reporting; report via `report-writing`. Prefer a sandbox, disposable VM, or controlled lab.\n\n### Example\n\n```bash\n# Read-only first step; confirm scope before anything active.\ncat scope.txt  # target list from the authorized engagement brief\n```\n\n> Adapted from [elementalsouls\u002FClaude-BugHunter](https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.\n","> **⚠️ AUTHORIZED USE ONLY**\n> This skill is for educational purposes or authorized security assessments only.\n> You must have explicit, written permission from the system owner before using this tool.\n> Misuse of this tool is illegal and strictly prohibited.\n\n> **Mandatory confirmation gate**\n> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:\n> 1. Ask the user to state the exact target URL, IP, account, or resource.\n> 2. Ask the user to confirm written authorization and the permitted scope.\n> 3. Show the exact command(s) and explain their expected effect.\n> 4. Wait for explicit confirmation in the current conversation.\n>\n> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.\n\n## When to use this skill\n\nTrigger when:\n- Recon surfaces 1+ apps under the target's Apple Developer \u002F App Store publisher page\n- A TestFlight public link or enterprise\u002Fad-hoc `.ipa`\u002F`manifest.plist` (OTA install) is found\n- Customer-facing app, dealer\u002Fpartner portal, or employee mobile companion app ships on iOS\n- Bug bounty program lists iOS in scope\n- `apk-redteam-pipeline` already found Android endpoints\u002Fsecrets — the iOS build often ships a *different* backend version worth diffing (see `hunt-shadow-api`)\n\nDO NOT use for:\n- Android-only targets — that's `apk-redteam-pipeline`\n- A task limited to web bundles with no authorized iOS scope; React Native\u002FFlutter native bridges, entitlements and platform storage still need iOS-specific review when in scope\n- Server-side only assessments with no mobile client in scope\n\n---\n\nUse a dedicated authorized test device\u002Faccount and private evidence directory. Establish whether app binary, backend, credential validation, TLS instrumentation and test-CA\u002Fprofile changes are each in scope; record\u002Fremove test profiles and artifacts afterward. Never use discovered keys merely because they exist: public Firebase config is not automatically a secret, and network access needs separate target confirmation. Create a virtual environment before Python installs, pin\u002Freview tools\u002Fscripts and check installed --help; legacy flags such as --no-pause and objection subcommands may differ. No universal TLS hook guarantees coverage across all stacks.\n\n## Stage 0 — Inventory all org-owned iOS apps\n\n```bash\n# App Store search API (no auth, no scraping needed)\ncurl -s \"https:\u002F\u002Fitunes.apple.com\u002Fsearch?term=\u003Cbrand>&country=us&entity=software&limit=50\" | python3 -m json.tool\n\n# Pull the full metadata for a known bundle ID (once you have one)\ncurl -s \"https:\u002F\u002Fitunes.apple.com\u002Flookup?bundleId=com.\u003Cbrand>.app&country=us\"\n```\n\nExtract: `trackId`, `bundleId`, `sellerName` (developer account — pivot to find sibling apps), `version`,\n`releaseNotes` (changelogs often reference deprecated\u002Fremoved API behavior — feeds `hunt-shadow-api`).\n\nCross-reference sibling-app bundle IDs surfaced from Android APK inventories (same\nmulti-brand conglomerate usually reuses `com.\u003Ccorp>.\u003Csub-brand>` naming on both platforms).\n\n---\n\n## Stage 1 — IPA acquisition\n\n### Primary: from a real device you control (no jailbreak needed for a purchased\u002Ffree app)\n```bash\n# Obtain an owner-provided test IPA\u002Fbuild when possible. Installing\u002Flisting apps does not\n# itself export a decryptable IPA; Configurator\u002FXcode extraction depends on supported workflow.\n# Or via libimobiledevice:\nbrew install libimobiledevice ideviceinstaller\nideviceinstaller -l              # list installed apps + bundle IDs\n```\n\n### Secondary: TestFlight (if the program distributes betas publicly)\nOpen the public TestFlight link, install via the TestFlight app, then extract as above.\nTestFlight builds are frequently LESS hardened than App Store releases (debug logging left on,\nstaging API hosts hardcoded) — compare channel\u002Fbuild\u002Fversion; a beta finding does not establish production exposure.\n\n### Tertiary: enterprise \u002F ad-hoc distribution (OTA install)\n```bash\n# itms-services:\u002F\u002F links embed a manifest.plist with a direct .ipa URL\ncurl -s \"https:\u002F\u002F\u003Ctarget>\u002Fmanifest.plist\" | plutil -convert xml1 -o - -\n# Look for \u003Ckey>software-package\u003C\u002Fkey> — that URL is a directly downloadable, unencrypted IPA\ncurl --fail --show-error --proto =https --proto-redir =https --max-time 120 \"\u003Capproved-software-package-url>\" -o target.ipa\n```\nEnterprise\u002Fad-hoc IPAs are **not FairPlay-encrypted** — no jailbreak or decryption tooling needed,\nunlike an App Store binary pulled from a device.\n\n### Decrypting an App-Store-sourced binary (only if extracted from a jailbroken device)\nApp Store binaries are FairPlay-encrypted at rest; a binary copied off a jailbroken device\nneeds runtime decryption (`frida-ios-dump`, `bagbak`, or `flexdecrypt`) before static tools can\nread it meaningfully:\n```bash\npython -m pip install frida-tools\n# with frida-server running on the jailbroken device and the app in foreground:\npython3 dump.py \u003Cbundle_id>          # frida-ios-dump — outputs a decrypted .ipa\n```\n\n---\n\n## Stage 2 — Unpack and static analysis\n\n```bash\n# An IPA is just a zip\nunzip -l target.ipa  # inspect archive paths\u002Fsize first; reject traversal\u002Fsymlinks\u002Foversized entries\n# Extract only in a fresh private directory with an archive tool that enforces containment.\nunzip target.ipa -d extracted_target\u002F\ncd extracted_target\u002FPayload\u002F*.app\n\n# Info.plist — bundle ID, URL schemes, ATS config, entitlements hint\nplutil -convert xml1 -o - Info.plist\n\n# Entitlements — codesign reads the .app bundle (or the Mach-O binary), NOT Info.plist\ncodesign -d --entitlements :- . 2>\u002Fdev\u002Fnull || \\\n  security cms -D -i embedded.mobileprovision | plutil -convert xml1 -o - -\n\n# class-dump for Objective-C symbol\u002Fclass recovery (compiled binary, not the .app bundle)\nbrew install class-dump\nclass-dump -H \u003CAppBinaryName> -o headers\u002F\n\n# Swift binaries: class-dump won't show much — use Hopper, Ghidra, or `nm`\u002F`strings` instead\nnm -a \u003CAppBinaryName> | grep -i swift | head -50\nstrings -a \u003CAppBinaryName> > strings_target.txt\n```\n\nFor a fast triage pass without a disassembler, the strings dump alone usually surfaces most of\nwhat Stage 3 is looking for.\n\n---\n\n## Stage 3 — Secret grep (same catalog as apk-redteam-pipeline, iOS-specific sources added)\n\n```bash\n# URL grep — owned-domain references\ngrep -oE 'https?:\u002F\u002F[a-zA-Z0-9.-]+\\.(target1|target2|target3)\\.(com|io|net)[a-zA-Z0-9.\u002F_?=&%-]*' strings_target.txt | sort -u\n\n# Cloud credentials (same 60-pattern catalog as Android — reuse verbatim)\ngrep -oE 'AKIA[A-Z0-9]{16}' strings_target.txt          # candidate ID, not proof of valid credential\ngrep -oE 'AIza[A-Za-z0-9_-]{35}' strings_target.txt     # may be public\u002Frestricted app configuration\ngrep -oE 'eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]*' strings_target.txt   # JWT\n\n# iOS-specific: GoogleService-Info.plist (Firebase config bundled per-platform)\nfind . -iname \"GoogleService-Info.plist\" -exec plutil -convert xml1 -o - {} \\;\n# Look for API_KEY, PROJECT_ID, STORAGE_BUCKET, GCM_SENDER_ID, GOOGLE_APP_ID — same Firebase\n# public-read tests as apk-redteam-pipeline Stage 6.\n\n# iOS-specific: hardcoded config plists shipped in the bundle\nfind . -iname '*.plist' ! -iname 'Info.plist' -exec sh -c 'for p do printf \"=== %s ===\\n\" \"$p\"; plutil -convert xml1 -o - \"$p\"; done' sh {} +\n\n# App Transport Security exceptions (Info.plist) — tells you if arbitrary\u002Finsecure loads are allowed\nplutil -extract NSAppTransportSecurity xml1 -o - Info.plist 2>\u002Fdev\u002Fnull\n```\n\n### Keychain items left in a backup (if you have a device backup, encrypted or not)\n```bash\npython -m pip install iphone_backup_decrypt   # for encrypted local backups\n# keychain-dumper (run ON a jailbroken device) for live keychain contents:\n.\u002Fkeychain-dumper -e   # -e also decodes entitlements per item, showing which app owns which secret\n```\n\n---\n\n## Stage 4 — App Transport Security (ATS) misconfig + certificate-pinning bypass\n\n### Check for blanket ATS disablement (the single most common iOS network misconfig)\n```bash\nplutil -extract NSAppTransportSecurity xml1 -o - Info.plist\n```\nRed flags in the output:\n- `NSAllowsArbitraryLoads = true` at the top level — HTTP (cleartext) allowed anywhere, app-wide.\n- Per-domain `NSExceptionAllowsInsecureHTTPLoads = true` for a domain that carries auth tokens.\n- `NSAllowsArbitraryLoadsInWebContent = true` — WKWebView traffic exempted, common blind spot.\n\nA blanket ATS exception + a network position (rogue AP, ARP spoof, malicious VPN profile) =\nplaintext credential\u002Ftoken interception without touching pinning at all.\n\n### Certificate-pinning bypass (when pinning IS present and correctly configured)\n```bash\npython -m pip install frida-tools objection\nobjection --gadget \u003Cbundle_id> explore\n# inside objection:\nios sslpinning disable\n```\nIf you want a Frida script instead, don't hand-roll one — use a maintained universal bypass\n(e.g. the widely-used `frida-ios-pinning`\u002F`ios-ssl-bypass` community scripts). Modern iOS TLS goes\nthrough **BoringSSL**, so a reliable universal hook targets `SSL_CTX_set_custom_verify` \u002F\n`SSL_get_psk_identity` at the native layer and forces the verify callback to return \"OK\" — this\ncatches `URLSession`, `AFNetworking`, `Alamofire`, and `TrustKit` at once, which per-delegate\nObjective-C hooks (like the deprecated `NSURLConnection` delegate) miss:\n```bash\n# Pull a maintained universal BoringSSL-layer bypass and run it:\nfrida -U -f \u003Cbundle_id> -l ios-ssl-bypass.js --no-pause\n```\nIn practice, prefer **SSL Kill Switch 2** (jailbroken device, installs as a tweak) or\n**objection's `ios sslpinning disable`** over any hand-rolled script — both cover the common\npinning implementations (`NSURLSession`, `AFNetworking`, `TrustKit`) without per-app tuning.\n\n---\n\n## Stage 5 — URL scheme \u002F Universal Link enumeration\n\n```bash\n# Custom URL schemes (CFBundleURLTypes) — anything can invoke these via Safari\u002Fanother app\nplutil -extract CFBundleURLTypes xml1 -o - Info.plist\n\n# Universal Links \u002F Associated Domains (applinks:) — requires a matching apple-app-site-association\ncodesign -d --entitlements :- .  # associated-domains belongs to signed entitlements, not Info.plist\ncurl -s \"https:\u002F\u002F\u003Cdomain>\u002F.well-known\u002Fapple-app-site-association\" | python3 -m json.tool\n```\n\nFor each custom scheme found (e.g. `myapp:\u002F\u002F`):\n- Trigger it from Safari\u002FNotes and observe what the app does with parameters:\n  `myapp:\u002F\u002Freset-password?token=x&redirect=https:\u002F\u002Fevil.com` — does the app trust an\n  attacker-supplied `redirect`\u002F`url`\u002F`callback` param and load it in a WebView (open-redirect →\n  WebView-XSS chain) or use it to bypass an auth screen?\n- If the scheme is also registered by another app on the device (scheme squatting), a malicious\n  app can intercept traffic intended for the legitimate app — check `CFBundleURLName` uniqueness.\n- Failed Universal Link association normally leaves an HTTPS web link; any custom-scheme fallback is application-specific and must be observed, not assumed.\n\n---\n\n## Stage 6 — Runtime instrumentation (Frida \u002F objection)\n\nUse an authorized compatible test environment. Frida supports jailbroken devices and debuggable apps without jailbreak (Gadget\u002Fdeveloper setup); support depends on the build\u002Fdevice.\n\n```bash\n# Setup\npython -m pip install frida-tools objection\n# Install frida-server on the jailbroken device via Cydia\u002FSileo (frida repo), matching the\n# host frida-tools version exactly — version skew is the #1 cause of \"failed to attach\" errors.\n\n# Full interactive exploration\nobjection --gadget \u003Cbundle_id> explore\n# Inside objection:\nios hooking watch class \u003CClassName>\nios hooking watch class_method \u003CClass>.\u003Cmethod> --dump-args --dump-return\nios keychain dump\nios plist dump\nios cookies get\n```\n\n### Network traffic capture (once pinning is bypassed)\n```bash\nmitmproxy --listen-port 8080\n# Set the device Wi-Fi proxy to host:8080, install the mitmproxy CA via http:\u002F\u002Fmitm.it on-device\n# (Settings > General > VPN & Device Management > trust the cert, then enable full trust under\n# Certificate Trust Settings — iOS requires this second step, unlike Android)\n```\n\n---\n\n## Decision tree — what to do with what you find\n\n| Finding | Next move |\n|---|---|\n| `NSAllowsArbitraryLoads = true` | Confirm a token\u002Fcredential actually transits HTTP — needs a network position to exploit, but is a real finding on its own (config-level, no MITM needed to report) |\n| Hardcoded JWT \u002F API key in strings dump | Same as Android — test against the API host, chain into `hunt-api-misconfig` |\n| GoogleService-Info.plist present | Test public Firestore\u002FRTDB\u002FStorage read (identical to apk-redteam-pipeline Stage 6) |\n| Custom URL scheme accepts a `redirect`\u002F`url` param | Test open-redirect → WebView-load chain; check for scheme squatting by other installed apps |\n| Universal Link AASA missing\u002Fmisconfigured | Confirm scheme fallback still carries the same injectable params |\n| Entitlements show `keychain-access-groups` shared with other apps | Cross-app Keychain read — a compromised sibling app reads this app's secrets |\n| Older API version referenced vs. what the current web app calls | Hand off to `hunt-shadow-api` for version-diffing |\n\n---\n\n## Anti-patterns\n\n- **Don't assume App Store = FairPlay-encrypted requires jailbreak** — TestFlight and enterprise\u002Fad-hoc\n  builds are frequently NOT encrypted and need no decryption step at all. Always check distribution\n  channel before reaching for `frida-ios-dump`.\n- **Don't skip Swift binaries because class-dump shows nothing** — `strings` and `nm` still work; a\n  proper Swift-aware disassembler (Hopper, Ghidra with Swift demangling) recovers the rest.\n- **Don't stop at \"pinning is present\" as a finding** — pinning is a mitigation, not a vulnerability;\n  the finding is what you can do once it's bypassed (or the ATS misconfig that makes it moot).\n- **Don't ignore WKWebView-loaded content** — `NSAllowsArbitraryLoadsInWebContent` is a distinct,\n  frequently-overlooked exception from the top-level ATS setting.\n- **Don't run Frida instrumentation against a personal\u002Fproduction Apple ID device** — use a\n  dedicated jailbroken test device or Corellium instance.\n\n---\n\n## Tooling install (one-time)\n\n```bash\nbrew install libimobiledevice ideviceinstaller class-dump\npython -m pip install frida-tools objection iphone_backup_decrypt\n# Jailbroken test device (checkra1n\u002Fpalera1n) or a Corellium virtual iOS device for runtime work\n# frida-server installed on-device via the Frida Cydia\u002FSileo repo\n```\n\n---\n\n## Related Skills & Chains\n\n- **`apk-redteam-pipeline`** — the Android counterpart; run both when a target ships on both\n  platforms. Sibling bundle IDs and shared backend endpoints frequently surface cross-platform.\n- **`hunt-shadow-api`** — mobile builds (iOS and Android alike) often hardcode an older API\n  version than the current web app. Chain: IPA reveals `\u002Fv1\u002F*` endpoints → `hunt-shadow-api`\n  diffs `\u002Fv1\u002F` against the current `\u002Fv3\u002F` for auth\u002Fvalidation regressions.\n- **`cloud-iam-deep`** — IPA secret extraction frequently yields live AWS\u002FGCP\u002FAzure credentials\n  or Firebase configs. Chain: strings-grep produces an AWS key → `cloud-iam-deep` privilege\n  analysis.\n- **`hunt-api-misconfig`** — hardcoded JWTs\u002FAPI keys extracted here feed directly into JWT\n  algorithm-confusion and mass-assignment testing there.\n- **`evidence-hygiene`** — extracted Keychain items and secrets need redaction before report\n  inclusion.\n- **`offensive-osint`** — App Store developer-page enumeration is part of the broader org recon\n  graph; pair with certificate-transparency lookups for the same brand.\n\n## Limitations\n\n- Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command.\n- Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed.\n- Validate every finding (see `triage-validation`) before reporting; report via `report-writing`. Prefer a sandbox, disposable VM, or controlled lab.\n\n### Example\n\n```bash\n# Read-only first step; confirm scope before anything active.\ncat scope.txt  # target list from the authorized engagement brief\n```\n\n> Adapted from [elementalsouls\u002FClaude-BugHunter](https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.\n",{"name":5,"risk":27,"source":50,"license":14,"sources":51,"category":43,"date_added":52,"description":7,"source_repo":53,"source_type":35,"report_count":54,"compatibility":55,"license_source":56},"https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter","public_research, frida_docs, objection_docs, owasp_mastg","2026-09-20","elementalsouls\u002FClaude-BugHunter",0,"Requires explicit written authorization for a target scope plus the relevant testing tools for this technique. Docs-only; helper scripts and commands not bundled.","https:\u002F\u002Fgithub.com\u002Felementalsouls\u002FClaude-BugHunter\u002Fblob\u002Fmain\u002FLICENSE","7bf2279c8a65758319526a721d5c4b75683aec9c","skills\u002Fantigravity-ios-redteam-pipeline",3,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections","https:\u002F\u002Fgithub.com\u002Fboisenoise","2026-11-11 14:20:43",{"source":8,"skillName":5,"commands":64,"prompt":74,"zipAvailable":75},[65,68,71],{"tool":66,"command":67},"npx","npx skills add boisenoise\u002Fskills-collections --skill ios-redteam-pipeline",{"tool":69,"command":70},"bunx","bunx skills add boisenoise\u002Fskills-collections --skill ios-redteam-pipeline",{"tool":72,"command":73},"pnpm","pnpm dlx skills add boisenoise\u002Fskills-collections --skill ios-redteam-pipeline","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-ios-redteam-pipeline\u002FSKILL.md",true,[],[78,105,130,155,174,196],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":83,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":45},"01M6WNH92BHVFXHGPDZCPJ0AG0","web-access","Use Treg for public web or platform data only when existing search, browser and connected tools cannot cover the task, with explicit cost and data boundaries.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FSKILL.md",[],[87,88,89,90,91,92,93,94,38,95,96,36,97,98,99,100,101,102,103,104,23],"web","access","web access","official","development","browser","search","data","read","fetch","youtube","free tools","platform","critical","free","cover","normal","when",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":109,"sourceHtmlUrl":110,"categories":111,"keywords":117,"publishedAt":45},"01M6WNF9XAYAB2CZDDJBAKNM93","treg","Use the Treg CLI or MCP catalog to discover, price and call authorized external tools with team-scoped credentials and a user-approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FSKILL.md",[112],{"categoryNo":113,"categoryName":114,"taxonomyType":115,"taxonomyTypeDesc":116},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[107,118,119,44,90,91,41,38,120,121,37,122,123,124,125,100,126,127,128,129,23],"MCP","cli","Budget","credentials","catalog","use","call","discover","external tools","with","scoped","blob",{"skillNo":131,"name":132,"nameZh":6,"description":133,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":134,"sourceHtmlUrl":135,"categories":136,"keywords":142,"publishedAt":45},"01M6WN93MEAZ4E41DYAHJRPHQT","recruit","Turn a job description into an evidence-linked candidate shortlist through Treg, with job-related ranking and optional authorized business contact enrichment.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FSKILL.md",[137],{"categoryNo":138,"categoryName":139,"taxonomyType":140,"taxonomyTypeDesc":141},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[132,44,90,41,143,144,145,146,147,148,100,149,150,151,127,24,152,153,154,129,107,23],"https","email","enrichment","business","evidence","phone","ranking","post","job description","person","candidate","reason",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":159,"sourceHtmlUrl":160,"categories":161,"keywords":162,"publishedAt":45},"01M6WN8R5RXSMHM9B4D9FAFX42","rea-growth","Analyze a company’s public growth and content through Treg, distinguish observations from hypotheses, and produce an evidence-linked playbook within an approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FSKILL.md",[],[163,164,165,44,90,41,166,167,143,168,120,169,170,171,147,100,172,173,129,107,23],"growth","rea","rea growth","produce","content","playbook","marketing","analyze","public","observations","company",{"skillNo":175,"name":176,"nameZh":6,"description":177,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":178,"sourceHtmlUrl":179,"categories":180,"keywords":181,"publishedAt":45},"01M6WN2EVE3RQRGWAKBT4S7YT2","make-ugc","Create original AI UGC-style product videos through Treg: research hooks, approve a licensed presenter and voice, generate clips, add captions and report costs.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FSKILL.md",[],[182,183,44,42,90,184,41,185,186,187,188,189,100,190,191,192,193,194,195,129],"make","make ugc","create","Video","Captions","ads","short","hooks","head","style","niche","trending","talking-head","approve",{"skillNo":197,"name":198,"nameZh":6,"description":199,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":82,"licenseFileUrl":200,"sourceHtmlUrl":201,"categories":202,"keywords":203,"publishedAt":45},"01M6WN10ARAA63Y8K1YNGXJ2RM","lead-signals","Find and qualify public buying signals through Treg, rank fitting business accounts and optionally enrich authorized business contact information.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FSKILL.md",[],[204,205,206,44,90,41,207,208,146,209,210,100,211,212,213,214,215,216,217,129],"signals","lead","lead signals","how","find","ready","as","how to","qualify","people","information","enrich","changes","funding"]