文章总结: XXE漏洞是一种XML外部实体注入漏洞,攻击者通过构造恶意XML数据引入外部实体,导致信息泄露、服务器端请求伪造等危害。漏洞原理是XML解析器配置不当和输入校验缺失。复现包括读取任意文件、查看PHP源代码和SSRF联动。防御方法是配置XML解析器不允许外部实体,并过滤敏感关键字如ENTITY、SYSTEM、PUBLIC。 综合评分: 88 文章分类: WEB安全,漏洞分析,渗透测试,实战经验
XXE漏洞基本原理及防御
原创
dcnb
Web安全基础与实践
2025年12月14日 21:00 广东
XXE漏洞,全称为XML External Entity Injection,即XML外部实体注入漏洞。这是一种因应用程序对XML输入解析不当,导致攻击者可通过构造恶意XML数据引入外部实体,进而实现信息泄露、服务器端请求伪造等攻击的安全漏洞,多出现于处理XML格式数据的应用场景中(如API接口、文件上传解析、数据交换等)。
XXE漏洞允许攻击者干扰应用程序对XML数据的处理。它通常允许攻击者查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。在某些情况下,攻击者可以利用XXE漏洞联合执行服务器端请求伪造(SSRF)攻击,提高XXE攻击等级。
1、XML介绍
XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,具有可扩展性,其核心设计目标为数据的可移植性和互操作性,被广泛应用于不同系统间的数据交换。与HTML侧重数据展示不同,XML专注于数据的结构定义和内容描述。XML文档的结构通常包括声明、元素、属性、实体等部分。下面我们介绍一个标准的XML文档的核心组成部分。
1.1 声明
XML声明位于文档最开头,用于指定XML文档的版本和编码格式,是可选但推荐添加的部分,语法格式如下:
<?xml version="1.0" encoding="UTF-8"?>
其中version为指定XML版本,主流版本为1.0;encoding为指定文档编码,如UTF-8、GBK等。
1.2 文档类型定义
用于定义XML文档的结构规则(如元素、属性、实体等),可分为内部DTD和外部DTD,XXE漏洞就出现在此处。
(1)内部DTD
直接在文档内部定义规则内容,如下为内部DTD示例:
<!DOCTYPE users [ <!ELEMENT users (user+)> <!-- users 元素包含一个或多个 user 元素 --> <!ELEMENT user (name, age, address)> <!-- user 元素包含 name、age、address 子元素 --> <!ELEMENT name (#PCDATA)> <!-- name 元素内容为文本数据 --> <!ATTLIST user id CDATA #REQUIRED> <!-- user 元素的 id 属性为必填文本 -->]>
(2)外部DTD
通过外部文件引入规则,如下为外部DTD示例:
<!DOCTYPE users SYSTEM "users.dtd"> <!-- 引入本地外部 DTD 文件 --><!DOCTYPE users PUBLIC "-//XXX//DTD User Data//EN" "http://xxx.com/users.dtd"> <!-- 引入公共外部 DTD -->
1.3 根元素
XML文档必须有且仅有一个根元素,所有其他元素都是根元素的子元素或后代元素。在1.2的示例中,
1.4 元素与属性
(1)元素
XML文档的核心内容载体,由开始标签、结束标签和内容组成,空元素可简写为
<websec> <title>XXE漏洞</title></websec>
其中
(2)属性
用于为元素提供额外信息,以“键值对”的形式嵌入开始标签中。一个元素可包含多个属性,但属性名不能重复。如下为元素中嵌入属性的示例:
<websec id="1"> <title>XXE漏洞</title></websec>
其中id就是属性。
1.5 实体
实体是XML中的一种“占位符”,用于引用数据,可以理解为XML中的“变量”,分为内部实体和外部实体。
(1)内部实体
实体的值直接在XML文档内部定义,仅在当前文档中生效。如下为内部实体的示例:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE websec [ <!ENTITY internalEntity "xml">]><websec> <content>&internalEntity;</content> <!-- 引用内部实体 --></websec>
在解析后,&internalEntity;会被替换为xml。
(2)外部实体
实体的值通过外部资源(如文件、网络地址)引入,需要通过SYSTEM关键字指定资源路径。外部实体的引入是XXE漏洞产生的核心载体。如下为外部实体的示例:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE websec [ <!ENTITY externalEntity SYSTEM "file:///etc/passwd"> <!-- 引用外部文件 -->]><websec> <content>&externalEntity;</content> <!-- 引用外部实体 --></websec>
在解析后,&externalEntity;会被替换为/etc/passwd文件中的内容。
1.6 注释
用于添加说明性文字,不参与数据解析,如下为注释格式示例:
<!-- 这是XML注释示例 -->
2、XXE漏洞原理
XXE漏洞的本质是应用程序使用的XML解析器启用了外部实体加载功能,且未对用户输入的XML数据进行严格的校验。在解析时未对XML外部实体加以限制,导致攻击者将恶意代码注入到XML中,导致服务器加载恶意的外部实体引发文件读取、SSRF、命令执行等危害操作。具体包含两个关键条件:
(1)解析器配置不当:XML解析器默认或被配置为允许处理外部实体,例如Java的DocumentBuilder等解析器,若未关闭外部实体解析,就可能存在风险。
(2)输入校验缺失:应用程序接收用户可控的XML数据(如用户提交的表单、API请求体)时,未过滤文档类型定义中的恶意实体声明,导致攻击者可构造包含危险外部实体的XML数据提交给服务器。
3、XXE漏洞复现
本文在Windows10攻击机环境中进行XXE漏洞的复现。下面我们结合pikachu靶场的XXE漏洞模块进行模拟实际环境下的复现。
pikachu靶场的下载链接:https://github.com/zhuifengshaonianhanlu/pikachu。下载zip压缩包,如图1所示。
图1 pikachu压缩包下载
接着我们打开phpstudy,启动Apache和MySQL,如图2所示。
图2 phpstudy界面
我们将先前下载好的pikachu压缩包解压至WWW目录下,如图3所示。
图3 压缩包解压
打开pikachu/inc目录下的config.inc.php,如图4所示。对配置文件进行修改,如图5所示。
图4 pikachu配置文件地址
图5 配置文件修改
完成上述步骤,靶场配置完成。接着访问靶场地址:http://127.0.0.1/pikachu/install.php,进行靶场初始化,如图6所示。
图6 pikachu靶场初始化
3.1读取任意文件
下面我们选择XXE模块进行漏洞演示。我们首先输入如下payload判断是否存在回显。
<?xml version="1.0"?> <!DOCTYPE ANY [ <!ENTITY xxe "" > ]> <a>&xxe;</a>
如图7所示,页面返回websec,可知存在回显。
图7 判断回显结果页面
这样我们就可以尝试读取一些敏感目录信息,如c:/windows/win.ini。我们构造如下payload尝试读取:
<?xml version="1.0"?><!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]><a>&xxe;</a>
如图8所示,页面返回了c:/windows/win.ini的相关信息。如果想要访问其它文件目录,只需改变绝对路径进行访问。
图8 构造payload访问目录的回显
3.2查看php源代码
首先我们在WWW目录下创建一个php文件,内容随意,用于复现XXE漏洞的php源代码查看,如图9所示。
图9 创建php文件
查看php源代码我们可以使用php伪协议php://filter来构造payload:
<?xml version="1.0"?><!DOCTYPE ANY [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=C:/websec/phpstudy_pro/WWW/websec.php"> ]><a>&xxe;</a>
如图10所示,输入上述payload后返回了一串base64字符。
图10 查看php源代码回显
经过解码可以得到与我们所创建的php文件中一样的内容,如图11所示。
图11 回显内容解码
3.3 SSRF联动
在实际场景中,还可以利用XXE漏洞与SSRF(服务端请求伪造)漏洞联动用于探测其他内网主机的信息。
4、XXE漏洞防御
XXE漏洞的存在是因为XML解析器解析了用户发送的危险数据。绝大多数解析器默认是可以解析外部实体的,它们对XXE漏洞攻击是十分脆弱的。因此,对于XXE漏洞最好的解决办法是配置XML解析器,不允许XML中含有用户自己声明的DTD,只允许使用本地的静态DTD。通过这样的方式,XML外部实体攻击就能被阻止。
此外,还可以对XML输入中的ENTITY、SYSTEM、PUBLIC等可能导致XXE漏洞的敏感关键字进行过滤操作,避免用户构造恶意实体声明。
本文由刘嘉奕同学投稿。
- END –
查看原文:《XXE漏洞基本原理及防御》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论