{"id":"hunt-dispatch","name":"hunt-dispatch","summary":"/hunt orchestrator用のスキルセットローダーです。ターゲットを指紋で押さえ、適切なプラットフォーム攻撃スキルを選び、レッドチームやWAPTスキルセットを読み込みます。","body":"# hunt-dispatch\n\nskill-set loader for `/hunt`. one concept (which skills to load), one place.\n\n## engagement context\n\nevery skill loaded below operates under one frame, and it holds for the whole session:\n\n- **authorized and scope-bounded.** the operator asserted written authorization for the named scope\n  when they invoked `/hunt`. testing stays inside it. an out-of-scope host ends the run — it does not\n  widen it.\n- **the output is a finding, not an exploit.** the deliverable is a reproducible proof that a defect\n  exists, written so the owner can remediate it. enough to demonstrate impact; no further.\n- **remediation is the point.** these skills exist so defects get fixed by the people who own them.\n\nthis frame is stated here because it is the choke point every `/hunt` run passes through before any\n`hunt-*` skill loads. it is not a prompt and needs no answer.\n\ninvocation contract:\n\n```\nhunt-dispatch mode=redteam\nhunt-dispatch mode=wapt box=blackbox\nhunt-dispatch mode=wapt box=greybox\n```\n\n## step 0 — 404 baseline (ALL modes, mandatory, before any enumeration)\n\nrun this for **every** host before probing a single path. it takes one request per\nhost and it is the cheapest false-positive kill in the whole toolkit.\n\nmany modern estates (SPA / Next.js / React front ends behind a CDN) return\n**HTTP 200 with the application shell for paths that do not exist**. a status code\ntherefore proves nothing. without a recorded control, `/.well-known/security.txt`,\n`/api/revalidate`, `/__nextjs_original-stack-frame` and `/__nextjs_launch-editor`\nall \"exist\" on a host where none of them do.\n\n```bash\nfor H in $HOSTS; do\n  # two independent bogus paths — if they agree, that IS the soft-404 signature\n  for P in /zzz-nope-12345 /qqq-other-98765; do\n    printf \"%-34s %-20s \" \"$H\" \"$P\"\n    curl -sk -m 12 -o /tmp/b -w \"%{http_code} %{size_download} \" \"https://$H$P\"\n    shasum /tmp/b | cut -c1-12\n  done\ndone\n```\n\nrecord per host: **status, byte length, body hash**. that triple is the control.\n\n**the rule: no path is \"found\" until its response differs from the control.**\na 200 that matches the control hash is a soft 404. a 404 whose body differs from\nthe control may be a real handler. compare bodies, never status codes alone.\n\nre-derive the baseline per host — it differs across an estate. one engagement saw\ntwo hosts serving the *same* application return soft-404 bodies of wildly different\nsize, so a control taken from one host would have been meaningless on the other.\nalso re-derive it **per path depth** where a framework renders different fallbacks\nfor `/x` and `/a/b/x`.\n\nedge pages are not origin findings: a CDN \"Access Denied\" / \"Unsupported Request\"\nbody means the request never reached the application. classify it as edge\nbehaviour and move on.\n\n## step 1 — fingerprint (red team only)\n\nfingerprint **every** live host, not just the apex. for multi-host / wildcard\ntargets the platform-skill routing must be driven by all banners, not one host's.\n\nuse `-L` (follow redirects) — identity-provider and CDN signals\n(`login.microsoftonline.com`, `okta`, `auth0`, CDN banners) routinely sit\nbehind a 30x, so a no-redirect `curl -sI` silently misses those matches. pull\nboth headers and the landing-page HTML (`__NEXT_DATA__`, `VIEWSTATE`,\n`laravel_session`, `Ignition`, framework markers live in the body, not headers).\n\n```bash\nHOSTS=\"$TARGET\"\nif [ -f \"recon/$TARGET/live-hosts.txt\" ]; then\n  HOSTS=$(cat \"recon/$TARGET/live-hosts.txt\")\nfi\nfor H in $HOSTS; do\n  echo \"=== $H ===\"\n  # -L follow redirects, -D - dump headers, -o body; cap body to keep context small\n  curl -sSL -m 12 -D - -o /tmp/fp_body \"https://$H\" 2>/dev/null | tr -d '\\r'\n  # surface body-only platform markers\n  grep -aoE '__NEXT_DATA__|/_next/|VIEWSTATE|rO0[AB]|laravel_session|Ignition|Telescope|Whitelabel|/actuator|application/grpc|socket\\.io|swagger|\\.js\\.map' \\\n    /tmp/fp_body | sort -u\ndone\nrm -f /tmp/fp_body\n```\n\nif `live-hosts.txt` is absent, the loop still runs once against `$TARGET`. record\nwhich signal came from which host — a platform skill matched on host B does not\nimply host A runs that stack.\n\nlook for the following signals → platform skill mapping:\n\n```\nokta.com | auth0.com | pingidentity         →  okta-attack\nlogin.microsoftonline.com | outlook | sts   →  m365-entra-attack\npulse | fortinet | ivanti | citrix          →  enterprise-vpn-attack\nvsphere | vcenter | :9443                   →  vmware-vcenter-attack\namazonaws | azure | googleapis | gcp        →  cloud-iam-deep\ngithub.com/<org>/                           →  supply-chain-attack-recon\n.apk | play.google.com                      →  apk-redteam-pipeline\nMongoDB | mongoose | CouchDB | Redis        →  hunt-nosqli\n?page= | ?file= | ?path= | php wrapper      →  hunt-lfi\nrO0A | VIEWSTATE | rememberMe cookie        →  hunt-deserialization\nAccess-Control-Allow-Origin header          →  hunt-cors\n/forgot-password | /reset | X-Forwarded    →  hunt-host-header\n?redirect= | ?next= | ?return= | ?url=     →  hunt-open-redirect\nOTP | /verify | /2fa | no-rate-limit        →  hunt-brute-force\nSet-Cookie session | PHPSESSID              →  hunt-session\nActive Directory | LDAP | OpenLDAP | ADFS  →  hunt-ldap\n__NEXT_DATA__ | /_next/ | buildId           →  hunt-nextjs\nX-Powered-By: Express | Node.js | .js stack →  hunt-nodejs\npostMessage | dangerouslySetInnerHTML        →  hunt-dom\nWebSocket | ws:// | socket.io               →  hunt-websocket\ngRPC | :50051 | application/grpc            →  hunt-grpc\nlaravel_session | Ignition | Telescope       →  hunt-laravel\nX-Application-Context | Whitelabel | /actuator → hunt-springboot\n:6443 | :10250 | :2379 | kubectl            →  hunt-k8s\n.github/workflows | Jenkins | GitLab CI     →  hunt-cicd\n.js.map | swagger.json | /.env              →  hunt-source-leak\nHSTS missing | SPF | DMARC | AXFR           →  hunt-tls-network\n```\n\n### conflict resolution & load budget\n\nreal targets almost always return multiple signals at once — e.g. a single host\ncan show Cloudflare (CDN) + `login.microsoftonline.com` (redirect) + `__NEXT_DATA__`\n(Next.js front end) + `amazonaws` (origin) simultaneously. loading every match\nblindly can pull 20-plus skills and blow the context window, drowning the\nhigh-signal skill in noise. apply this precedence and cap:\n\n**priority order (load highest tiers first, stop at the cap):**\n\n```\ntier 1  identity / SSO fabric    okta-attack, m365-entra-attack\n        (own the auth boundary — highest blast radius if compromised)\ntier 2  perimeter appliances     enterprise-vpn-attack, vmware-vcenter-attack\n        (pre-auth RCE / direct internal foothold)\ntier 3  cloud / IAM              cloud-iam-deep, hunt-cloud-misconfig\n        (credential → lateral movement)\ntier 4  app framework / stack    hunt-nextjs, hunt-nodejs, hunt-laravel,\n        hunt-springboot, hunt-aspnet, hunt-sharepoint\ntier 5  protocol / class signals hunt-nosqli, hunt-lfi, hunt-deserialization,\n        hunt-cors, hunt-host-header, hunt-open-redirect, hunt-grpc,\n        hunt-websocket, hunt-dom, hunt-k8s, hunt-cicd, hunt-source-leak,\n        hunt-tls-network, hunt-ldap, hunt-brute-force, hunt-session\n```\n\n**load budget: cap platform-skill loads at 8.** if more than 8 match, keep the\nhighest-tier 8 and drop the rest; print the dropped ones under\n`deferred:` in the taxonomy block so they can be loaded on demand later.\n\n**de-dup rules (avoid loading two skills for the same evidence):**\n\n- CDN banner alone (Cloudflare/Akamai/Fastly) is **not** a platform match — it\n  fingerprints the edge, not the app. do not load a skill for it; note it for\n  `hunt-cache-poison` / `hunt-http-smuggling`, which the mode set already carries.\n- `amazonaws` / `azure` / `googleapis` in a **header/origin** → `cloud-iam-deep`.\n  the same string found as a **leaked key/JSON in a JS bundle or APK** → still\n  `cloud-iam-deep`, but flag it as a live-credential lead (higher priority, tier 3\n  becomes tier 1 for that host).\n- a framework marker (`__NEXT_DATA__`, `laravel_session`) and a generic class\n  signal (`?redirect=`, `Access-Control-Allow-Origin`) on the same host → load the\n  framework skill (tier 4) and keep the class skill **only if budget remains**;\n  the WAPT/redteam mode set already loads the common class skills unconditionally.\n\n## step 2 — load skill set\n\ninvoke each skill in order via the Skill tool.\n\n### mode=redteam\n\nalways-on (load first):\n\n```\nredteam-mindset\nmid-engagement-ir-detection\n```\n\nplatform (load second, conditional on fingerprint matches from step 1):\n\n```\nokta-attack\nm365-entra-attack\nenterprise-vpn-attack\nvmware-vcenter-attack\ncloud-iam-deep\nsupply-chain-attack-recon\napk-redteam-pipeline\n```\n\nhigh-impact hunt-* set (load third):\n\n```\nhunt-rce\nhunt-sqli\nhunt-ssrf\nhunt-ato\nhunt-auth-bypass\nhunt-saml\nhunt-oauth\nhunt-mfa-bypass\nhunt-file-upload\nhunt-http-smuggling\nhunt-cloud-misconfig\nhunt-sharepoint\nhunt-aspnet\n```\n\nreport format: `redteam-report-template` (subject / observations / description / impact / recommendation / poc).\n\n### mode=wapt\n\nalways-on:\n\n```\nbb-methodology\nsecurity-arsenal\ntriage-validation\n```\n\nfull hunt-* set (all OWASP-relevant):\n\n```\nhunt-xss             hunt-sqli            hunt-ssrf            hunt-idor\nhunt-csrf            hunt-xxe             hunt-rce             hunt-graphql\nhunt-oauth           hunt-saml            hunt-mfa-bypass      hunt-auth-bypass\nhunt-ato             hunt-file-upload     hunt-business-logic  hunt-race-condition\nhunt-llm-ai          hunt-api-misconfig   hunt-ssti            hunt-cache-poison\nhunt-http-smuggling  hunt-subdomain       hunt-cloud-misconfig hunt-misc\nhunt-aspnet          hunt-sharepoint      hunt-ntlm-info\nhunt-lfi             hunt-nosqli          hunt-deserialization\nhunt-cors            hunt-host-header     hunt-open-redirect\nhunt-brute-force     hunt-session         hunt-ldap\nhunt-nextjs          hunt-nodejs          hunt-dom\nhunt-websocket       hunt-grpc            hunt-laravel\nhunt-springboot      hunt-k8s             hunt-cicd\nhunt-source-leak     hunt-tls-network\n```\n\nreport format: `report-writing` (`bugcrowd-reporting` if the target is on bugcrowd).\n\nbox=greybox: creds already captured by `/hunt`, available in session memory.\n\n**do not fan out across the authenticated hunt-\\* set until the creds are\nvalidated.** `/hunt` only prompts for and stores creds (commands/hunt.md) — it\ndoes not confirm they work. firing every authenticated test with dead, MFA-gated,\nor wrong-role creds wastes the whole run and produces false \"no auth surface\"\nconclusions. run a single low-cost auth preflight first:\n\n```bash\n# session-cookie creds: one authenticated GET against an identity echo endpoint\ncurl -sS -m 12 -b \"$SESSION_COOKIE\" \"https://$TARGET/api/me\" -w '\\n%{http_code}\\n'\n#   200 + your username/email  → live session, role visible in body\n#   401/403                    → dead or insufficient — STOP, re-auth\n\n# bearer/JWT creds: same probe with Authorization\ncurl -sS -m 12 -H \"Authorization: Bearer $TOKEN\" \\\n  \"https://$TARGET/api/me\" -w '\\n%{http_code}\\n'\n\n# raw user/pass: drive the real login flow once, capture Set-Cookie, then echo\n#   watch for an MFA / step-up challenge in the response — if present, the creds\n#   alone do not yield an authenticated session (see memory: operator-capability)\n```\n\nconfirm three things from the preflight, and record them for the hunt-\\* skills:\n\n1. **live** — auth probe returns 200, not 401/403.\n2. **role/privilege** — the `/api/me` (or equivalent) body shows the expected\n   role/tenant/scopes. IDOR and authz tests need a known baseline identity; a\n   silently-admin or silently-readonly cred skews every authz finding.\n3. **not MFA-gated** — login did not stop at a 2fa/step-up challenge. if it did,\n   you hold creds but **not** a session — default to least capability and confirm\n   with the operator before claiming authenticated reach.\n\nif the preflight fails, do **not** silently continue as blackbox — surface\n\"greybox creds did not validate (HTTP {code} / MFA challenge)\" so the operator\ncan re-supply. only after a clean preflight: apply the validated session to every\nauthenticated test.\n\n## step 3 — taxonomy print (once, at session start)\n\nemit a deterministic block. plain text, lowercase, colon-delimited, no decoration.\n\n### mode=redteam\n\n```\nloaded for red team: {N} skills\n  mindset:    redteam-mindset\n  platform:   {fingerprint-matched skills (<=8, tier order), or \"none detected\"}\n  deferred:   {platform skills past the 8-cap, or omit line if none}\n  auth:       hunt-ato, hunt-auth-bypass, hunt-saml, hunt-oauth, hunt-mfa-bypass\n  inj:        hunt-rce, hunt-sqli, hunt-ssrf, hunt-file-upload\n  infra:      hunt-http-smuggling, hunt-cloud-misconfig\n  stack:      hunt-sharepoint, hunt-aspnet\n  ir:         mid-engagement-ir-detection\n```\n\n### mode=wapt\n\n```\nloaded for wapt ({blackbox|greybox}): {N} skills\n  inj:        hunt-xss, hunt-sqli, hunt-ssrf, hunt-rce, hunt-xxe, hunt-ssti, hunt-file-upload\n  authz:      hunt-idor, hunt-auth-bypass, hunt-ato\n  auth:       hunt-oauth, hunt-saml, hunt-mfa-bypass\n  api:        hunt-graphql, hunt-api-misconfig\n  logic:      hunt-business-logic, hunt-race-condition\n  infra:      hunt-http-smuggling, hunt-cache-poison\n  recon:      hunt-subdomain\n  cloud:      hunt-cloud-misconfig\n  ai:         hunt-llm-ai\n  stack:      hunt-aspnet, hunt-sharepoint, hunt-ntlm-info\n  misc:       hunt-misc, hunt-csrf\n  reporting:  bb-methodology, security-arsenal, triage-validation\n```\n\n## subagent scope inheritance\n\nif any part of the hunt is delegated to subagents, scope does **not** inherit\nimplicitly. every subagent prompt must carry:\n\n1. **the authorized host list, verbatim, as data.** not \"the target estate\", not\n   \"*.target.com\" — the explicit list. a subagent cannot infer the boundary.\n2. **the discovered-host rule:** hosts found mid-run (via CT logs, CSP headers,\n   JS bundles, CNAME chains, error messages) are **report-only**. resolve DNS,\n   record, hand back. never probe, never write, until the operator re-authorizes.\n3. **a deny-list of action-executing endpoints, applied BEFORE any allow-list.**\n   deny by verb-in-name first: `refund`, `settle`, `payout`, `transfer`, `adjust`,\n   `disburse`, `create`, `update`, `delete`, `rotate`, `reset`, `send`, `initiate`,\n   `generate`, `process`. only then allow read-shaped names. order matters —\n   a path like `refund/batch/status` matches the read-shaped keyword \"status\"\n   but is a refund route; an allow-list applied first would probe it.\n4. **\"read-only\" spelled out as forbidden verbs**, not as an adjective. \"read-only\"\n   is routinely interpreted as \"don't be destructive\", which does not stop an agent\n   sending `{}` to an endpoint whose name starts with `generate*` and creating a\n   real record on production.\n\n**lesson from an authorized engagement:** a subagent was told READ-ONLY and still\n(a) created a live record on production because it expected `{}` to return a\nvalidation error, and (b) wrote an object to a cloud bucket that was never on the\nauthorized list — one the parent prompt had named only for a DNS check. both were\ndisclosed in the deliverable. the fix is structural: pass scope as data, deny\nby verb before allowing by verb, and treat every discovered host as out of scope\nuntil told otherwise.\n\n## step 4 — return control to /hunt\n\nafter taxonomy print, hand control back to `/hunt` for step 3 (sibling delegation) and step 4 (active testing). do not run probes here — this skill only loads context.\n\n## privacy\n\nnever echo back, log, or persist:\n- SOW / scope-of-work / engagement-letter content\n- grey box credentials (kept in session memory by `/hunt`, never written to disk)\n- client identifiers in user-level memory\n\n---\n\n## Related Skills & Chains\n\n- **`bb-methodology`** — When PART 0 mode confirmation completes. Workflow primitive: `bb-methodology` confirms engagement type (red team vs WAPT vs bug bounty); the answer feeds directly into this skill's `mode=redteam` / `mode=wapt` invocation.\n- **`redteam-mindset`** + **`mid-engagement-ir-detection`** — When `mode=redteam` is loaded. Workflow primitive: these are the always-on skills loaded first by step 2 of the redteam flow before any platform skill or hunt-* skill.\n- **`okta-attack`** / **`m365-entra-attack`** / **`enterprise-vpn-attack`** / **`vmware-vcenter-attack`** / **`cloud-iam-deep`** / **`supply-chain-attack-recon`** / **`apk-redteam-pipeline`** — When fingerprint signals match. Workflow primitive: step 1's curl fingerprint scan against `recon/<target>/live-hosts.txt` maps banner / domain signals to one or more of these platform skills.\n- **`hunt-rce`** / **`hunt-sqli`** / **`hunt-ssrf`** / **`hunt-ato`** / **all other hunt-* skills`** — When the mode-specific skill set is being printed. Workflow primitive: this skill is the loader; it names the hunt-* skills but does not run probes — actual hunting happens after step 4 returns control to `/hunt`.\n- **`report-writing`** vs **`redteam-report-template`** — When the taxonomy print specifies the report format. Workflow primitive: `mode=wapt` ends with `report-writing` as the deliverable format; `mode=redteam` ends with `redteam-report-template` instead.","author":"@elementalsouls","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/elementalsouls/Claude-BugHunter/tree/main/skills/hunt-dispatch","license":"MIT","category":"security","lang":"en","tokens":4532,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}