开始之前先讲一讲什么是序列化和反序列化
- 序列化
将对象的状态信息转换为可以存储或传输的形式 - 反序列化
把字节序列转化为对象的过程 - PHP反序列化漏洞
PHP5 < 5.6.25
PHP7 < 7.0.10
PHP官方给了示例:https://bugs.php.net/bug.php?id=72663
这个漏洞核心:序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行
- 例题:
用XCTF上的一道题来讲解PHP反序列化漏洞
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
审计代码后,我们可以知到xctf这个类正常序列化结果为
O:4:"xctf":1:{s:4:"flag";s:3:"111";}
O代表结构类型为:类,4表示类名长度,接着是类名、属性(成员)个数 大括号内分别是:属性名类型、长度、名称;值类型、长度、值
根据代码中的?code= 可得知,将得到的序列化字符串赋值给code进行传递。
我们在浏览器地址输入正常序列化结果进行尝试,发现在反列化时会自动调用__wakeup()函数。
利用反序列化漏洞,修改成员个数
O:4:"xctf":9:{s:4:"flag";s:3:"111";}
再次尝试,获得flag
序列化漏洞常见的魔法函数
construct():当一个类被创建时自动调用 destruct():当一个类被销毁时自动调用
invoke():当把一个类当作函数使用时自动调用 tostring():当把一个类当作字符串使用时自动调用
wakeup():当调用unserialize()函数时自动调用 sleep():当调用serialize()函数时自动调用
__call():当要调用的方法不存在或权限不足时自动调用
部分内容摘自 https://blog.youkuaiyun.com/nzjdsds/article/details/82703639