PHP反序列化漏洞

原理

​ 未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程。当进行反序列化的时候可能会触发一些对象中的某些魔术方法。

反序列化:将字符串或数组转化成对象

序列化:将对象转换成字符串或数组

DEMO

demo1.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$a="abcd"; //字符串
$arr = array('j' => 'jack' ,'r' => 'rose'); //数组
class A{
public $test="yeah";
}
echo "序列化:";
echo "</br>";
$aa=serialize($a);
print_r($aa);
echo "</br>";
$arr_a=serialize($arr);
print_r($arr_a);
echo "</br>";
$class1 = new A(); //对象
$class_a=serialize($class1);
print_r($class_a);
//echo "<br/>";
//echo "反序列化:";
//echo "<br/>";
//print_r(unserialize($aa));
//echo "</br>";
//print_r(unserialize($arr_a));
//echo "</br>";
//print_r(unserialize($class_a));
?>

反序列化常用魔术方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__construct() 当一个对象创建时被调用,
__destruct() 当一个对象销毁时被调用,
__toString() 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发