hunt-dispatch について
hunt-dispatch は、認可済みのセキュリティテストで /hunt 用のスキルセットを読み込むローダーです。モードとホストの指紋に応じてスキルを選び、スコープ、ソフト 404 の基準、認証情報の事前確認、分類出力を定めます。
主な機能
- 01テストモード別のスキル読み込み
- 02ホストごとのソフト 404 基準設定
- 03指紋に基づくプラットフォームスキル選択
- 04優先順位付けと読み込み数の上限
- 05グレーボックステスト前の認証情報と権限確認
- 06認可範囲とサブエージェント境界の設定
活用シーン
- 01レッドチームまたは WAPT のスキル読み込み
- 02複数ホストの指紋に基づく振り分け
- 03グレーボックステスト前のセッションと権限確認
- 04サブエージェントの対象と操作の制限
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ elementalsouls/ claude-bughunter --skill hunt-dispatchインストール後、Claude Code で/hunt-dispatchを入力して読み込まれたか確認します。
詳細
hunt-dispatch
/hunt 用のスキルセットローダーです。読み込むスキルという単一の概念を、単一の場所にまとめています。
エンゲージメントのコンテキスト
以下で読み込まれるすべてのスキルは、ひとつの枠組みのもとで動作し、セッション全体を通じてこの枠組みが適用されます。
- 認可済みで、スコープが限定されています。 オペレーターは
/huntを呼び出す際に、指定されたスコープについて書面による認可を得ていることを明示しています。テストはその範囲内で行います。スコープ外のホストが見つかった場合は実行を終了します。スコープを広げることはありません。 - 出力するのはエクスプロイトではなく、発見事項です。 成果物は、欠陥の存在を再現可能な形で証明し、所有者が修正できるように記述したものです。影響を実証するのに必要な範囲にとどめ、それ以上は行いません。
- 目的は修正です。 これらのスキルは、欠陥を所有者が修正できるようにするために存在します。
この枠組みをここに記載するのは、すべての /hunt 実行が hunt-* スキルの読み込み前に必ず通過する要所だからです。これはプロンプトではないため、回答は不要です。
呼び出しの契約:
hunt-dispatch mode=redteam
hunt-dispatch mode=wapt box=blackbox
hunt-dispatch mode=wapt box=greybox
ステップ 0 — 404 ベースライン(すべてのモードで必須。列挙の前に実施)
パスをひとつでもプローブする前に、すべてのホストでこれを実行してください。ホストごとにリクエストは 1 回だけで、ツールキット全体で最も低コストに誤検出を排除できます。
多くの最新の環境(CDN の背後にある SPA/Next.js/React フロントエンド)は、存在しないパスに対してアプリケーションシェルを HTTP 200 で返します。そのため、ステータスコードだけでは何も証明できません。記録済みのコントロールがなければ、/.well-known/security.txt、/api/revalidate、/__nextjs_original-stack-frame、/__nextjs_launch-editor は、いずれも実際には存在しないホスト上で「存在する」ことになります。
for H in $HOSTS; do
# two independent bogus paths — if they agree, that IS the soft-404 signature
for P in /zzz-nope-12345 /qqq-other-98765; do
printf "%-34s %-20s " "$H" "$P"
curl -sk -m 12 -o /tmp/b -w "%{http_code} %{size_download} " "https://$H$P"
shasum /tmp/b | cut -c1-12
done
done
ホストごとに、ステータス、バイト長、本文のハッシュを記録してください。この 3 つがコントロールになります。
ルール:応答がコントロールと異なるまで、パスが「見つかった」と判断してはいけません。 コントロールとハッシュが一致する 200 はソフト 404 です。本文がコントロールと異なる 404 は、実際のハンドラーである可能性があります。ステータスコードだけで判断せず、必ず本文を比較してください。
環境全体で異なるため、ホストごとにベースラインを取り直してください。あるエンゲージメントでは、同じアプリケーションを提供する 2 つのホストが、サイズの大きく異なるソフト 404 本文を返していました。そのため、片方のホストで取得したコントロールは、もう片方では意味をなしません。また、フレームワークが /x と /a/b/x に対して異なるフォールバックをレンダリングする場合は、パスの深さごとにもベースラインを取り直してください。
エッジのページはオリジンでの発見事項ではありません。CDN の「Access Denied」/「Unsupported Request」本文は、リクエストがアプリケーションに到達していないことを意味します。エッジの挙動として分類し、次に進んでください。
ステップ 1 — フィンガープリント(レッドチームのみ)
アペックスホストだけでなく、稼働中のすべてのホストでフィンガープリントを取得してください。複数ホスト/ワイルドカードのターゲットでは、プラットフォームスキルのルーティングに、単一ホストではなくすべてのバナーを反映する必要があります。
-L(リダイレクトを追跡)を使用してください。ID プロバイダーや CDN のシグナル(login.microsoftonline.com、okta、auth0、CDN バナー)は、通常 30x リダイレクトの先にあるため、リダイレクトしない curl -sI では該当シグナルを見落とします。ヘッダーとランディングページの HTML の両方を取得してください(__NEXT_DATA__、VIEWSTATE、laravel_session、Ignition、フレームワークのマーカーはヘッダーではなく本文にあります)。
HOSTS="$TARGET"
if [ -f "recon/$TARGET/live-hosts.txt" ]; then
HOSTS=$(cat "recon/$TARGET/live-hosts.txt")
fi
for H in $HOSTS; do
echo "=== $H ==="
# -L follow redirects, -D - dump headers, -o body; cap body to keep context small
curl -sSL -m 12 -D - -o /tmp/fp_body "https://$H" 2>/dev/null | tr -d '\r'
# surface body-only platform markers
grep -aoE '__NEXT_DATA__|/_next/|VIEWSTATE|rO0[AB]|laravel_session|Ignition|Telescope|Whitelabel|/actuator|application/grpc|socket\.io|swagger|\.js\.map' \
/tmp/fp_body | sort -u
done
rm -f /tmp/fp_body
live-hosts.txt が存在しない場合でも、ループは $TARGET に対して 1 回実行されます。どのシグナルがどのホストから得られたかを記録してください。ホスト B でプラットフォームスキルが一致しても、ホスト A が同じスタックを実行しているとは限りません。
次のシグナルとプラットフォームスキルの対応を確認してください。
okta.com | auth0.com | pingidentity → okta-attack
login.microsoftonline.com | outlook | sts → m365-entra-attack
pulse | fortinet | ivanti | citrix → enterprise-vpn-attack
vsphere | vcenter | :9443 → vmware-vcenter-attack
amazonaws | azure | googleapis | gcp → cloud-iam-deep
github.com/<org>/ → supply-chain-attack-recon
.apk | play.google.com → apk-redteam-pipeline
MongoDB | mongoose | CouchDB | Redis → hunt-nosqli
?page= | ?file= | ?path= | php wrapper → hunt-lfi
rO0A | VIEWSTATE | rememberMe cookie → hunt-deserialization
Access-Control-Allow-Origin header → hunt-cors
/forgot-password | /reset | X-Forwarded → hunt-host-header
?redirect= | ?next= | ?return= | ?url= → hunt-open-redirect
OTP | /verify | /2fa | no-rate-limit → hunt-brute-force
Set-Cookie session | PHPSESSID → hunt-session
Active Directory | LDAP | OpenLDAP | ADFS → hunt-ldap
__NEXT_DATA__ | /_next/ | buildId → hunt-nextjs
X-Powered-By: Express | Node.js | .js stack → hunt-nodejs
postMessage | dangerouslySetInnerHTML → hunt-dom
WebSocket | ws:// | socket.io → hunt-websocket
gRPC | :50051 | application/grpc → hunt-grpc
laravel_session | Ignition | Telescope → hunt-laravel
X-Application-Context | Whitelabel | /actuator → hunt-springboot
:6443 | :10250 | :2379 | kubectl → hunt-k8s
.github/workflows | Jenkins | GitLab CI → hunt-cicd
.js.map | swagger.json | /.env → hunt-source-leak
HSTS missing | SPF | DMARC | AXFR → hunt-tls-network
競合の解決とロード上限
実際のターゲットでは、ほぼ必ず複数のシグナルが同時に返されます。たとえば、1つのホストに Cloudflare(CDN)+ login.microsoftonline.com(リダイレクト)+ __NEXT_DATA__
(Next.js フロントエンド)+ amazonaws(オリジン)が同時に現れることがあります。すべての一致を無条件にロードすると、20個以上のスキルを読み込んでコンテキストウィンドウを使い切り、シグナルの強いスキルがノイズに埋もれてしまいます。次の優先順位と上限を適用してください。
優先順位(上位のティアからロードし、上限に達したら停止):
tier 1 identity / SSO fabric okta-attack, m365-entra-attack
(own the auth boundary — highest blast radius if compromised)
tier 2 perimeter appliances enterprise-vpn-attack, vmware-vcenter-attack
(pre-auth RCE / direct internal foothold)
tier 3 cloud / IAM cloud-iam-deep, hunt-cloud-misconfig
(credential → lateral movement)
tier 4 app framework / stack hunt-nextjs, hunt-nodejs, hunt-laravel,
hunt-springboot, hunt-aspnet, hunt-sharepoint
tier 5 protocol / class signals hunt-nosqli, hunt-lfi, hunt-deserialization,
hunt-cors, hunt-host-header, hunt-open-redirect, hunt-grpc,
hunt-websocket, hunt-dom, hunt-k8s, hunt-cicd, hunt-source-leak,
hunt-tls-network, hunt-ldap, hunt-brute-force, hunt-session
ロード上限:プラットフォームスキルのロードは最大8個です。 8個を超えて一致した場合は、ティアの高い8個を残し、それ以外は除外します。後で必要に応じてロードできるよう、除外した項目は分類ブロックの
deferred: の下に出力してください。
重複排除ルール(同じ証拠に対するスキルの二重ロードを避ける):
- CDN のバナーのみ(Cloudflare/Akamai/Fastly)は、プラットフォームの一致とは見なしません。これはアプリではなくエッジを特定するものです。このためのスキルはロードせず、すでにモードセットに含まれている
hunt-cache-poison/hunt-http-smugglingのために記録してください。 - ヘッダー/オリジンにある
amazonaws/azure/googleapis→cloud-iam-deep。 同じ文字列が JS バンドルまたは APK 内の漏えいしたキー/JSONとして見つかった場合も →cloud-iam-deepですが、有効な認証情報につながる手がかりとして記録してください(優先度を上げ、このホストではティア3をティア1にします)。 - 同じホストでフレームワークのマーカー(
__NEXT_DATA__、laravel_session)と汎用クラスシグナル(?redirect=、Access-Control-Allow-Origin)が見つかった場合は、フレームワークスキル(ティア4)をロードし、クラススキルは上限に余裕がある場合に限り残してください。WAPT/redteam モードセットには、一般的なクラススキルがすでに無条件でロードされています。
ステップ2 — スキルセットをロードする
Skill ツールを使い、各スキルを順番に呼び出します。
mode=redteam
常時ロード(最初にロード):
redteam-mindset
mid-engagement-ir-detection
プラットフォーム(ステップ1のフィンガープリント一致に応じて、2番目にロード):
okta-attack
m365-entra-attack
enterprise-vpn-attack
vmware-vcenter-attack
cloud-iam-deep
supply-chain-attack-recon
apk-redteam-pipeline
影響度の高い hunt-* セット(3番目にロード):
hunt-rce
hunt-sqli
hunt-ssrf
hunt-ato
hunt-auth-bypass
hunt-saml
hunt-oauth
hunt-mfa-bypass
hunt-file-upload
hunt-http-smuggling
hunt-cloud-misconfig
hunt-sharepoint
hunt-aspnet
レポート形式:redteam-report-template(subject / observations / description / impact / recommendation / poc)。
mode=wapt
常時ロード:
bb-methodology
security-arsenal
triage-validation
完全な hunt-* セット(OWASP 関連のすべて):
hunt-xss hunt-sqli hunt-ssrf hunt-idor
hunt-csrf hunt-xxe hunt-rce hunt-graphql
hunt-oauth hunt-saml hunt-mfa-bypass hunt-auth-bypass
hunt-ato hunt-file-upload hunt-business-logic hunt-race-condition
hunt-llm-ai hunt-api-misconfig hunt-ssti hunt-cache-poison
hunt-http-smuggling hunt-subdomain hunt-cloud-misconfig hunt-misc
hunt-aspnet hunt-sharepoint hunt-ntlm-info
hunt-lfi hunt-nosqli hunt-deserialization
hunt-cors hunt-host-header hunt-open-redirect
hunt-brute-force hunt-session hunt-ldap
hunt-nextjs hunt-nodejs hunt-dom
hunt-websocket hunt-grpc hunt-laravel
hunt-springboot hunt-k8s hunt-cicd
hunt-source-leak hunt-tls-network
レポート形式:report-writing(ターゲットが bugcrowd 上にある場合は bugcrowd-reporting)。
box=greybox:認証情報は /hunt によってすでに取得され、セッションメモリで利用できます。
認証情報の検証が済むまでは、認証済みの hunt- セットを一斉に実行しないでください。* /hunt は認証情報の入力を求めて保存するだけで(commands/hunt.md)、それが有効かどうかは確認しません。無効な認証情報、MFA で制限された認証情報、またはロールの異なる認証情報で認証済みテストをすべて実行すると、実行時間を無駄にし、「認証対象の攻撃面がない」という誤った結論につながります。まず、コストの低い認証プリフライトを1つ実行してください。
# session-cookie creds: one authenticated GET against an identity echo endpoint
curl -sS -m 12 -b "$SESSION_COOKIE" "https://$TARGET/api/me" -w '\n%{http_code}\n'
# 200 + your username/email → live session, role visible in body
# 401/403 → dead or insufficient — STOP, re-auth
# bearer/JWT creds: same probe with Authorization
curl -sS -m 12 -H "Authorization: Bearer $TOKEN" \
"https://$TARGET/api/me" -w '\n%{http_code}\n'
# raw user/pass: drive the real login flow once, capture Set-Cookie, then echo
# watch for an MFA / step-up challenge in the response — if present, the creds
# alone do not yield an authenticated session (see memory: operator-capability)
プリフライトで次の3点を確認し、hunt-* スキル用に記録してください。
- 有効であること — 認証プローブが 401/403 ではなく 200 を返す。
- ロール/権限 —
/api/me(または同等のエンドポイント)の本文に、想定されるロール/テナント/スコープが示されている。IDOR と認可テストでは、既知の基準となるユーザーが必要です。気づかないまま管理者または読み取り専用になっている認証情報は、認可関連のすべての調査結果を歪めます。 - MFA で制限されていないこと — ログインが 2fa/ステップアップ認証のチャレンジで停止していない。停止している場合、認証情報はあってもセッションはありません。能力は最小限と見なし、認証済みの到達範囲を主張する前にオペレーターへ確認してください。
プリフライトに失敗した場合、黙ってブラックボックスとして続行してはいけません。オペレーターが認証情報を再提出できるよう、「greybox creds did not validate (HTTP {code} / MFA challenge)」を明示してください。プリフライトに問題がないことを確認してから、その検証済みセッションをすべての認証済みテストに適用してください。
ステップ3 — 分類情報の出力(セッション開始時に1回)
決定的なブロックを出力します。装飾なしのプレーンテキストで、小文字を使い、コロンで区切ってください。
mode=redteam
loaded for red team: {N} skills
mindset: redteam-mindset
platform: {fingerprint-matched skills (<=8, tier order), or "none detected"}
deferred: {platform skills past the 8-cap, or omit line if none}
auth: hunt-ato, hunt-auth-bypass, hunt-saml, hunt-oauth, hunt-mfa-bypass
inj: hunt-rce, hunt-sqli, hunt-ssrf, hunt-file-upload
infra: hunt-http-smuggling, hunt-cloud-misconfig
stack: hunt-sharepoint, hunt-aspnet
ir: mid-engagement-ir-detection
mode=wapt
loaded for wapt ({blackbox|greybox}): {N} skills
inj: hunt-xss, hunt-sqli, hunt-ssrf, hunt-rce, hunt-xxe, hunt-ssti, hunt-file-upload
authz: hunt-idor, hunt-auth-bypass, hunt-ato
auth: hunt-oauth, hunt-saml, hunt-mfa-bypass
api: hunt-graphql, hunt-api-misconfig
logic: hunt-business-logic, hunt-race-condition
infra: hunt-http-smuggling, hunt-cache-poison
recon: hunt-subdomain
cloud: hunt-cloud-misconfig
ai: hunt-llm-ai
stack: hunt-aspnet, hunt-sharepoint, hunt-ntlm-info
misc: hunt-misc, hunt-csrf
reporting: bb-methodology, security-arsenal, triage-validation
サブエージェントへのスコープの継承
調査の一部をサブエージェントに委任する場合、スコープが暗黙に継承されることはありません。すべてのサブエージェント向けプロンプトには、次の内容を含めてください。
- 許可されたホストのリストを、データとして一字一句そのまま記載します。「対象環境」でも「*.target.com」でもなく、明示的なリストを渡します。サブエージェントが境界を推測することはできません。
- **ホスト発見時のルール:**実行中に見つかったホスト(CT ログ、CSP ヘッダー、JS バンドル、CNAME チェーン、エラーメッセージ経由)は、報告のみとします。DNS を解決して記録し、引き継いでください。オペレーターが再承認するまでは、プローブを実行せず、書き込みも行わないでください。
- **許可リストより先に適用する、アクション実行エンドポイントの拒否リスト。**まず名前に含まれる動詞で拒否します:
refund、settle、payout、transfer、adjust、disburse、create、update、delete、rotate、reset、send、initiate、generate、process。その後にのみ、読み取りを示す名前を許可します。順序が重要です。refund/batch/statusのようなパスは、読み取りを示すキーワード「status」に一致しますが、返金用のルートです。先に許可リストを適用すると、これをプローブしてしまいます。 - 「読み取り専用」は形容詞ではなく、禁止する動詞を明記します。「読み取り専用」は「破壊的な操作をしないこと」と解釈されることがよくありますが、エンドポイント名が
generate*で始まるエンドポイントにエージェントが{}を送信し、本番環境に実際のレコードを作成するのを防げません。
**許可されたエンゲージメントからの教訓:**サブエージェントに「読み取り専用」と指示したにもかかわらず、(a) {} を送れば検証エラーが返ると予想して本番環境に実際のレコードを作成し、(b)許可リストに含まれていないクラウドバケットにオブジェクトを書き込みました。そのバケットは親プロンプトでは DNS 確認の対象として名前が挙げられていただけでした。どちらも成果物で開示しました。解決策は構造的なものです。スコープをデータとして渡し、動詞で許可する前に動詞で拒否し、発見したホストは別途指示があるまですべてスコープ外として扱います。
ステップ 4 — /hunt に制御を戻す
分類を出力したら、ステップ 3(兄弟エージェントへの委任)とステップ 4(アクティブテスト)のために、制御を /hunt に戻します。ここではプローブを実行しないでください。このスキルはコンテキストを読み込むだけです。
プライバシー
次の内容を決してそのまま繰り返したり、ログに記録したり、永続化したりしないでください。
- SOW/作業範囲記述書/エンゲージメントレターの内容
- グレーボックスの認証情報(
/huntがセッションメモリー内に保持し、ディスクには書き込みません) - ユーザーレベルのメモリーにおけるクライアント識別情報
関連スキルと連携
bb-methodology— PART 0 のモード確認が完了したとき。ワークフローの基本要素:bb-methodologyがエンゲージメントの種類(レッドチーム、WAPT、バグバウンティ)を確認します。その回答は、このスキルのmode=redteam/mode=waptの呼び出しに直接反映されます。redteam-mindset+mid-engagement-ir-detection—mode=redteamが読み込まれたとき。ワークフローの基本要素:レッドチームのフローでは、プラットフォームスキルや hunt-* スキルより先に、ステップ 2 でこれらの常時有効なスキルを読み込みます。okta-attack/m365-entra-attack/enterprise-vpn-attack/vmware-vcenter-attack/cloud-iam-deep/supply-chain-attack-recon/apk-redteam-pipeline** — フィンガープリントのシグナルが一致したとき。ワークフローの基本要素:ステップ 1 のrecon/<target>/live-hosts.txtに対する curl フィンガープリントスキャンで、バナー/ドメインのシグナルをこれらのプラットフォームスキルの 1 つ以上に対応付けます。hunt-rce/hunt-sqli/hunt-ssrf/hunt-ato/all other hunt-* skills** — モード固有のスキルセットを出力するとき。ワークフローの基本要素:このスキルはローダーです。hunt-* スキルを列挙しますが、プローブは実行しません。実際の調査は、ステップ 4 で制御が/huntに戻った後に行われます。report-writingとredteam-report-template— 分類の出力でレポート形式を指定するとき。ワークフローの基本要素:mode=waptでは成果物の形式としてreport-writingを使用し、mode=redteamでは代わりにredteam-report-templateを使用します。