寻找和利用 XXE – XML 外部实体注入

在本文中,我们将深入了解如何查找和利用 XML 外部实体注入漏洞

XXE(XML External Entity)顾名思义,是一种与解析 XML 数据的应用程序相关的攻击。根据 XML 标准规范,实体可以被视为一种存储类型。在编程术语中,我们可以将实体视为具有某些值的变量。XML 规范中有两种类型的实体:

内部实体:

根据 XML 标准,内部实体是一个实体,其值被定义为字符串文字。例如,仅指向字符串值的实体可以称为内部实体。它可以定义如下:

<!ENTITY internal
“Internal Entity”>

internal  =变量名称

“Internal Entity” =字符串文字

外部实体:

如果实体不是内部实体,则它是外部实体。外部实体可以定义如下:

<!ENTITY external
SYSTEM|PUBLIC
“http://www.example.com/test.xml”>

外部实体声明包括称为实体的系统标识符的SystemLiteral ( SYSTEM )。当 XML 处理器使用SystemLiteral解析实体时,它会解析 URI 引用 ( http://www.example.com/test.xml ) 以获取 XML 处理器的输入,以将值分配给“外部”变量或任何其他引用在 XML 数据中定义。我们将在 OOB(带外)XXE 开发部分中更详细地讨论这一点。

根据实体的声明方式,实体可以进一步分为通用实体和参数化实体两种类型。

一般实体

一般实体是可以用“ & ”符号引用的实体。声明如下:

<xml version=”1.0″>
<!DOCTYPE html[

    <!ELEMENT bar>

    <!ENTITY foo “this is foo”>

]>

<bar>&foo;</bar>

参数化实体

参数化实体也可用于将值分配给其他实体。参数化实体在声明期间在其名称前有一个百分号' % ',可以引用为%(name); . 参数化实体通常可以在 DTD 声明中找到。百分号“ % ”告诉 XML 处理器它是一个参数化实体,在它被引用的地方插入这个实体的替换值,并将实体的值作为 DTD 的一部分进行解析。在处理 OOB XXE 有效载荷的构造时,我们会看到这样的实体。参数化实体可以定义如下:

<xml version=”1.0″>
<!DOCTYPE html[

    <!ELEMENT bar>

    <!ENTITY foo “this is foo”>

<!ENTITY another ‘%foo;‘>

]>

<bar>&another;</bar>

寻找 XXE 漏洞

由于 XXE 漏洞仅与解析 XML 数据的应用程序相关,因此在测试应用程序是否存在 XXE 漏洞时,主要攻击向量将是应用程序中接受 XML 格式输入的任何功能。查找和确认漏洞还取决于不同的情况,即呈现给我们的应用程序。

案例 1:当解析的 XML 数据在 HTTP 响应中可见时

如果应用程序正在解析 XML 数据并在 HTTP 响应中显示解析 XML 的结果,则测试 XXE 漏洞的基本测试用例将发送使用内部实体的 XXE 有效负载,以确保应用程序是否具有实体。

将以下 PHP 代码另存为xxe.php在 webserver 根文件夹中:

 

向xxe.php文件发送 POST 请求,其中包含以下屏幕截图所示的 XML 数据:

 

观察应用程序在 HTTP 响应中显示用户名,确认它正在解析 XML 数据。

 

现在,让我们向 XML 数据添加一个内部实体,并使用&u;在<username>元素中引用它。并再次发送请求。

 

观察应用程序解析我们的内部实体,成功确认 XXE 漏洞。

 

情况 2:当解析的 XML 数据在 HTTP 响应中不可见时

要模拟在 HTTP 响应中不显示解析 XML 数据的结果的应用程序,我们可以简单地注释掉前面使用的 Php 代码中的echo 语句。注释掉 echo 语句后,我们的 PHP 代码将如下所示。

 

在这种情况下,我们无法仅使用内部实体来确认 XXE 漏洞,因为我们无法确认注入的实体是否正在被应用程序解析。让我们快速测试一下。

我们将简单地发送案例 1中所示的内部实体有效负载。

 

观察应用程序在 HTTP 响应正文中没有显示任何内容。

 

因此,对于这种情况,我们可以使用外部实体来解析我们(攻击者/漏洞测试者)控制的URL 。这样,如果我们收到从易受攻击的服务器到我们服务器的 HTTP 请求,我们就可以确认该漏洞。

我们将使用本地 python 服务器进行演示。但是,您也可以使用任何远程服务器。我们的请求将如下所示:

 

观察应用程序通过向我们在localhost监听端口81的服务器发送 HTTP 请求来解析我们的外部实体。这种将实体解析为已知 URL 的方法称为 OOB(带外)XXE。

 

数据泄露

在本节中,我们将了解如何使用外部实体将一些敏感数据(针对不同情况)从易受攻击的系统中提取出来,以了解该漏洞的整体影响。

案例 1:当解析的 XML 数据在 HTTP 响应中可见时

使用外部实体,我们还可以在分配给易受攻击的应用程序/ XML 解析器的权限的上下文中读取系统文件。如果您可以在 HTTP 响应中看到解析的 XML 数据,这意味着您将能够在 HTTP 响应中看到系统文件的内容,这使得利用变得更加容易。我们将使用与“查找 XXE 漏洞”部分的案例 1中使用的相同的 PHP 代码。

我们使用外部实体读取系统文件的请求如下所示:

 

注意上面的有效载荷;我们在 URL 中滥用协议类型(使用 file:// 而不是 http://)来读取系统文件。

 

情况 2:当解析的 XML 数据在 HTTP 响应中不可见时 (OOB XXE)

这是您在应用程序安全参与期间会遇到的最常见情况。在这种情况下,我们将使用参数化实体来构建我们的有效负载并在此过程中学习一些概念。这里的想法是将文件的内容存储在某个变量中,并在 HTTP 请求中解析该变量以将文件的内容发送到我们的服务器。

让我们逐步构建我们的有效载荷,并了解我们的有效载荷的方式和原因。我们简单地定义了一个文件变量来存储win.ini的内容和一个req变量来将内容发送到我们的服务器。

 

让我们尝试在“查找 XXE 漏洞”部分的案例 2中的易受攻击的 Php 文件中使用此有效负载。我们的请求负载将如下所示:

 

我们从 PHP 解释器收到以下错误,指出我们的 URL 无效。

 

为了克服上述错误,我们使用了一个与外部实体嵌套的内部实体并再次触发了请求。我们的请求负载将如下所示:

 

然而,这次我们得到了一个不同的错误,这仅仅意味着我们不能在内部文档类型声明中引用参数化实体。

 

我们可以通过使用外部 DTD 来克服上述限制。我们在监听localhost:81的服务器上创建了一个xxe.dtd文件,其内容如下:

 

我们使用 XML 有效负载的最终请求将如下所示。有效负载解析对外部 DTD ( %dtd ) 的引用以及 DTD 文件xxe.dtd ( %all;
%req; ) 中定义的引用。

 

观察应用程序解析我们的 DTD 文件以及请求中的所有引用,并发送回win.ini文件的 base64 编码内容,稍后可以对其进行解码以获得原始内容。

来源

  • https://www.w3.org/TR/xml/#wfc-PEinInternalSubset
  • https://www.w3.org/TR/xml
  • https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf

 

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等库,这些库会自动过滤掉外部实体
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值