当前位置: 首页 > news >正文

SSRF由浅入深

引言

SSRF(Server-Side Request Forgery,服务器端请求伪造)是一类由攻击者构造请求,并由目标服务器执行的安全漏洞。攻击者通过精心构造的 URL,使服务器以自身身份向指定的地址发起请求,从而实现对目标系统的探测、访问或攻击。

在许多 Web 应用中,服务器通常会提供从指定地址获取资源的功能,例如读取远程图片、抓取网页内容或访问第三方接口等。如果这些功能未对用户输入的 URL 做严格校验,就可能被攻击者利用,构造特殊的请求指向服务器所在的内网地址。由于这些内网资源通常无法从外网直接访问,因此 SSRF 能够成为突破边界防护的一个重要手段。

简单来说,SSRF 的本质是攻击者借助存在漏洞的服务器,伪装成服务器自身,去访问攻击者原本无法直接接触的内部资源或服务。这类攻击在现代架构中尤为危险,尤其是在云环境、微服务、Kubernetes 集群和各种开放 API 场景中,可能带来敏感数据泄露、内网横向移动甚至远程代码执行等严重后果。

SSRF 漏洞原理

SSRF 漏洞的本质,是攻击者利用存在漏洞的服务器作为跳板,向原本无法直接访问的目标地址发起请求。在实际场景中,攻击者可能希望访问服务器 B 上的某个服务,但由于服务器 B 位于内网或受防火墙保护,外部网络是无法直接访问的。

如果此时服务器 A 存在 SSRF 漏洞,例如其提供了从 URL 中获取资源的功能,攻击者就可以构造一个特殊的请求地址,将其指向服务器 B,并提交给服务器 A。服务器 A 在没有对请求目标做充分校验的情况下,会以自身身份向服务器 B 发起请求。这样,攻击者就间接实现了对内网主机 B 的访问。

换句话说,攻击者并不直接访问目标服务,而是通过中间的受害服务器(A)来完成对目标(B)的探测、访问甚至攻击,从而绕过网络边界的安全限制。这种方式不仅能访问内网服务,还可能用于探测端口开放状态、访问云元数据接口,甚至执行远程命令。

攻击路径

在这里插入图片描述

示例

漏洞场景:某网站有一个在线加载功能可以把指定的远程文章加载到本地,链接如下:

http://www.xxx.com/article.php?url=https://blog.csdn.net/qq_43531669/article/details/112498646

假如系统没有对url参数进行任何的检查,就可以构造其他的请求,例如:

http://www.xxx.com/article.php?url=http://127.0.0.1:22
http://www.xxx.com/article.php?url=file:///etc/passwd
http://www.xxx.com/article.php?url=dict://127.0.0.1:22/data:data2 (dict可以向服务端口请求data data2)
http://www.xxx.com/article.php?url=gopher://127.0.0.1:2233/_test (向2233端口发送数据test,同样可以发送POST请求)
...
漏洞形成原理

许多网站为了实现功能,会提供从其他服务器获取数据的接口。例如通过指定的 URL 加载图片、下载文件或读取内容等。当这些接口未对目标地址进行严格校验时,就可能被攻击者利用,从而实现 SSRF。

SSRF 的本质是利用存在漏洞的 Web 应用作为代理,向远程或本地服务器发起请求。由于请求是由服务端发出,因此攻击者可借此访问那些本应只能由内网访问的资源。

该漏洞通常是由于服务端缺乏对目标地址的过滤和访问控制导致的。攻击者可利用该漏洞获取内部系统的信息,或进一步发起内网攻击。

漏洞的危害
  1. 对外网、服务器所在内网、本地进行端口扫描
  2. 向内部任意主机的任意端口发送payload来攻击内网服务
  3. DOS攻击(请求大文件,始终保持连接Keep-Alive Always)
  4. 攻击内网的web应用,如直接SQL注入、XSS攻击等
  5. 利用file、gopher、dict协议读取本地文件、执行命令等
  6. 可以无视网站CDN

内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。

SSRF 攻击

漏洞利用
产生漏洞的函数

