PHP反序列化总结
2019-01-12 22:25:34
漏洞成因
Demo:
<?php
class A{
public $target = "demo";
function __destruct(){
echo "destructing!<br/>";
echo $this->target."<br/>";
echo "destructed!<br/>";
}
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>
在这里我们可以构造一个对象,控制$test的值,以实现控制数据流的目的
生成序列化字符串:
<?php
class A{
public $target = "w2t3rp2dd13r";
}
$a = serialize(new A);
echo $a;
?>
常见绕过方式
_wakeup绕过:
__wakeup()是用在反序列化操作中。unserialize()会检查存在一个__wakeup()方法。如果存在,则先会调用__wakeup()方法。
<?php
class A{
function __wakeup(){
echo 'Hello';
}
}
$c = new A();
$d=unserialize('O:1:"A":0:{}');
?>
存在wakeup函数,所以会输入hello
<?php
class Student{
public $full_name = 'zhangsan';
public $score = 150;
public $grades = array();
function __wakeup() {
echo "__wakeup is invoked";
}
}
$s = new Student();
var_dump(serialize($s));
?>
这里会输出student的实例序列化字符串
O:7:"Student":3:{s:9:"full_name";s:8:"zhangsan";s:5:"score";i:150;s:6:"grades";a:0:{}}
student后的3代表该类存在3个属性
而当该属性大于真实值时代码就会跳过_wakeup()函数执行
所以当输入序列化字符串为:
O:7:”Student”:4:{s:9:”full_name”;s:8:”zhangsan”;s:5:”score”;i:150;s:6:”grades”;a:0:{}}
时,就不会执行_wakeup()函数。