__wakeup()函数漏洞利用随笔
<!-- php __wakeup() 函数漏洞分析,测试 -->
<!-- __wekup()函数是在反序列化操作时,unserialize()函数会先检查有没有存在
一个名为 __wakeup()的函数,如果存在,先执行 __wakeup()-->
<?php
class A{
function __wakeup(){
echo 'hello';
}
}
// 反序列化一个类,__wakeup() 执行,输出 hello
$d = unserialize('O:1:"A":0:{}');
// echo '<br/>'.serialize($d);
?>
<!-- __wakeup() 函数漏洞说明 -->
<?php
echo "<br/>";
class Student{
public $full_name = "zhangsan";
public $score = 150;
public $grades = array();
function __wakeup(){
echo "__wakeup is invoked";
}
}
$s = new Student();
// 输出Student 对象的序列化结果以及类型,长度
var_dump(serialize($s));
// 输出为 :string(86) "O:7:"Student":3:{s:9:"full_name";s:8:"zhangsan";s:5:"score";i:150;s:6:"grades";a:0:{}}"
// 漏洞利用:当序列化结果(字符串)表示对象属性个数的值 大于 真实个数的属性值时,就会跳过 __wakeup() 函数的执行
// 构造payload:"O:7:"Student":5:{s:9:"full_name";s:8:"zhangsan";s:5:"score";i:150;s:6:"grades";a:0:{}}"
echo "<br/>";
// 如果属性值为 3 ,即为真实结果,输出 __wakeup is invoked ,随意改为大于 3 的值,页面无输出;
$stu = @unserialize('O:7:"Student":3:{s:9:"full_name";s:8:"zhangsan";s:5:"score";i:150;s:6:"grades";a:0:{}}');
?>