根据后端所使用函数的不同,SSRF 漏洞的影响范围和利用方式也有所差异。在 PHP 中,以下函数如果使用不当,可能导致 SSRF 漏洞:

file_get_contents()
fsockopen()
curl_exec()       
file_get_contents()

该函数用于将整个文件内容读入一个字符串中,是读取文件内容的首选方法之一。

例如,以下代码会输出 test.txt 文件中的内容:

<?php
echo file_get_contents("test.txt");
?>
fsockopen()

fsockopen() 函数用于打开一个网络连接,可用于向用户指定的 URL 发起请求(例如获取文件或 HTML 内容)。若传入的地址参数未做限制,也可能被用来发起 SSRF 请求。

curl_exec()

该函数用于执行一个 cURL 会话。当使用 curl_exec() 向外部资源发起请求时,若未对 URL 做严格校验,同样可能被攻击者利用实现 SSRF。

cURL 支持的协议包括但不限于:

  • http / https
  • ftp / ftps
  • file
  • gopher
  • dict
  • ldap
  • telnet
  • smtp

这意味着攻击者可通过构造带有特定协议的 URL 发起跨协议攻击,进一步扩大 SSRF 的危害范围。

漏洞检测
漏洞验证

因为SSRF漏洞是构造服务器发送请求的安全漏洞,所以我们可以通过抓包分析发送的请求是否是由服务器端发送的来判断是否存在SSRF漏洞。

在页面源码中查找访问的资源地址,如果该资源地址类型为http://www.xxx.com/a.php?image=地址就可能存在SSRF漏洞。

漏洞的可能出现点

(1) 分享功能:通过URL地址分享文章等,例如如下地址:

http://share.xxx.com/index.php?url=http://www.xxx.com

通过url参数的获取来实现点击链接的时候跳到指定的分享文章。如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。

(2)图片加载/下载:通过URL地址加载或下载图片:

http://image.xxx.com/image.php?image=http://www.xxx.com

图片加载存在于很多的编辑器中,编辑器上传图片处加载设定好的远程服务器上的图片地址,如果没对加载的参数做限制可能造成SSRF。

(3)图片/文章收藏功能:

http://title.xxx.com/title?title=http://title.xxx.com/xxx

例如 title参数是文章的标题地址,代表了一个文章的地址链接,如果收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。

(4)转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览。

(5)在线翻译:给网址翻译对应网页的内容。

(6)邮件系统:比如接收邮件服务器地址。

(7)利用参数中的关键字查找:

关键字:

share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain...

总的来说,需要从远程服务器请求资源的网站都有可能存在SSRF漏洞。

SSRF攻防

绕过方法
绕过域名限制

有些功能限制只能访问某个固定域名,如 http://www.xxx.com,可使用以下方法绕过:

使用 @ 符号绕过

URL 格式:

[协议]://[用户名]:[密码]@[服务器地址]:[端口]/路径?参数#片段

示例:

http://www.xxx.com@evil.com       # 实际请求的是 evil.com
http://www.aaa.com@www.bbb.com@ccc.com

在不同解析器中效果不同:

PHP parse_url():识别为 ccc.com

libcurl:识别为 bbb.com

绕过内网 IP 限制

有些系统禁止访问内网地址,如 127.0.0.110.0.0.0/8 等,常见绕过方式包括:

1. 使用短网址

例如 https://t.cn/xxxhttps://bit.ly/xxx 等短链重定向。

2. 使用特殊解析域名(xip.io / xip.name)

xip.ioxip.name 支持将子域名自动解析为对应 IP 地址:

127.0.0.1.xip.io
www.10.0.0.2.xip.io
mysite.10.0.0.3.xip.name
foo.bar.192.168.1.1.xip.io
3. 进制绕过
表达方式示例实际地址
十进制整数http://2130706433127.0.0.1
十六进制http://0x7f.0x00.0x00.0x01http://0x7f000001127.0.0.1
八进制http://0177.0.0.1127.0.0.1
八进制溢出http://265.0.0.310.0.0.3
混合进制http://0x0A.00.00.0310.0.0.3
4. 使用 IPv6 简写
http://[::]      # 等价于 http://127.0.0.1
5. 替换句号 . 为类似字符
http://127。0。0。1   # 全角句号
6. 添加端口号
http://127.0.0.1:8080
绕过协议限制

