目录
一、魔术方法利用点分析
<__construct&__destruct>
<__toString>
<__call>
<__get>
<__set>
<__sleep>
<__wakeup>
<__isset>
<__unset>
<__invoke>
<总结>
二、对象变量属性及序列化数据显示
对象变量属性
序列化数据显示
演示
三、反序列化利用的分类
一、魔术方法利用点分析
<__construct&__destruct>
__construct() //构造函数,当对象 new 的时候会自动调用
__destruct() //析构函数当对象被销毁时会被自动调用
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__toString>
__toString() //在对象当做字符串的时候会被调用
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__call>
__call() //在对象上下文中调用不可访问的方法时触发
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__get>
__get() //用于从不可访问的属性读取数据
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__set>
__set() //用于将数据写入不可访问的属性
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__sleep>
__sleep() //serialize之前被调用,可以指定要序列化的对象属性
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__wakeup>
__wakeup() //unserialize()时会被自动调用
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__isset>
__isset() //检测对象的某个属性是否存在时执行此函数
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__unset>
__unset() //在不可访问的属性上使用unset()时触发,销毁对象的某个属性时执行此函数
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<__invoke>
__invoke() //将对象当做函数来使用时执行此方法,通常不推荐这样做
1.实验代码部分如下。
2.将代码执行后可以看到下面的执行结果。
<总结>
触发:unserialize 函数的变量可控,文件中存在可利用的类,类中有魔术方法:
__construct(): //构造函数,当对象 new 的时候会自动调用
__destruct(): //析构函数当对象被销毁时会被自动调用
__wakeup(): //unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call(): //在对象上下文中调用不可访问的方法时触发
__callStatci(): //在静态上下文中调用不可访问的方法时触发
__get(): //用于从不可访问的属性读取数据
__set(): //用于将数据写入不可访问的属性
__isset(): //在不可访问的属性上调用 isset()或 empty()触发
__unset(): //在不可访问的属性上使用 unset()时触发
__toString(): //把类当作字符串使用时触发
__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep(),如果存在,该方法会被优先调用
二、对象变量属性及序列化数据显示
对象变量属性
- publt(公共的):在本类内部、外部类、子类都可以访问。
- protect(受保护的):只有本类或子类或父类中可以访问。
- private(私人的):只有本类内部可以使用。
序列化数据显示
- private属性序列化的时候格式是%00类名%00成员名。
- protect属性序列化的时候格式是%00*%00成员名。
演示
- 代码
- 运行结果
三、反序列化利用的分类
- 魔术方法的调用逻辑---如触发条件语言。
- 原生类的调用逻辑---如SoapClient语言。
- 自身的安全缺陷---如CVE-2016-7124 。