前言
- 考点:序列化与反序列化
- 序列化:将对象的状态信息转换为可以存储或传输的形式的过程,简单来说,就是将状态信息保存为字符串,相当于编码;
- 反序列化:将字符串转换为状态信息,相当于解码;
- PHP中特殊魔法函数:
- __construct():当对象创建(new)时会自动调用,但在unserialize()时是不会自动调用的(构造函数)
- __destruct():当对象操作执行完毕后自动执行destruct()函数的代码
- __wakeup():unserialize()时自动调用
- __call():方法当调用类实例中不存在的函数时自动执行
- 优先级问题:__wakeup()优先执行,优先级高于__destruct()
- 漏洞利用思路:
- PHP中存在一个关于__wakeup方法的漏洞,当反序列化的字符串中,表示对象属性个数的值大于实际属性个数时,__wakeup()方法不会被调用
解题思路:
- 进入页面,看到一段PHP代码,进行代码审计

- 分析知这段代码:定义了一个类,类中有一个公共属性$flag,值为‘111’;定义了__wakeup()魔术方法,当对象被反序列化时,这个方法会被自动调用,调用后执行exit(‘bad request),直接终止程序。
- 题目问code=?,我们只需要对flag进行序列化,得到
其中:1:中1是属性个数 - 如果我们直接提交?code=O:4:"xctf":1:{s:4:"flag";s:3:"111";}的话,会执行__wakeup()方法直接退出程序我们需要绕过__wakeup方法,将属性个数改为2,即提交?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";}
- 成功得到flag(序列化脚本如下)
<?php
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
}
$b=new xctf();
$c=serialize($b);
echo $c;
?>






