序列化与反序列化

序列化基础知识

序列化的作用

序列化(serialization)是将对象的状态信息 (属性) 转化为可以存储或传输的形式的过程
对象 ------------ >序列化 ----------------> 字符串
将对象或者数组转化为可储存/传输的字符串。
在php中使用函数serialize()来将对象或者数组进行序列化,并返回一个包含字节流的字符串来表示。

表达方式

image.png
可以看到是个N;
后面这个分号一定要的记得 ,

image.png

**数组序列化: **

$a = array('abc','def','jhk');
echo $a[0]."<br>";
echo serialize($a);

image.png

先出现 数组 下标为0 的 数值
0 下标为 abc ;

a:3:{i:0;s:3:“abc”;i:1;s:3:“def”;i:2;s:3:“jhk”;}

解释 :
a array :3 参数数量 :{i:0 编号 ;s:3 字符型;长度:“abc”;i:1;s:3:“def”;i:2;s:3:“jhk”;}

对象序列化

image.png
序列化内容

O:4:“test”:1:{s:3:“pub”;s:6:“benben”;}

不能序列化‘类’可以序列化′对象’
对象序列化 不会序列化方法 ,只会序列化成员属性和他对应的值;
解释 :

O object :4 类名长度 :“test” 类名 :1 变量数量:{s:3 变量名字长度 :“pub” 变量名字 ;s:6 值的长度 :“benben” 变量值;}

增加一个 他也会随之增加
image.png

**私有属性 : **
image.png

private私有属性序列化时
在变量名前加"url编码之后的%00类名%00”

这里为什么是9 个呢
因为在类名前后都要加一个%00
%00 为空代表一个字符

O:4:“test”:1:{s:9:“%00testpub%00”;s:6:“benben”;}

受保护属性序列化 :

protected受保护属性序列化时,在变量名前加"%00*%00"

image.png

O:4:“test”:1:{s:6 变量名长度:"00pub";s:6:“benben”;}
加了0
0 所以是6个

成员属性调用对象 :

image.png

O:5:“test2”:1:{s:3:“ben”;O:4:“test”:1:{s:3:“pub”;s:6:“benben”;}}

去new 一个test2()的时候 就已经把 test() 序列化了
去调用test2 对应的 成员属性是ben 但是ben对应的 是 一个完整的object 对象 赋值给ben 了

再来一个列子
image.png
实例化后的对象 a 的成员变 量 ′ b e n ′ 调用实例化后的对象 a的成员变量'ben'调用实例化后的对象 a的成员变ben调用实例化后的对象b

反序列化

反序列化的作用
将序列化后的参数还原成实例化的对象
image.png

image.png
这样就拿到了个序列化

O:4:“test”:3:{s:1:“a”;s:6:“benben”;s:4:“*b”;i:666;s:7:“testc”;b:0;}

反序列化:
image.png
这里要将序列化的内容 , 受保护的 和私有的 类名要加上%00
再对其进行urldecode 进行解码
然后再进行反序列 (unserialize)

C:\Users\chenxL\Desktop\PHP\反序列化\反序列化.php:15:
object(test)[1]
  public 'a' => string 'benben' (length=6)
  protected 'b' => int 666
  private 'c' => boolean false

这是反序列化后的内容 和 还没有序列化的数据是一样的

反序列化生成的对象里的值,由反序列化里的值(字符串$a)提供;与原有类预定义的值无关;

意思就是原类里面的值是可以随便修改的
例如
image.png
现在 0 是flase 我们该成true 然后再修改一下数据
image.png
完全是可以修改的
调用成员方法
$f->displayVar();
调用的是 $d里面的成员属性
所属的值就 不是 benben 而是 abcdef
image.png
反序列化不改变类的成员方法;需要调用方法后才能触发;

反序列化例题

image.png
定义 test 类
定义了 $a 的 一个成员变量 输出一个 this istest!!
然后还有一个动作 ,displayVar
里面有一个eval 函数 (危险函数 ) 可以执行命令
存在一个 可控变量 benben
然后 对传进来的值进行反序列化 , 再赋值给 $b 去调用了 test类里面的 displayVar()
就是这么个过程

但是由于benben 可以构造
b 把字符串 b把字符串 b把字符串get反序列化为对象,
通过更改字符串可改变得到的对象中$a的值,通过调用方法触发可控代码
构建payload :
image.png
序列化后的内容 :

O:4:“test”:1:{s:1:“a”;s:10:“phpinfo();”;}

然后去把序列化的内容 给 ?benben 就可以执行phpinfo();
http://localhost:8002/class06/index.php?benben=O:4:"test":1:{s:1:"a";s:10:"phpinfo();";}
image.png
这样就执行了反序列化 执行 php命令

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值