XXE(XML External Entity Injection),即XML外部实体注入。漏洞发生在应用程序解析 XML 输入时,没有禁止外部实体的加载。
XML与DTD的关系
DTD(Document Type Definition)文档类型定义,一种XML约束模式语言,属于XML文件组成的一部分。
|
|
DTD文档有三种应用形式。
内部DTD文档:
|
外部DTD文档:
|
内外部DTD文档结合:
|
XXE漏洞原理——XML实体
实体主要分为四种:
- 内置实体 (Built-in entities)
- 字符实体 (Character entities)
- 通用实体 (General entities)
- 参数实体 (Parameter entities)
注: 完整实体类别可参考 DTD - Entities
其实,XML可分为普通实体和参数实体。
而根据实体声明方式的不同,还分为内部实体和外部实体,XXE利用的是外部实体。
普通实体引入外部实体
|
|
参数实体引入外部实体
|
|
注:外部资源的URI主要支持file、http、https、ftp等协议,对不同的程序所支持的协议不同。
XXE漏洞类型与危害
I.任意文件读取
通过外部实体引用,实现任意文件读取。
II.URL请求,SSRF
- 端口扫描,探测内网服务
- 内网攻击get型payload,如st2命令执行、discuz ssrf通过redis实施getshell;指纹识别等等
- DoS拒绝服务:通过实体的递归调用,占用大量服务器资源。
III.远程代码执行
在php开启expect扩展的前提下
|
|
XXE漏洞本地测试
任意文件读取
构造index.html
、func.php
和test.txt
。index.html
构造表单,并转换成XML字符串,发送到func.php
转化成XML对象,并输出数据。
|
|
|
|
输入数据点击提交,利用burpsuite进行抓包:
修改XML数据,发包,可读取到test.txt
的数据:
利用参数实体取得间接回显
对于传统的XXE来说,要求攻击者只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,如果没有回显则可以使用Blind XXE漏洞来构建一条带外信道提取数据。
- 客户端发送payload1给Web服务器
- Web服务器向VPS获取恶意DTD,并执行文件读取payload2
- Web服务器带着回显结果访问VPS上特定FTP或者HTTP
- 黑客通过VPS获得回显
服务器中构造index.php
、xxe.xml
和flag.txt
。VPS中构造evil.xml
、recv.php
和data.txt
。其中flag.txt
为要读取的数据,然后存入data.txt
中。
|
|
|
|
|
|
|
|
访问服务器的index.php
,服务器将去请求VPS上的evil.xml
并执行,带上flag.txt
经过base64加密后的内容
去请求VPS上的recv.php
,于是将base64解码后的数据存入了data.txt
。完成间接回显。
注:若flag.txt
的读取不采用php://filter
,则当文件内容包含空格换行等,将导致recv.php
请求失败。
XXE的防御
- 禁用外部实体
- 过滤和验证用户提交的XML数据
- 不允许XML中含有任何自己声明的DTD
- 禁止外来引入,如在php中可设置
libxml_disable_entity_loader(true)