某些系统只允许访问以 http://https:// 开头的 URL,可尝试以下方式:

利用 302 跳转

请求一个合法地址,由其重定向至非法地址:

http://example.com/redirect?url=http://127.0.0.1
使用短地址服务

短地址可隐藏实际协议、IP 等。

正则限制绕过示例(进制)

源代码示例:

if (preg_match('#^https?://#i', $handler) !== 1) {die("Wrong scheme! You can only use http or https!");
} else if (preg_match('#^https?://10.0.0.3#i', $handler) === 1) {die("Restricted area!");
}

被阻止的请求:

http://10.0.0.3

可尝试的绕过方式:

http://0x0A000003          # 十六进制
http://012.0.0.3           # 八进制
http://2130706433          # 十进制
http://0x0A.0x00.0x00.0x03 # 混合进制
绕过方法对照表
绕过目标绕过方式
域名限制@ 符号、短网址、跳转地址
内网 IP 限制进制转换、IPv6、xip.io 域名、句号替换、端口变换
协议限制302 跳转、短地址伪装
防御措施
禁止 URL 跳转
  • 禁止用户控制的 URL 发生 302/301 跳转
  • 对重定向逻辑进行校验,避免跳转到非预期地址。
禁用危险协议
  • 拒绝解析非 HTTP 协议,例如:
    • file://:本地文件读取
    • gopher://:可构造任意 TCP payload
    • dict://:同样可用于投送任意数据包
  • 只允许 http://https:// 协议头通过。
限制端口范围
  • 限制仅允许请求标准 HTTP/HTTPS 端口:
    • 常见端口:80、443、8080
  • 拒绝对内网常用端口访问,例如:
    • Redis:6379
    • MySQL:3306
    • 内网 Web 应用:7001、8888 等
统一错误信息输出
  • 不泄露服务端请求的详细错误信息(如:连接被拒绝、响应超时等)。
  • 所有错误返回统一格式,防止攻击者据此判断端口开放状态或地址是否有效。
地址过滤与白名单校验
  • 使用 白名单机制:只允许访问可信 URL/域名。
  • 检查目标 IP 是否属于以下范围(常见内网地址):
    • 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
  • 使用 IP 解析和反向解析校验,避免利用域名跳转或 DNS 投毒绕过。

参考文献

  1. SSRF漏洞原理解析[通俗易懂]

    https://cloud.tencent.com/developer/article/2103240

  2. SSRF漏洞原理攻击与防御(超详细总结)

    https://blog.csdn.net/qq_43378996/article/details/124050308

相关文章:

  • 重启Eureka集群中的节点,对已经注册的服务有什么影响
  • HDMI 显示器热插拔对应显示应用启停测试
  • 实现弹窗随键盘上移居中
  • 基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
  • 协议转换利器,profinet转ethercat网关的两大派系,各有千秋
  • 【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
  • 论文笔记:Urban Computing in the Era of Large Language Models
  • 基于51单片机的篮球计分器
  • 【第一章:人工智能基础】01.Python基础及常用工具包-(4)Python环境管理
  • REBT 分类任务中,`loss`(损失值)和 `logits`(原始预测分数)是什么
  • 用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
  • SAM2Long本地部署,视频分割处理,绿幕抠像,超长视频支持
  • Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
  • 深度解析云存储:概念、架构与应用实践
  • XMLGregorianCalendar跟Date、localDateTime以及String有什么区别
  • VisualXML全新升级 | 新增数据库编辑功能
  • 【深度学习新浪潮】大模型中,active parameters和total parameters都是什么?
  • rnn判断string中第一次出现a的下标
  • Unity-ECS详解
  • Ubuntu里面单独编译某一个模块
  • 网站制作源码版权/热搜榜上能否吃自热火锅
  • 用asp做的一个网站实例源代码/搜索引擎优化网站排名
  • 机票网站建设/营销培训心得体会
  • 免费网站发布怎么做的/网络关键词优化方法
  • 移动端开发流程/优化推广关键词
  • 中 网站建设 扬州/seo体系百科