php反序列化(昨天的补充)

魔术方法

在对PHP反序列化进行利用时,经常需要通过反序列化中的魔术方法,检查方法里是否有敏感操作来进行利用。

常见方法:

创建对象时触发:__construct()

对象被销毁时触发:__destruct()

在对象上下文中调用不可访问的方法时触发:__call()

在静态上下文中调用不可访问的方法时触发:__callStatic()

用于从不可访问的属性读取数据:__get()

用于将数据写入不可访问的属性:__set()

在不可访问的属性上调用isset()或empty()触发:__isset()

在不可访问的属性上使用unset()时触发:__unset()

当脚本尝试将对象调用为函数时触发:__invoke()

而需要记住的重要方法有:

__sleep():

serialize()序列化函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则NULL被序列化,并产生一个E_NOTICE级别的错误。

简而言之就是该方法在对象被序列化之前触发,返回需要被序列化存储的成员属性,删除不必要的属性。

__wakeup():

unserialize()反序列化函数会检查是否存在一个__wakeup()方法。如果存在,则会先调用__wakeup方法,预先准备对象需要的资源。

简而言之就是会预先准备对象资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作。

注:在CTF中的反序列化的题目,一旦有__wakeup(),可以将序列化字符串中表示对象属性个数的值修改为大于真实的属性个数,那么就会跳过__wakeup()的执行。

__toString():

__toString()方法用于一个类被当成字符串时应怎样回应。例如echo $obj;应该显示些什么。此方法必须返回一个字符串,否则将发出一条E_RECOVERABLE_ERROR级别的致命错误。

<?php
    class test{
        public function __construct($ID,$sex,$age){
            $this->ID = $ID;
            $this->sex = $sex;
            $this->age = $age;
            $this->info = sprintf("ID:%s,age:%d,sex:%s",$this->ID,$this->sex,$this->age);
        }

        public function __toString(){
            return $this->info;
        }
    }
    
    $me = new test('test',21,'male');
    echo '__toString:'.$me.'<br>';
?>

运行结果为

__toString:ID:test,age:21,sex:male
原文地址:https://www.cnblogs.com/-an-/p/12184770.html