当前位置:网站首页 > 网络安全培训 > 正文

序列化与反序列化之PHP

freebuffreebuf 2021-08-25 326 0

本文来源:Z1R0

序列化和反序列化

简述

序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

1629855393_61259ea1dec03bf91b9c5.png

使用场景

对象的持久化(将对象内容保存到数据库或文件中)

远程数据传输(将对象发送给其他计算机系统)

使用原因

序列化与序列化主要解决的是数据的一致性问题。简单来说,就是输入数据与输出数据是一样的。

对于数据的本地持久化,只需要将数据转换为字符串 进行保存即可是实现,但对于远程的数据传输,由于操作系统,硬件等差异,会出现内存大小端,内存对齐等问题,导致接收端无法正确解析数据,为了解决这种问题。

特点

永久性保存对象,保存对象的字节序列到本地文件 或者数据库中;

通过序列化以字节流的形式使对象在网络中进行传 递和接收;

通过序列化在进程间传递对象。

PHP序列化和反序列化

在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。

serialize():将一个对象转成字符串形式,方便保存以便于下次再次 反序列化出该对象直接使用。

unserialize():将序列化后的字符串反序列化成一个对象。

序列化函数原型如下:

string serialize ( mixed $value )

看个栗子

class CC {public $data;private $pass;public function __construct($data, $pass){$this->data = $data;$this->pass = $pass;}}$number = 34;$str = 'uusama';$bool = true;$null = NULL;$arr = array('a' => 1, 'b' => 2);$cc = new CC('uu', true);var_dump(serialize($number));var_dump(serialize($str));var_dump(serialize($bool));var_dump(serialize($null));var_dump(serialize($arr));var_dump(serialize($cc));

输出结果为:

string(5) "i:34;"string(13) "s:6:"uusama";"string(4) "b:1;"string(2) "N;"string(30) "a:2:{s:1:"a";i:1;s:1:"b";i:2;}"string(52) "O:2:"CC":2:{s:4:"data";s:2:"uu";s:8:" CC pass";b:1;}"

序列化对于不同类型得到的字符串格式为:

String : s:size:value;Integer : i:value;Boolean : b:value;(保存1或0)Null : N;Array : a:size:{key definition;value definition;(repeated per element)}Object : O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

常见的序列化数据类型标志

标志数据类型
i整数
d浮点数
O对象
R引用
S字符串Hex
s字符串
a数组
b布尔值
NNULL
权限Puiblic 权限:公共、默认的Private 权限:私有权限Protected 权限:受保护的
访问权限publicprotectedprivate
类内
子类
所有

Private权限:前面加上自己的名字%00属性名%00Protected权限%00*%00属性名

反序列化漏洞

本质上serialize()和unserialize()在PHP内部实现上是没有漏洞的,漏洞的主要产生是由于应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。

当传给unserialize()的参数可控时,那么用户就可以注入精心构造的payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。

PHP魔术方法

函数说明
__construct()类的构造函数
__destruct()类的析构函数
__wakeup()执行unserialize()时,先会调用这个函数
__tostring()类被当成字符串时的回应方法
__sleep()执行serialize()时,先会调用这个函数
__call()在对象中调用一个不可访问方法时调用
__callStatic()用静态方式中调用一个不可访问方法时调用

魔术方法的调用是在该类序列化或者反序列化的同时(特 定情况下)自动完成的,不需要人工干预,这就非常符合 我们的想法,因此只要魔术方法中出现了一些我们能利用 的函数,我们就能通过反序列化中对其对象属性的操控来 实现对这些函数的操控,进而达到我们发动攻击的目的。

防御方法

要严格控制unserialize()函数的参数,坚持用户所输入的信息都是不可靠的原则;

要对于反序列化后的变量内容进行检查,以确定内容没有被污染。

小拓展

追加任意字符串

序列化字符串之后追加任意字符串,不影响反序列化的进行。

长度前面添加0

在序列化字符串表示长度的数字前添加一个或者多个0,不影响反序列化的进行。

任意单个字符代替s之后的

在序列化字符串中使用任意单个字符代替s之后的分号,不影响反序列化的进行。​

转载请注明来自网盾网络安全培训,本文标题:《序列化与反序列化之PHP》

标签:php安全网络安全技术序列化和反序列化

关于我

欢迎关注微信公众号

关于我们

网络安全培训,黑客培训,渗透培训,ctf,攻防

标签列表