序列化和反序列化本身是为了实现数据在网络上完整高效的传输,如果序列化的数据再进行了其他的编码,那么将无法进行反序列化,为了代码的简洁,自动调用魔术函数进行解码。但是由于反序列化过程中,对象的魔术方法会自动调用,魔术方法本身调用了别的方法,最终呈现一种链式调用,直到执行任意的代码或者命令。
示例:
<?php
function a(){
b();
}
function b(){
if (@$_GET['cmd']=="zhoaxi")
system("calc");
}
class Person{
public $name;
public $age;
public $sex;
public function __wakeup(){
a();
}
}
$stu1 = new Person();
$stu1->name = "zhoaxi";
$stu1->age = 22;
$stu1->sex = true;
$a = serialize($stu1);
var_dump($a);
echo "<hr>";
$b = unserialize($a);
var_dump($b);
?>
当反序列化语句 $b = unserialize($a);
执行时,系统会自动调用 Person
类中的 __wakeup()
方法, __wakeup()
方法调用 a()
函数,a()
函数调用 b()
函数,b()
函数接受到传参,即可执行系统命令,形成链式调用。
数,b()
函数接受到传参,即可执行系统命令,形成链式调用。