关于 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 基线(所有模式均须执行,必须在任何枚举之前完成)
对每台主机进行探测前,都要先执行此步骤。每台主机只需发送一个请求,这是整个工具包中成本最低的误报排除方式。
许多现代环境(由 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
每台主机记录:状态码、字节长度、正文哈希。这三项就是对照基线。
**规则:只有响应与对照不同,路径才算“已发现”。**与对照哈希相同的 200 属于软 404。正文与对照不同的 404 可能对应真实处理程序。比较正文,绝不能只看状态码。
每台主机都要重新推导基线,因为同一环境中的基线可能各不相同。一次测试中,有两台主机提供相同应用,却返回大小迥异的软 404 正文;因此,在一台主机上获取的对照用于另一台主机毫无意义。如果框架对 /x 和 /a/b/x 返回不同的回退页面,也要按路径深度重新推导基线。
边缘页面不属于源站发现结果:CDN 返回“Access Denied”/“Unsupported Request”正文,意味着请求未到达应用。将其归类为边缘行为,然后继续。
步骤 1 — 指纹识别(仅限红队)
对每台存活主机进行指纹识别,而不只是顶级域名。对于多主机 / 通配符目标,平台技能的路由必须依据所有主机的标识,而非仅凭一台主机。
使用 -L(跟随重定向)——身份提供商和 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 运行一次。记录每个信号来自哪台主机——在主机 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
冲突解决与加载预算
真实目标几乎总是会同时返回多个信号——例如,同一个主机可能同时显示 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 的指纹匹配结果决定是否加载):
okta-attack
m365-entra-attack
enterprise-vpn-attack
vmware-vcenter-attack
cloud-iam-deep
supply-chain-attack-recon
apk-redteam-pipeline
高影响力 hunt-* 集(第三加载):
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 限制或角色不符的凭证运行所有已认证测试,会浪费整次运行,并得出错误的“无认证攻击面”结论。请先运行单个低成本认证预检:
# 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)
确认预检的以下三项,并记录下来供 hunt-* 技能使用:
- 有效——认证探测返回 200,而不是 401/403。
- 角色/权限——
/api/me(或等效接口)的响应正文显示预期的角色/租户/范围。IDOR 和授权测试需要已知的基线身份;未察觉的管理员或只读凭证会扭曲每项授权测试结果。 - 未受 MFA 限制——登录未停留在 2FA/step-up 挑战环节。如果停留在该环节,你持有凭证,但没有会话——默认采用最低权限,并在声称已通过认证访问前向操作员确认。
如果预检失败,不要默默地继续按黑盒模式处理——请明确提示“greybox 凭证未通过验证(HTTP {code} / MFA 挑战)”,以便操作员重新提供凭证。只有预检顺利通过后,才将已验证的会话应用于所有已认证测试。
步骤 3 — 打印分类信息(仅在会话开始时一次)
输出一个确定性区块。使用纯文本、小写、以冒号分隔,不添加装饰。
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
子 Agent 的范围继承
如果将搜寻的任何部分委派给子 Agent,范围不会隐式继承。每条子 Agent 提示词都必须包含:
- 逐字列出获授权的主机列表,并将其作为数据提供。 不要写“目标环境”,也不要写
"*.target.com"——必须提供明确列表。子 Agent 无法自行推断边界。 - 发现主机规则: 在运行过程中发现的主机(通过 CT 日志、CSP 标头、JS 包、CNAME 链、错误消息)只能报告。解析 DNS、记录下来,然后交回。绝不探测,绝不写入,除非操作员重新授权。
- 在任何允许列表之前应用针对会执行操作的端点的拒绝列表。 首先根据名称中的动词拒绝:
refund、settle、payout、transfer、adjust、disburse、create、update、delete、rotate、reset、send、initiate、generate、process。之后才允许名称呈读取特征的端点。顺序很重要——像refund/batch/status这样的路径会匹配读取特征关键词"status",但它实际上是退款路由;如果先应用允许列表,就会对它进行探测。 - 将“只读”明确写成禁止的动词,而不是一个形容词。 “只读”通常会被理解为“不要造成破坏”,这并不能阻止 Agent 向名称以
generate*开头的端点发送{},并在生产环境中创建真实记录。
来自一次授权测试的教训: 子 Agent 收到“只读”指示后,仍然 (a) 在生产环境中创建了一条真实记录,因为它预期 {} 会返回验证错误;(b) 向一个从未列入授权清单的云存储桶写入了对象——父提示词只要求对该存储桶进行 DNS 检查。这两件事都在交付内容中披露了。解决办法在于结构本身:将范围作为数据传递,先按动词拒绝,再按动词允许,并将每个发现的主机视为范围外对象,直到另行授权。
步骤 4 — 将控制权交还给 /hunt
打印完分类结果后,将控制权交还给 /hunt,以执行步骤 3(同级委派)和步骤 4(主动测试)。此处不要运行探测——此技能仅加载上下文。
隐私
绝不回显、记录或持久化:
- SOW / 工作范围 / 参与协议内容
- 灰盒凭据(由
/hunt保存在会话内存中,绝不写入磁盘) - 用户级记忆中的客户标识符
相关技能与调用链
bb-methodology— 完成 PART 0 模式确认时。工作流原语:bb-methodology确认参与类型(红队、WAPT 或漏洞赏金);答案会直接用于此技能的mode=redteam/mode=wapt调用。redteam-mindset+mid-engagement-ir-detection— 加载mode=redteam时。工作流原语:在红队流程的步骤 2 中、加载任何平台技能或 hunt-* 技能之前,始终首先加载这些技能。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 指纹扫描,会将横幅 / 域名信号映射到一个或多个这些平台技能。hunt-rce/hunt-sqli/hunt-ssrf/hunt-ato/ 所有其他 hunt- 技能* — 打印特定模式的技能集时。工作流原语:此技能负责加载;它会列出 hunt-* 技能,但不会运行探测——步骤 4 将控制权交还给/hunt后才会开始实际搜寻。report-writing与redteam-report-template— 分类结果指定报告格式时。工作流原语:mode=wapt最终使用report-writing作为交付格式;mode=redteam则改用redteam-report-template。