第 6 章 · 04 服务端请求伪造(SSRF)


文档摘要

第 6 章 · 04 服务端请求伪造(SSRF) 本节摘要:服务端请求伪造(SSRF)让服务器去访问攻击者够不到的网络与服务。一个「替用户取远程内容」的功能(代理、预览器、导入器、webhook 测试器、PDF/图片渲染器、链接展开),就是一条通往内网与控制面的隧道。本节讲透攻击面(直接 URL 参数、间接来源、协议转换服务、不那么明显的 GraphQL resolver/后台爬虫/包管理器)、高价值目标(云元数据 IMDSv1/v2、GCP/Azure 元数据、Kubernetes kubelet/API、Docker/Redis/Elasticsearch/FastCGI 等内网服务)、协议滥用(gopher/dict/file/各种 wrapper)、地址变体与 URL

第 6 章 · 04 服务端请求伪造(SSRF)

本节摘要:服务端请求伪造(SSRF)让服务器去访问攻击者够不到的网络与服务。一个「替用户取远程内容」的功能(代理、预览器、导入器、webhook 测试器、PDF/图片渲染器、链接展开),就是一条通往内网与控制面的隧道。本节讲透攻击面(直接 URL 参数、间接来源、协议转换服务、不那么明显的 GraphQL resolver/后台爬虫/包管理器)、高价值目标(云元数据 IMDSv1/v2、GCP/Azure 元数据、Kubernetes kubelet/API、Docker/Redis/Elasticsearch/FastCGI 等内网服务)、协议滥用(gopher/dict/file/各种 wrapper)、地址变体与 URL 混淆、重定向滥用、头部/方法控制,以及把盲 SSRF 经 OAST 落地为凭据窃取与 RCE 的链式攻击。SSRF 的杀伤力在于「一次 fetch 就能换出凭据、横向移动,甚至 RCE」。

内容来源:原项目知识包 strix/skills/vulnerabilities/ssrf.md,汉化并套用体系化模板。

⚠️ 仅限授权测试:本节所有 payload 与技术仅用于你自己的应用或有书面授权的渗透测试。未经授权对他人系统使用这些技术是非法的。

学习目标

阅读完本节,你应当能够:

  1. 识别 SSRF 的典型攻击面(直接 URL 参数、间接来源、协议转换服务、隐蔽入口)。
  2. 锁定高价值目标:云元数据(IMDSv1/v2、GCP、Azure)、Kubernetes、内网服务(Docker/Redis/ES/FastCGI)。
  3. 掌握协议滥用(gopher/dict/file/wrapper)与地址变体/URL 混淆
  4. 重定向滥用、DNS rebinding、URL 解析器差异绕过白名单。
  5. OAST 把盲 SSRF 落地为可观测回调,并据此推断内网可达性。
  6. 用验证步骤确认漏洞、排除误报(尤其区分服务端请求与客户端请求)。
  7. 评估 SSRF 的影响等级并完成链式攻击(元数据→云 API、Redis/FCGI/Docker→RCE)。

一、攻击面

作用域:

  • 出站 HTTP/HTTPS 取数器(代理、预览器、导入器、webhook 测试器)。
  • 经 URL handler 触达的非 HTTP 协议(gopher、dict、file、ftp、smb wrapper)。
  • 经网关与 sidecar(envoy/nginx)的服务到服务跳转。
  • 云/平台元数据端点、实例服务、控制面。

直接 URL 参数:url=link=fetch=src=webhook=avatar=image=

间接来源:Open Graph/链接预览、PDF/图片渲染器;服务端分析(Referer 跟踪器)、导入/导出 job;webhook/回调校验器。

协议转换服务:经 wkhtmltopdf/无头 Chrome 的 PDF、图片管线;文档解析器、SSO 校验器、归档展开器。

不那么明显的入口:按 URL 取数的 GraphQL resolver;后台爬虫、仓库/包管理器(git、npm、pip);日历(ICS)取数器。

💡 核心心法:任何「替用户取远程内容」的功能,都是通往内网与控制面的潜在隧道。scheme/host/port/header 若未被显式绑定,攻击者就会借道而行。

二、检测通道

建立神谕(oracle)

  • OAST 优先:用带外回调确认出站。interactsh-client -v(在沙箱中运行)给一个唯一 *.oast.fun 域;把它嵌进 URL 参数,观察 interactsh stdout 的入站 DNS/HTTP 命中。每次调用产生新域——需要在多个 payload 间关联命中时,重启以获取新域。
  • 时延/响应差异:从时延、响应大小、TLS 错误、ETag 差异推断内网可达性。
  • 端口测绘:用短连接/读超时做二分搜索,得到内网端口图。

高价值目标速查

平台 端点 关键要求
AWS IMDSv1 http://169.254.169.254/latest/meta-data//iam/security-credentials/{role}/user-data 无需头
AWS IMDSv2 PUT /latest/api/token(头 X-aws-ec2-metadata-token-ttl-seconds),再带 X-aws-ec2-metadata-token GET sink 必须能设头/方法;否则找能设的中介
AWS ECS/EKS http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 任务凭据
GCP http://metadata.google.internal/computeMetadata/v1//instance/service-accounts/default/token 必须带 Metadata-Flavor: Google
Azure http://169.254.169.254/metadata/instance?api-version=2021-02-01 必须带 Metadata: true;MSI OAuth 在 /metadata/identity/oauth2/token
Kubernetes kubelet 10250(认证)/10255(废弃只读);API server https://kubernetes.default.svc/ 常需 service account token;SSRF 若透传头/cookie 可能复用
Docker http://localhost:2375/v1.24/containers/json 无 TLS 变体常仅内网
Redis/Memcached dict://localhost:11211/stat、gopher 打 Redis 6379 协议滥用
Elasticsearch http://localhost:9200/_cat/indices 内网默认无认证
FastCGI/PHP-FPM gopher://localhost:9000/ 构造记录写文件/执行

