教程
🛡️

网络安全

Web 安全、渗透测试、密码学与安全合规的系统化教程。

SSRF 服务端请求伪造:拿服务器当跳板

讲清 SSRF 的原理与危害,覆盖 file://、dict://、gopher:// 等协议利用,结合靶场代码审计思路,并给出 URL 白名单、禁用危险协议等防御。

· 更新于 2026-07-18 阅读量 --

SSRF(服务端请求伪造,OWASP A10) 和 CSRF 名字像,方向相反:CSRF 是借用户身份,SSRF 是借服务器身份。当网站允许你指定”让服务器去请求某个 URL”时,攻击者就能让这台服务器去访问它内网里的东西——比如 127.0.0.1 的管理后台、Redis、云元数据。

以下仅在授权靶场(如 SSRF-Labs、DVWA)练习;对他人服务器发起 SSRF 探测属违法。

原理:服务器成了你的”代理”

很多功能会让服务器发请求:

  • 网页截图服务:输入 URL,服务器去抓取;
  • 在线翻译/采集:输入网址,服务器去读;
  • 头像加载:输入图片 URL,服务器去下载;
  • 预览链接:输入链接,服务器去取标题。

如果”目标 URL”用户可控且没限制,攻击者就能让服务器去请求任意地址——包括内网。

// 有洞示例:让服务器下载用户给的 URL
$url = $_GET['url'];
$content = file_get_contents($url);  // 服务器去请求 $url
echo $content;

输入 ?url=http://127.0.0.1:8080/admin,服务器就访问了本机 8080 的管理后台,把内容回显给你——你借此”看到”了内网才能看的东西。

危害:从读取到打穿内网

  • 读内网服务:访问 127.0.0.1192.168.x.x 上的管理后台、接口;
  • 读云元数据:云服务器 http://169.254.169.254/(云厂商元数据服务)可能拿到临时密钥、AK/SK,进而控制整朵云;
  • 探测端口:通过响应差异判断内网哪些端口开着,做内网资产测绘;
  • 打内网服务:对内网 Redis、FastCGI、MySQL 等发请求利用(配合 gopher 协议);
  • 读本地文件:用 file:// 协议读取服务器文件。

SSRF 是”打进内网”的经典跳板。

协议玩出花:file / dict / gopher

file_get_contents 这类函数支持多种协议(取决于 PHP 的 allow_url_fopen/allow_url_include 等):

file:// 读文件

?url=file:///etc/passwd

直接读服务器本地文件,等于文件读取漏洞。

dict:// 探测端口

?url=dict://127.0.0.1:6379

dict 协议能和端口对话,用来探测某端口是否开放、甚至对其发简单命令(如 Redis)。

gopher:// 万能协议

?url=gopher://127.0.0.1:6379/_<payload>

gopher 能发送任意 TCP 字节流,于是可以构造完整的 Redis、MySQL、FastCGI 等协议请求,直接打内网服务。这是 SSRF 利用的”大杀器”,Redis 未授权访问 + SSRF + gopher 常能拿 shell。

靶场代码审计思路

找 SSRF,先搜”服务器发起请求”的函数:

  • PHP:file_get_contentscurl_execfsockopenfopen
  • Java:URL.openStreamHttpClientHttpURLConnection
  • Python:requests.geturllib.request

再看这些函数的 URL 是否来自用户输入。若来自 GET 参数且未校验,基本就是 SSRF。审计时画一条线:“用户值 → 请求函数”,中间有没有过滤,就是漏洞所在。

绕过技巧(靶场向)

防御常黑名单 127.0.0.1localhost,于是:

  • 用十进制/八进制 IP127.0.0.1 = 2130706433
  • 用短域名/域名解析到内网:自己注册个域名解析到 127.0.0.1
  • @ 迷惑http://expected@127.0.0.1/(部分解析取后半);
  • 进制/省略前缀http://0177.0.0.1(八进制);
  • DNS 重绑定:域名首次解析到外网通过校验,再解析到内网发起请求。

理解这些,才能既会测也会防。

防御:管住”服务器能去哪”

1. URL 白名单(最靠谱)

只允许访问你信任的域名/IP,其他一律拒绝:

$allowed = ['api.trusted.com', 'img.cdn.com'];
$host = parse_url($_GET['url'], PHP_URL_HOST);
if (!in_array($host, $allowed)) die('拒绝');

2. 禁止非常规协议

只允许 http/https,禁掉 filedictgopherftp 等:

if (!in_array(parse_url($url, PHP_URL_SCHEME), ['http','https'])) die('拒绝');

3. 解析后校验 IP

把 URL 解析成真实 IP,判断是不是内网地址(过滤 127.0.0.0/810.x192.168.x169.254.x 等),且解析后、请求前再校验一次(防 DNS 重绑定)。

4. 网络层隔离

让”能发外网请求的应用服务器”和”内网敏感服务”在网络上隔离,即使 SSRF 存在也访问不到核心内网。云上给元数据服务设 IMDSv2(带令牌)防 SSRF 读密钥。

5. 不出网/不回显

