为什么需要PHP反序列化呢?
其实是为了传输数据的方便,因为一个程序里面的运行的数据,当这个程序运行结束以后,那么存储的数据也就自然不见了。
因此,为了传递数据的方便性,就引入了序列化、反序列化。
PHP序列化将数组、变量、对象等在需要的时候将其变成字符串,方便传输等。而后在合适的机会就又进行一次反序列化,再将序列化后的字符串变成变量,由此方便了数据的传输。同时更是造成了很多的安全问题。在了解相关漏洞之前,我们简单的学一下序列化,以及反序列化。
我们先做一个小小的实验:
这里面将"test"序列化输出,我们来看看会输出什么.
在这里面 s代表的是字符串(string) 后面的4代表的是字符串的长度,在后面的话就是字符串的值了
同样的对于数字来说:
其中i代表的是整数(int),后面的是他的值。因为int型不是字符串,所以没有必要去输出字符串长度
试试Double型的
发现:
这个貌似是因为Double精度的问题?
不太了解。。但是d是代表的是double型的数据,后面跟的是他的值
再来试试数组:
别急我们一步一步来分析
首先对于整体来说$a是一个数组,里面有四个元素
因此前面的a代表的是一个数组,后面的数字代表的是后面有$a里面有多少的元素
然后在用{}包住里面的元素
接下来就是对里面的各个元素分析了
这里面很有意思,竟然将元素对应的数组的键也写了出来
先写出来一下其键与键值的关系
0->1 1->2 2->2 ko->LOL
仔细看看是不是将键与键值按上方的格式输出来了。并且每一个元素之间用分号";"隔开
之所以这样是因为PHP支持索引数组,防止反序列化后找不到其对应的键
接下来看一下对象的(这个比较重要,因为涉及到一些PHP的魔法函数,基本上PHP反序列化就跟对象联系到了一起):
我们看看会反序列化成什么:
简单地说一下吧,对于这个输出。
o代表是一个对象,后面的4代表的是他这个类的长度(因为是字符串吗,最后面就接上了他的原名'test')
之后还是大括号包起来,这里边跟数组很类似
创建对象的时候传入了两个参数,就是13 45,在PHP对象的魔法方法(就是__construct)里面调用的。并且将$a与$b给赋初始值,
所以最后就会将打出$a与$b序列化后的值,注意这里面也是和数组一样的a->13 b->45
下面总结一下魔法方法
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup将在序列化之后立即被调用
至于怎么弄的话我实在讲不出来。。。所以下面给几篇讲的很好的博客
添加链接描述
添加链接描述
添加链接描述
感觉刚开始学挺绕的。。慢慢学吗,以后可能还要涉及到PHP伪协议等等。