三、利用方法与技术

协议滥用

gopher:说裸文本协议(Redis/SMTP/IMAP/HTTP/FCGI);用来构造多行 payload、经 Redis 排 cron、或构造 FastCGI 请求。

file 与 wrapper:file:///etc/passwdfile:///proc/self/environ(当库允许 file handler 时);jar:netdoc:smb:// 以及语言特定 wrapper(php://expect://,启用时)。

地址变体

  • 回环:127.0.0.1127.121307064330x7f000001::1[::ffff:127.0.0.1]
  • RFC1918/链本地:10/8、172.16/12、192.168/16、169.254/16。
  • 测 IPv6 映射与混合记法。

URL 混淆

  • userinfo 与片段:http://internal@attacker/http://attacker#@internal/
  • 无 scheme/相对形式,服务器可能内部补全://169.254.169.254/
  • 尾点与混合大小写:internal. vs INTERNAL;Unicode 点号同形字。

重定向滥用

  • 白名单只在重定向前校验:攻击者 302 → 内网主机。
  • 测多跳与协议切换(http → file/gopher,经自定义客户端)。

头部与方法控制

  • 部分 sink 反射或允许 CRLF 注入到请求行/header。
  • 若任意头/方法可行,IMDSv2、GCP、Azure 变得可达。

四、绕过技巧

地址编码:IP 的十进制、十六进制、八进制表示;IPv6 变体、IPv4 映射 IPv6、混合记法。

DNS rebinding:第一次解析返回允许的 IP,第二次返回内网目标;用攻击者控制的短 TTL DNS 记录。

URL 解析器差异:白名单校验器与实际取数器之间解析不一致;利用 scheme、host、port、path 处理上的分歧。

重定向链:初始 URL 过白名单,重定向指向内网;经重定向做协议降级/升级。

中介放大:sink 不能设头/方法时,找能设的中间服务(经它转发到元数据端点)。

💡 绕过的本质:白名单校验器与实际取数器常常是两个不同的库/两次解析,二者对同一 URL 的理解不一致——找到「校验器认为是允许的、取数器却打到内网」的表示形式。

五、验证与误报排除

确认一个 SSRF 真实存在的稳妥步骤:

  1. 证明发生了服务端发起的出站请求:OAST 交互,或仅内网才有的响应差异。
  2. 访问到非公开资源:元数据、内网管理面板、服务端口,来自漏洞服务。
  3. 最小影响凭据访问:尽可能演示短命 token 或无害的内网数据读取。
  4. 可复现:记录控制 scheme/host/header/method 与重定向行为的请求参数。

常见误报:

  • 仅客户端 fetch(无服务端请求)。
  • 带 DNS pinning 且不跟随重定向的严格白名单。
  • 返回 canned 响应、无真实出站的 SSRF 模拟器/mock。
  • 所有目标与协议返回统一错误,确认出站被阻断。
  • OAST 回调的源 IP 是测试者机器而非服务器——是浏览器或客户端 fetch 发的请求,不是后端。

六、影响评估

  • 云凭据泄露:进而控制面/API 访问(列 bucket、读 secret)。
  • 访问内网控制面板与数据存储:公开未暴露的内部服务。
  • 横向移动:进入 Kubernetes、服务网格、CI/CD。
  • RCE:经协议滥用(FCGI、Redis)、Docker daemon 访问、可脚本化的管理界面。

⚠️ SSRF 的影响天花板极高:云元数据凭据 = 云账号接管;Redis/FCGI/Docker 协议滥用 = RCE。即便是「只读」的内网端口扫描,也暴露了内部拓扑。

本节要点回顾

  1. 核心心法:任何「替用户取远程内容」的功能都是通往内网与控制面的隧道;scheme/host/port/header 未显式绑定就会被借道。
  2. 攻击面:直接 URL 参数(url=/webhook=/avatar=)、间接来源(链接预览/PDF 渲染/webhook 校验)、协议转换服务、隐蔽入口(GraphQL resolver/后台爬虫/包管理器)。
  3. 高价值目标:云元数据(IMDSv1 无头、IMDSv2 需 token 头、GCP 需 Metadata-Flavor、Azure 需 Metadata)、Kubernetes(kubelet/API server)、内网服务(Docker/Redis/ES/FastCGI/RabbitMQ/Jenkins)。
  4. 协议滥用:gopher(裸文本协议/Redis cron/FastCGI)、file/wrapper(file:///php:///expect://)。
  5. 绕过四路:地址编码(十进制/十六进制/IPv6)、DNS rebinding(双解析)、URL 解析器差异、重定向链;sink 不能设头时找中介。
  6. 盲 SSRF 落地:interactsh-client -v*.oast.fun 域;用时延/响应大小/TLS 错误/ETag 推断可达性;短超时二分测绘端口。
  7. 验证四步:证明服务端出站、访问非公开资源、最小凭据访问、可复现;警惕客户端 fetch、DNS pinning、模拟器、出站全阻断等真实误报——尤其 OAST 源 IP 必须是服务器而非测试者机器。
  8. 影响与链式:云凭据→云 API、Redis/FCGI/Docker→RCE、kubelet/API→token/secret→横向移动;天花板是云账号接管与 RCE。

下一节,我们看认证与 JWT——当令牌签发、校验或 claim 绑定出错,攻击者就能伪造身份、跨服务复用令牌,实现持久账户接管。


发布者: 作者: 灏天文库 转发
评论区 (0)
U