PHP反序列化

用户数据在$_SESSION中存储,当用户数据过大,内存占用过大,为了节省内存,选择把用户数据存储在文件中,即使用serialize()函数把用户数据存储到文件中,在使用的时候,在通过unserialize()函数调用

漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果

serialize()

函数用于序列化对象或数组,并返回一个字符串。

整数12i:12;

字符串abcs:3:"abc";

浮点型3.14d:3.14;

布尔型:true->b:1;、false->b:0;

数组array('abc','ab')a:2:{i:0;s:3:"abc";i:1;s:2:"ab";}

NULL:N;

<?php
class obje{
    var $name = 'clancy';
    var $age = '18';
    function play(){
        echo $this->age;
        echo "\n";
    }
}
$p = new obje();
$p->play();
var_dump($p);
echo serialize($p);
?>

18
object(obje)#1 (2) {
  ["name"]=>
  string(6) "clancy"
  ["age"]=>
  string(2) "18"
}
O:4:"obje":2:{s:4:"name";s:6:"clancy";s:3:"age";s:2:"18";}

unserialize()

函数用于将通过serialize()函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。

<?php
class obje{
    var $name = 'clancy';
    var $age = '18';
}
$p = new obje();
$c = serialize($p);
var_dump(unserialize($c));
?>

object(obje)#2 (2) {
  ["name"]=>
  string(6) "clancy"
  ["age"]=>
  string(2) "18"
}

对象中的成员变量可控,成员函数如__wakeup()中调用了危险函数,然后在反序列化就会有漏洞

反序列化黑盒测试基本测不出来,需要代码审计

PHP魔术方法
_construct(): 创建对象时初始化
_destruction(): 结束时销毁对象
_toString(): 对象被当作字符串时使用
_sleep(): 序列化对象之前调用
_wakeup(): 反序列化之前调用
_call(): 调用对象不存在时使用
__wakeup() //使用unserialize时触发
__destruct() //对象被销毁时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
posted @ 2023-02-26 22:26  cowpokee  阅读(13)  评论(0编辑  收藏  举报