PHP反序列化漏洞
1、原理
将数组或者class转化字符串,就叫做序列化。
反序列化就是将转化的字符串恢复。
PHP中使用serialize()函数进行序列化,使用**unserialize()**函数进行反序列化。
2、利用条件
-
序列化的参数可控
-
序列化的对象为class
-
class中有魔术方法
魔术方法: __construct()// 构建对象的时被调用;new一个对象的时候使用,也就是说只要实例化的时候就会第一个调用这个函数,并且执行该函数中的内容,多用于初始化 __destruct()// 明确销毁对象或脚本结束时被调用;意思就是在对象使用类中的属性或者函数结束后,执行该函数的内容,用于收尾工作 __wakeup()// 当使用unserialize()时被调用,可用于做些对象的初始化操作。进行反序列化的时候执行,也就是我们将一串字符串进行反序列化的时候会优先执行。 __sleep()// 当使用serialize()时被调用,当你不需要保存大对象的所有数据时很有用。序列化的时候使用 __get()// 读取不可访问或不存在属性时被调用 例如一些私有属性或者不存在的属性 __call()// 读取不可访问或不存在的函数时被调用 __invoke()// 当以函数方式调用对象时被调用 当我们的对象被当做函数调用的时候,执行该函数的内容 __toString()// 当一个类被转换成字符串时被调用 我们对实例化的对象直接作为字符串使用的时候调用该函数的内容执行
-
方法中有一些敏感函数,例如(include()、file_get_contents()、file_put_contents()、eval()等),总结起来就是一些可以利用的函数。
3、查找漏洞的方法
先观察代码中是否有class,然后查找是否有反序列化的函数,判断是否可控,接着这条线索查找是否有魔术方法可利用,是否有敏感函数利用,开始构造poc,思考代码逻辑,先顺着代码走一边,然后思考poc。