可扩展标记语言(英語:Extensible Markup Language,简称:XML)是一种标记语言。 标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。如图所示:
xxe漏洞与DTD文档相关。
文档类型定义(DTD)可定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于XML文档中(内部引用),也可作为一个外部引用。
内部声明DTD:
引用外部DTD:
DTD文档中重要的关键字如下:
DOCTYPE(DTD的声明)
ENTITY(实体的声明)
SYSTEM、PUBLIC(外部资源申请)
实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。
实体按类型主要分为以下四种:
内置实体 (Built-in entities)
字符实体 (Character entities)
通用实体 (General entities)
参数实体 (Parameter entities)
实体根据引用方式,还可分为内部实体与外部实体。
内部实体:
外部实体:
参数实体:
或者
参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。
实例演示:除参数实体外实体+内部实体
]>
&name;
实例演示:参数实体+外部实体
%name;
]>
注意:%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。
实例:外部实体
]>
&content;
xxe漏洞主要是利用了DTD引用外部实体导致的漏洞
XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,允许引用外部实体,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
先检测是否解析XML
]>
&name;
如果页面输出了Hello,hacker!,说明xml文件可以被解析。
然后检测服务器是否支持DTD引用外部实体:
%name;
]>
可通过查看自己服务器上的日志来判断,看目标服务器是否向你的服务器发了一条请求test.xml的请求。
xml version="1.0"?>
]>
XML内容:
xml version="1.0"?>
%d;
&b;
DTD文件(evil.dtd)内容:
XML内容:
xml version="1.0"?>
DTD文件(evil.dtd)内容:
xmL version="1.0"?>
& xxe;
EOF;
$data=simplexml_load_string($xml);
print_r($data);
xml version="1.0"?>
& xxe;
EOF; Sdata=simplexml_1oad_string($xml); print_r($data);
该例子是探测192.168.1.1的80、81端口,通过返回的“Connection refused”可以知道该81端口是closed的,而80端口是open的。
抓包发现客户端以json形式发送了数据,服务端返回了客户端的内容
]>
&file;
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))
过滤关键词:
参考资料:https://security.tencent.com/index.php/blog/msg/69
https://thief.one/2017/06/20/1/