XML外部实体(XXE)注入
Last updated
Last updated
在本节中,我们将讲解什么是XML外部实体注入,描述一些常见示例,解释如何发现和利用各种XXE注入,并总结如何防范XXE注入攻击。
XML外部实体注入(也称为XXE)是一种Web安全漏洞,允许攻击者干扰应用程序对XML数据的处理。它通常允许攻击者查看应用服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。
在某些情况下,攻击者可以利用XXE漏洞将XXE攻击升级,从而威胁底层服务器或其他后端基础设施,并实施服务器端请求伪造(SSRF)攻击。
Labs
如果你已经熟悉XXE漏洞背后的基本概念,并且只想在一些真实的、故意易受攻击的目标上练习利用它们,你可以从下面的链接访问本主题中的所有实验。
一些应用程序使用XML格式在浏览器和服务器之间传输数据。这样的应用程序基本都是使用标准库或平台API来处理服务器上的XML数据。XXE漏洞之所以产生,是因为XML规范包含各种潜在的危险特性,而标准解析器也支持这些特性,即使应用程序通常不使用这些特性。
阅读更多
XML外部实体是一种自定义的XML实体,其定义的值是从声明它们的DTD之外加载。从安全角度来看,外部实体尤其有趣,因为它们允许根据文件路径或URL的内容定义实体。
XXE攻击有多种类型:
利用XXE检索文件,其中定义了一个包含文件内容的外部实体,并在应用程序的响应中返回。
利用XXE实施SSRF攻击,其中外部实体是基于后端系统的URL定义的。
利用盲XXE带外渗出数据,即将敏感数据从应用服务器传输到攻击者控制的系统。
利用盲XXE通过错误信息检索数据,攻击者可以触发一个包含敏感数据的解析错误信息。
要实施从服务器文件系统检索任意文件的XXE注入攻击,你需要以两种方式修改提交的XML:
引入(或编辑)一个DOCTYPE
元素,该元素定义了一个包含文件路径的外部实体。
编辑应用程序响应中返回的XML中的数据值,以使用定义的外部实体。
例如,假设一个购物应用程序通过向服务器提交以下XML来检查产品的库存水平:
该应用程序对XXE攻击没有特别的防御措施,因此你可以提交以下XXE有效负载,利用XXE漏洞来检索/etc/passwd
文件:
这个XXE有效负载定义了一个外部实体&xxe;
,其值为/etc/passwd
文件的内容,并在productId
值中使用了该实体。这将导致应用程序的响应包含文件的内容:
注意
在真实的XXE漏洞中,提交的XML中通常会有大量的数据值,其中任何一个都可能会在应用程序的响应中使用。为了系统地测试XXE漏洞,通常需要分别测试XML中的每个数据节点,通过使用你定义的实体并查看它是否出现在响应中。
LAB
除了检索敏感数据外,XXE攻击的另一个主要影响是,它们可以被用来实施服务器端请求伪造(SSRF)。这是一个潜在的严重漏洞,可诱使服务器端应用程序向服务器可以访问的任何URL发起HTTP请求。
要利用XXE漏洞实施SSRF攻击,你需要使用你想攻击的URL定义一个外部XML实体,并在数据值中使用该实体。如果可以在应用程序响应中返回的数据值内使用已定义的实体,那么你就能够在应用程序响应中查看来自URL的响应,从而获得与后端系统的双向交互。否则,就只能实施盲SSRF攻击(仍有可能造成严重后果)。
在下面的XXE示例中,外部实体将导致服务器向组织基础设施内的内部系统发起后端HTTP请求:
LAB
很多XXE漏洞都是不可见的。这意味着应用程序在其响应中不返回任何已定义的外部实体的值,因此无法直接检索服务器端文件。
尽管如此,盲XXE漏洞仍然可以被检测和利用,只是需要更高级的技术。有时,你可以使用带外技术发现漏洞并利用它们来外泄数据。有时还可以触发XML解析错误,从而导致在错误信息中泄漏敏感数据。
阅读更多
在很多情况下,XXE注入漏洞的攻击面是显而易见的,因为应用程序的正常HTTP流量包括包含XML格式数据的请求。在其他情况中,攻击面则不那么明显。不过,只要在正确的地方寻找,你就能在不包含任何XML的请求中发现XXE攻击面。
一些应用程序接收客户端提交的数据,在服务器端将其嵌入到XML文档中,然后解析该文档。一个例子是当客户端提交的数据被放入到后端SOAP请求,然后由后端SOAP服务进行处理。
在这种情况下,你无法实现一个典型的XXE攻击,因为你无法控制整个XML文档,不能定义或修改DOCTYPE
元素。不过,你也许可以使用XInclude
。XInclude
是XML规范的一部分,它允许从子文档构建XML文档。你可以在XML文档的任何数据值中植入XInclude
攻击,因此在你仅控制一个被放置到服务器端XML文档中的数据项的情况下,也可以实施攻击。
要实施XInclude
攻击,你需要引用XInclude
命名空间,并提供你希望包含的文件的路径。例如:
LAB
一些应用程序允许用户上传文件,这些文件随后在服务器端被处理。有些常见的文件格式使用XML或包含XML子组件。基于XML格式的示例包括DOCX办公文档格式和SVG图像格式。
例如,一个应用程序可能允许用户上传图像,并在上传后在服务器上处理或验证这些图像。即使应用程序期望接收的是PNG或JPEG的格式,但所使用的图像处理库可能支持SVG图像。由于SVG格式使用XML,攻击者可以提交恶意SVG图像,从而达到XXE漏洞的隐藏攻击面。
LAB
大多数POST请求使用由HTML表单生成的默认内容类型,如application/x-www-form-urlencoded
。有些网站期望接收这种格式的请求,但也允许接受其他内容类型,包括XML。
如果一个正常的请求包含以下内容:
那么你可以提交以下请求,得到同样的结果:
如果应用程序允许在消息正文中包含XML的请求,并解析消息正文内容为XML,那么你只需将请求重新格式化为XML格式,就能达到隐藏的XXE攻击面。
绝大多数XXE漏洞都可以通过Burp Suite的Web漏洞扫描器快速可靠地找到。
手动测试XXE漏洞一般包括:
通过定义一个基于已知操作系统文件的外部实体,并将该实体用于应用程序响应返回的数据中,从而测试文件检索。
测试盲XXE漏洞可以根据你所控制的系统的URL定义一个外部实体,并监视与该系统的交互。Burp Collaborator对此非常适合。
通过使用XInclude攻击尝试检索已知的操作系统文件,测试服务器端XML文档中是否容易包含用户提供的非XML数据。
注意
请记住,XML只是一个数据传输格式。确保还测试了任何基于XML的功能是否存在其他漏洞,如XSS和SQL注入。你可能需要使用XML转义序列对有效载荷进行编码,以避免破坏语法,但你也可以使用这种方式来混淆你的攻击,以绕过薄弱的防御。
几乎所有的XXE漏洞都是因为应用程序的XML解析库支持了一些可能带来危险的XML特性,而应用程序本身并不需要或打算使用这些特性。防范XXE攻击最简单有效的方法就是禁用这些特性。
通常,禁用外部实体的解析和禁用对XInclude
的支持就足够了。一般可以通过配置选项或编程方式覆盖默认行为来实现。有关如何禁用不必要功能的细节,请参阅你的XML解析库或API的文档。
阅读更多