【反序列化】PHP序列化基础

PHP序列化基础知识储备-阿里云开发者社区

概念

PHP中的序列化是指,将复杂的数据类型,转换成可以传输的字符串,反序列化就是将这个过程还原回原数据的方法。

PHP中,使用函数serialize()函数进行序列化操作。通过unserialize()进行还原操作

 

序列化后的结果

经过序列化后,会得到一串字符串,其按照规定的格式编写:

基础格式如下:

[变量类型/o/a/s/i] : [长度] : [内容]

对象(Object)序列化格式

O:<类的名字的长度>:"类的名字":"属性个数":{<属性1名>;<属性1值>;...}

示例:

class xctf{
    public $flag = '111';  // 定义一个属性
    public function __wakeup(){
        exit('bad requests');
    }
}

在上述例中,定义了一个xctf类,内部有一个属性,属性名为flag,值为111

因此可以获得,类的名称长度为4类的名字为"xctf"

只有一个属性为flag 因此属性个数为1 

在属性中 属性1的名字是 flag 为字符串 值为 111 同为字符串

整合格式

O:<类的名字的长度>:"类的名字":"属性个数":{<属性1名>;<属性1值>;...}

得到

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

 

数值(interger)的序列化格式

i : 值

字符串(String)序列化格式

字符的序列化后的格式比较简单,格式如下:

s : <字符串长度> : "字符串内容"

 

数组(Array)序列化格式

数组序列化后格式如下

a:<数组中元素个数>:{<键1>;<值1>;....}

其中,键和值 都遵循序列化的要求,如果为字符串则会变为字符串序列化后的结果,

 

特性(魔术方法)

与python类似,有一些__开头的隐藏函数,在序列化函数执行的时候的时候会执行

__construct()		//当一个对象创建时被调用
__destruct()		//当一个对象被销毁时会触发
__wakeup()			//使用反序列化的时候会触发
__sleep()			//使用序列化函数的时候会触发
__toString()		//当把类当做字符串的时候会触发
__get()				//从不可访问的属性读取数据
__set()				//将数据写入不可访问的属性

 

绕过某个函数

__wakeup()函数

当序列化后的结果,在进行反序列化过程中,会触发该函数,但当声明的属性个数大于实际提供的属性个数时,该函数就会跳过。

比如:

class xctf{
    public $flag = '111';  // 假设真实flag在实际环境中
    public function __wakeup(){
        exit('bad requests');  // 反序列化时会触发,导致程序退出
    }
}

这个类中,属性只有1个,因此序列化后的结果为:

o:4:"xctf":1:{s:4:"flag";s:3:"111"}

当我们把其中的1改为2,他就会大于后面实际给出的属性。

o:4:"xctf":2:{s:4:"flag";s:3:"111"}

达到越过的目的

相关题目

unserialize3


目录