攻防世界 WEB 高手进阶区 unserialize3 Writeup
攻防世界 WEB 高手进阶区 unserialize3 Writeup
题目介绍
题目考点
- PHP反序列化 __wakeup漏洞
Writeup
-
题名 unserialize 是反序列化函数名
-
了解一下什么是序列化和反序列化
当在php中创建了一个对象后,可以通过 serialize() 函数把这个对象转变成一个字符串,保存对象的值方便之后的传递与使用。与 serialize() 相反的就是反序列化函数 unserialize() ,它可以将一个字符串转变为相对应的php对象。
在序列化过程中会用到的函数:
__construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
__destruct():当对象被销毁时会自动调用。(析构函数)
__wakeup():unserialize() 时会自动调用。
__sleep() 在对象被序列化之前运行。
__toString ()当一个对象被当作一个字符串使用。
__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
-
php代码分析
class xctf{ //定义一个名为xctf的类 public $flag = '111'; //定义一个公有的类属性$flag,值为111 public function __wakeup(){ //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本 exit('bad requests'); } ?code= //可能是在提示我们http://111.198.29.45:30940?code=一个值进行利用
代码中的__wakeup()方法如果使用就是和unserialize()反序列化函数结合使用的,这里没有序列化字符串,何来反序列化呢?于是,我们这里实例化xctf类并对其使用序列化(这里就实例化xctf类为对象a)
<?php 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";}
序列化后格式:
O:
:" ": :{<field name 1><field value 1>... } O:表示序列化的事对象
< length>:表示序列化的类名称长度
< class name>:表示序列化的类的名称
< n >:表示被序列化的对象的属性个数
< field name 1>:属性名
< field value 1>:属性值 -
我们要反序列化xctf类的同时还要绕过wakeup方法的执行 (如果不绕过wakeup()方法,将会输出bad requests并退出脚本)
-
_wakeup()函数漏洞原理:当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup()的执行。
-
因此,需要修改序列化字符串中的属性个数:当我们将上述的序列化的字符串中的对象属性个数由真实值1修改为3,即如下所示
O:4:"xctf":3:{s:4:"flag";s:3:"111";}
-
得到flag