需要抓取的功能,尽量由独立、无内网权限的”采集服务器”承担,且关闭不必要的协议支持。

更多实战案例:从外网打到内网

某网站有”在线翻译/抓取网页”功能,后端用 file_get_contents($_GET['url']) 去取用户给的网址。攻击者不传公网地址,而传 http://169.254.169.254/latest/meta-data/(云服务器元数据接口),直接读到实例的临时凭证、密钥,进而控制整台云主机。再传 http://localhost:6379/ 探测内网 Redis,或 http://192.168.1.1/ 打路由器管理页。SSRF 的本质是:让服务器代替攻击者去访问它本不该访问的内部资源。

更多实战案例:协议与外带

除了 http,攻击者还能用 file:// 读服务器本地文件(如 /etc/passwd),用 dict:// 探测端口与服务指纹,用 gopher:// 构造任意 TCP 报文去打内网未授权服务(如 FastCGI、Redis 未授权写入 crontab 拿 shell)。配合 DNS 重绑定还能绕过基于域名的黑名单。

常见坑

  1. 只拦 127.0.0.1localhost:攻击者用 0177.0.0.1(八进制)、0.0.0.0[::1]、短域名解析到回环来绕过。
  2. 只校验域名白名单但没解析后比对:先放行域名,再 DNS 重绑定到内网 IP。
  3. 以为 https 就安全:协议无关,关键是目标地址是否内网。
  4. 黑名单永远补不全:应走白名单 + 解析后地址校验。

进阶:修复

最稳是白名单:只允许访问少数可信域名,且对解析后的 IP 做校验,禁止命中内网段(RFC1918、169.254.169.254、IPv6 回环等)。禁止非常用协议(只允许 http/https)。服务器出网做网络隔离,云主机对元数据接口加 IMDSv2 鉴权。

小测验

  • 问题1:SSRF 读云凭证常用哪个地址?答案:http://169.254.169.254/latest/meta-data/
  • 问题2:只拦 127.0.0.1 够吗?答案:不够,可用 [::1]、0.0.0.0、八进制等绕过。
  • 问题3:修复首选?答案:白名单域名 + 解析后 IP 校验,禁内网段与非常用协议。

更多实战案例:利用 SSRF 打内网未授权服务

内网里常有未授权服务:Redis 默认无密码且监听内网,gopher:// 协议可构造 TCP 报文给 Redis 写 cron 计划任务或写 webshell 到 web 目录,直接 getshell。还有内网 Admin 后台(如 http://192.168.1.10:8080/admin)只对内网开放,外网访问不了,但 SSRF 让服务器代访问,等于绕过网络隔离。FastCGI(127.0.0.1:9000)若未授权,可构造 FastCGI 请求执行任意 PHP 代码。这些利用都依赖”服务器能访问内网、而攻击者不能”。

更多实战案例:云元数据与凭证窃取

云主机(AWS、阿里云、腾讯云)的元数据接口 169.254.169.254 返回实例的临时访问凭证、角色、内网信息。若应用有 SSRF 且没拦这个地址,攻击者可读取 latest/meta-data/iam/security-credentials/ 拿到能操作云资源的 AK/SK,进而控制整批云资源。现代云用 IMDSv2 要求带 token 才返回,缓解了这一风险,但老配置仍危险。

常见坑(补充)

  1. 只拦 127.0.0.1 和 localhost:可用 [::1]0.0.0.0、八进制 0177.0.0.1、十进制 IP、短域名解析到回环来绕过。
  2. 只校验域名白名单但没解析后比对:先放行域名再 DNS 重绑定到内网 IP。
  3. 以为 https 就安全:协议无关,关键是目标地址是否内网。
  4. 黑名单永远补不全:应走白名单 + 解析后地址校验。

进阶(补充):修复要点

最稳是白名单:只允许访问少数可信域名;对解析后的 IP 做校验,禁止命中内网段(RFC1918、169.254.169.254、IPv6 回环等);禁止非常用协议(只允许 http/https);服务器出网做网络隔离;云主机对元数据接口加 IMDSv2 鉴权;对用户输入的 URL 做规范化后再校验。

小测验(补充)

  • 问题1:SSRF 读云凭证常用哪个地址?答案:http://169.254.169.254/latest/meta-data/
  • 问题2:只拦 127.0.0.1 够吗?答案:不够,可用 [::1]、0.0.0.0、八进制等绕过。
  • 问题3:修复首选?答案:白名单域名 + 解析后 IP 校验,禁内网段与非常用协议。

这一篇你该记住的

SSRF 是”借服务器身份发请求”,当功能允许用户输入目标 URL 且未限制时,攻击者能打内网:读 127.0.0.1 后台、file:// 读本地文件、dict/gopher 打内网服务(如 Redis)、读云元数据拿密钥。审计找”用户值→请求函数”链路。防御靠 URL 白名单、禁危险协议、解析后校验内网 IP、网络隔离。

SSRF 是”借服务器去访问”。下一篇 RCE 更直接——攻击者直接在服务器上执行系统命令或代码,基本等于拿下整台机器。