0x00 背景
近期看到OWASP TOP 10 2017 版中添加了XXE的内容便对XXE的一些知识进行梳理和总结,XXE可以使用例如http,file等协议,所以可以利用支持的协议进行内网探测和内网入侵,这部分的内容后续在SSRF中补充。
要点:libxml2.9.1及以后,默认不解析外部实体。测试的时候window下使用的是php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。Linux中需要将libxml低于libxml2.9.1的版本编译到PHP中,可以使用phpinfo()查看libxml的版本信息。
参考链接:
http://vulhub.org/#/environments/php_xxe/
有回显有报错测试代码:
无回显无报错测试代码:
0x01 DTD的基础知识
概念:
XXE:XML External Entity 即外部实体,从安全角度理解成XML External Entity attack 外部实体注入攻击。
DTD:Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上XML Schema。
参考链接:http://www.w3school.com.cn/dtd/
首先了解下基本的PAYLOAD结构,然后再介绍每部分涉及的知识点,如下PAYLOAD开头进行了XML的声明,然后使用DTD声明实体(这里使用了file协议),最后使用XML获取实体的数据。
基本的PAYLOAD结构:
使用DTD实体的攻击方式:
DTD引用方式(简要了解):
1. DTD内部声明
2. DTD外部引用
3.引用公共DTD
示例:
DTD实体声明(重点学习):
1.内部实体声明
一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在GET还是在POST中都需要进行URL编码,因为是使用参数传入xml的,&符号会被认为是参数间的连接符号,示例:
2.外部实体声明
外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:
示例:
3.参数实体声明
示例:
外部evil.dtd中的内容。
4.引用公共实体
0x02 XXE的利用方式-DTD
使用DTD的利用方式
利用xxe漏洞可以进行拒绝服务攻击,文件读取,命令(代码)执行,SQL(XSS)注入,内外扫描端口,入侵内网站点等,内网探测和入侵是利用xxe中支持的协议进行内网主机和端口发现,可以理解是使用xxe进行SSRF的利用,基本上啥都能做了:-)
一般xxe利用分为两大场景:有回显和无回显。有回显的情况可以直接在页面中看到Payload的执行结果或现象,无回显的情况又称为blind xxe,可以使用外带数据通道提取数据。
1.有回显情况:
有回显的情况可以使用如下的两种方式进行XXE注入攻击。
外部evil.dtd中的内容。
当然也可以进行内网站点的入侵(属于SSRF的内容 后续补充)。
2.无回显的情况:
可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。
evil.dtd的内容,内部的%号要进行实体编码成%。
有报错直接查看报错信息。
无报错需要访问接受数据的服务器中的日志信息,可以看到经过base64编码过的数据,解码后便可以得到数据。
XXE的拓展知识
0x01 xmlns的基本知识
接下来说一些拓展的知识,这些攻击方式,需要有某些条件才能正常利用,下文仅对互联网上的一些知识进行梳理,暂未验证。
概念:
XML Schema:称为可扩展标记语言架构,用来定义 XML 文档的合法构建模块,类似 DTD,Schema是DTD的替代者, 它比DTD可以做更多的事情 。
参考链接:
http://www.w3school.com.cn/schema/schema_intro.asp
先说下xmlns,当有多个文档被一起使用时候不同文档可能带有不同内容和定义名称相同的元素,这样就会发生命名冲突,XML解释器无法确定如何处理这类冲突,而xmlns可以解决这个问题,我们为标签添加了一个 xmlns 属性,这样就为前缀赋予了一个与某个命名空间相关联的限定名称。此时再把它们放在一起,XML解析器就不会报错了。
语法:xmlns=”namespaceURI”表示默认的Namespace,可以不使用前缀;非默认的便需要使用前缀避免XML报错。 xmlns:namespace-prefix=”namespaceURI”,其中namespace-prefix为自定义前缀,只要在这个XML文档中保证前缀不重复即可;namespaceURI是这个前缀对应的XML Namespace的定义,如下例子中的xmlns:xsi表示使用xsi作为前缀的Namespace。
xsi:schemaLocation属性便是Namespace为http://www.w3.org/2001/XMLSchema-instance里的schemaLocation属性。xsi:schemaLocation定义了XML Namespace和对应的 XSD(Xml Schema Definition)文档的位置的关系。它的值由一个或多个URI引用对组成,两个URI之间以空白符分隔(空格和换行均可)。第一个URI是定义的 XML Namespace的值,第二个URI给出Schema文档的位置,Schema处理器将从这个位置读取Schema文档,文档的targetNamespace必须与第一个URI相匹,具体内容如下所示:
0x02使用XML Schema实体的攻击方式
XML Schema攻击的分类
根据FB的小编对外文的翻译,得知XML Schema攻击分为:
1.schemaLocation
2.noNamespaceSchemaLocation
3.XInclude。
4.XSLT 攻击
1. schemaLocation
在OWASP 的XML External Entity Attacks(XXE)议题中有看到这这个知识点,但是具体的案例并未找到,FB给出了如下的示例。
2. noNamespaceSchemaLocation
与schemaLocation一样,在OWASP 的XML External Entity Attacks(XXE)议题中有看到这个知识点,但是具体的案例并未找到,FB给出了如下的示例,也给出了SSRF的示例,但是在示例中总觉得有些诡异,这也是我疑惑的地方。
3. XInclude
XInclude在XML Schema, DTD, and Entity Attacks 的文档中有提到,但是经过测试和查阅材料,在微软的将 XML 文档与 XInclude 合并在一起这篇文档中有提到并不是所有XML 语法分析程序都支持 XInclude,W3C在XInclude Implementations Report中列出了支持的列表,include的href属性中可以进行文件读取,也可以使用协议进行SSRF,freebuf中是使用DTD实体的方式再结合XInclude进行利用的,似乎觉得有些不大贴切,因为如果可以使用XInclude的话那么就不需要使用DTD了,直接在href属性中利用协议获取信息,即可;但是FB这种在属性处使用&internal;的思路值得借鉴。
XML Schema, DTD, and Entity Attacks中的示例:
freebuf的示例,如下所示:
以上示例中external_entity_attribute.dtd文件的内容,根据示例中的参数实体payload的声明,在此处应该可以使用各种协议进行SSRF等操作。
4. XSLT攻击
这个攻击方式在XML Out-Of-Band Data Retrieval有提到,可以通过如下的方式先用document()获得目标主机的信息,然后使用concat()将数据与evil主机进行拼接,然后document()访问拼接后的地址,便可以在evil主机日志上获得信息。
XSL中document() 用于访问外部 XML 文档中的节点;concat(string,string,…)用于返回字符串的拼接。
0x03总结
互联网上XXE的文章还是很多的,所以先进行知识的梳理,方便学习和提高,本文参考了互联网上各个师傅和前辈的文章进行总结和梳理,在拓展部分的知识还有许多地方还未进行实践和验证,仅是先做个记录方便后续完善和测试,大家如果已经复现过了或者有更好场景,期待一起交流,如下是撰写本文的参考链接。
通往白帽子的奇妙世界
领取专属 10元无门槛券
私享最新 技术干货