XXE漏洞基本原理及防御

admin 2025-12-22 04:23:51 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: XXE漏洞是一种XML外部实体注入漏洞,攻击者通过构造恶意XML数据引入外部实体,导致信息泄露、服务器端请求伪造等危害。漏洞原理是XML解析器配置不当和输入校验缺失。复现包括读取任意文件、查看PHP源代码和SSRF联动。防御方法是配置XML解析器不允许外部实体,并过滤敏感关键字如ENTITY、SYSTEM、PUBLIC。 综合评分: 88 文章分类: WEB安全,漏洞分析,渗透测试,实战经验


cover_image

XXE漏洞基本原理及防御

原创

dcnb

Web安全基础与实践

2025年12月14日 21:00 广东

XXE漏洞,全称为XML External Entity Injection,即XML外部实体注入漏洞。这是一种因应用程序对XML输入解析不当,导致攻击者可通过构造恶意XML数据引入外部实体,进而实现信息泄露、服务器端请求伪造等攻击的安全漏洞,多出现于处理XML格式数据的应用场景中(如API接口、文件上传解析、数据交换等)。

XXE漏洞允许攻击者干扰应用程序对XML数据的处理。它通常允许攻击者查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。在某些情况下,攻击者可以利用XXE漏洞联合执行服务器端请求伪造(SSRF)攻击,提高XXE攻击等级。

1XML介绍

XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,具有可扩展性,其核心设计目标为数据的可移植性和互操作性,被广泛应用于不同系统间的数据交换。与HTML侧重数据展示不同,XML专注于数据的结构定义和内容描述。XML文档的结构通常包括声明、元素、属性、实体等部分。下面我们介绍一个标准的XML文档的核心组成部分。

1.1 声明

XML声明位于文档最开头,用于指定XML文档的版本和编码格式,是可选但推荐添加的部分,语法格式如下:

<?xml version="1.0"&nbsp;encoding="UTF-8"?>

其中version为指定XML版本,主流版本为1.0;encoding为指定文档编码,如UTF-8、GBK等。

1.2 文档类型定义

用于定义XML文档的结构规则(如元素、属性、实体等),可分为内部DTD和外部DTD,XXE漏洞就出现在此处。

(1)内部DTD

直接在文档内部定义规则内容,如下为内部DTD示例:

<!DOCTYPE&nbsp;users&nbsp;[&nbsp;&nbsp;<!ELEMENT&nbsp;users&nbsp;(user+)>&nbsp;<!-- users 元素包含一个或多个 user 元素 -->&nbsp;&nbsp;<!ELEMENT&nbsp;user&nbsp;(name,&nbsp;age,&nbsp;address)>&nbsp;<!-- user 元素包含 name、age、address 子元素 -->&nbsp;&nbsp;<!ELEMENT&nbsp;name&nbsp;(#PCDATA)>&nbsp;<!-- name 元素内容为文本数据 -->&nbsp;&nbsp;<!ATTLIST&nbsp;user&nbsp;id&nbsp;CDATA&nbsp;#REQUIRED>&nbsp;<!-- user 元素的 id 属性为必填文本 -->]>

(2)外部DTD

通过外部文件引入规则,如下为外部DTD示例:

<!DOCTYPE&nbsp;users&nbsp;SYSTEM&nbsp;"users.dtd">&nbsp;<!-- 引入本地外部 DTD 文件 --><!DOCTYPE&nbsp;users&nbsp;PUBLIC&nbsp;"-//XXX//DTD User Data//EN"&nbsp;"http://xxx.com/users.dtd">&nbsp;<!-- 引入公共外部 DTD -->

1.3 根元素

XML文档必须有且仅有一个根元素,所有其他元素都是根元素的子元素或后代元素。在1.2的示例中,就是根元素。

1.4 元素与属性

(1)元素

XML文档的核心内容载体,由开始标签、结束标签和内容组成,空元素可简写为。元素需遵循命名规则:不能以数字开头、不能包含空格和特殊字符(除下划线_,连字符-,冒号:)。如下为元素的示例:

<websec>&nbsp; &nbsp;&nbsp;<title>XXE漏洞</title></websec>

其中为开始标签,为结束标签。

(2)属性

用于为元素提供额外信息,以“键值对”的形式嵌入开始标签中。一个元素可包含多个属性,但属性名不能重复。如下为元素中嵌入属性的示例:

<websec&nbsp;id="1">&nbsp; &nbsp;&nbsp;<title>XXE漏洞</title></websec>

其中id就是属性。

1.5 实体

实体是XML中的一种“占位符”,用于引用数据,可以理解为XML中的“变量”,分为内部实体和外部实体。

(1)内部实体

实体的值直接在XML文档内部定义,仅在当前文档中生效。如下为内部实体的示例:

<?xml version="1.0"&nbsp;encoding="UTF-8"?><!DOCTYPE&nbsp;websec&nbsp;[&nbsp;&nbsp;<!ENTITY&nbsp;internalEntity&nbsp;"xml">]><websec>&nbsp;&nbsp;<content>&internalEntity;</content>&nbsp;<!-- 引用内部实体 --></websec>

在解析后,&internalEntity;会被替换为xml。

(2)外部实体

实体的值通过外部资源(如文件、网络地址)引入,需要通过SYSTEM关键字指定资源路径。外部实体的引入是XXE漏洞产生的核心载体。如下为外部实体的示例:

<?xml version="1.0"&nbsp;encoding="UTF-8"?><!DOCTYPE&nbsp;websec&nbsp;[&nbsp;&nbsp;<!ENTITY&nbsp;externalEntity&nbsp;SYSTEM&nbsp;"file:///etc/passwd">&nbsp;<!-- 引用外部文件 -->]><websec>&nbsp;&nbsp;<content>&externalEntity;</content>&nbsp;<!-- 引用外部实体 --></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"?>&nbsp;<!DOCTYPE&nbsp;ANY&nbsp;[ &nbsp; &nbsp;<!ENTITY&nbsp;xxe&nbsp;""&nbsp;>&nbsp;]>&nbsp;<a>&xxe;</a>

如图7所示,页面返回websec,可知存在回显。

图7  判断回显结果页面

这样我们就可以尝试读取一些敏感目录信息,如c:/windows/win.ini。我们构造如下payload尝试读取:

<?xml version="1.0"?><!DOCTYPE&nbsp;ANY&nbsp;[&nbsp; &nbsp; &nbsp;<!ENTITY&nbsp;xxe&nbsp;SYSTEM&nbsp;"file:///c:/windows/win.ini">&nbsp;]><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&nbsp;ANY&nbsp;[&nbsp; &nbsp; &nbsp;<!ENTITY&nbsp;xxe&nbsp;SYSTEM&nbsp;"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漏洞基本原理及防御》

评论:0   参与:  2