两道php反序列化题目分析
2025-03-07
2 min read
经典反序列化
<?php
error_reporting(1);
class Read {
public $var;
public function file_get($value)
{
$text = base64_encode(file_get_contents($value));
return $text;
}
/**
* 尝试将$read()当作函数调用时会触发这个方法
* @return [type] [description]
*/
public function __invoke(){
$content = $this->file_get($this->var);
echo $content;
}
}
class Show
{
public $source;
public $str;
//此处可以触发__toString方法
public function __construct($file='index.php')
{
$this->source = $file;
echo $this->source.'Welcome'."<br>"; //此处有字符串拼接
}
/**
* 假设这里可以触发__get方法,怎么触发__toString方法
*/
public function __toString()
{
$this->str['str']->source;
}
public function _show()
{
if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) {
die('hacker');
} else {
highlight_file($this->source); //其实这里也可以读文件但是好像没什么乱用
}
}
public function __wakeup()
{
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test
{
/**
* 将$p覆盖为read 就能触发Read类的__invoke方法,如何触发__get方法
*/
public $p;
public function __construct()
{
$this->p = array();
}
public function __get($key)
{
$function = $this->p;
return $function();
}
}
if(isset($_GET['hello']))
{
unserialize($_GET['hello']);
}
else
{
$show = new Show('index.php');
$show->_show();
}
这道题还是在上大学的时候做的了,现在回过头来看,其中一个比较隐藏的点:
public function __construct($file='index.php')
{
$this->source = $file;
echo $this->source.'Welcome'."<br>"; //此处有字符串拼接
}
因为有字符串拼接,所以可以触发 __toString()
方法
另外一个惊喜则是deepseek