php反序列化漏洞
关于类与对象
对象:可以对其做事情的一些东西。一个对象有状态、行为和标识三种属性。
类:一个共享相同结构和行为的对象的集合。
每个类的定义都以关键字class开头,后面跟着类的名字。一个类可以包含有属于自己的变量,变量(称为“属性”)以及函数(“称为方法”)。类可能会包含一些特殊的函数叫magic函数,magic函数命名是以符号“_”开头的,比如_sleep,_wakeup等。这些函数在某些情况下会自动调用。比如:
- _construct当一个对象创建时调用(constructor);
- _destruct当一个对象被销毁时调用(destructor);
- _toString当一个对象被当作一个字符串时使用。
反序列化中常见的魔术方法
__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
反序列化漏洞
而反序列化过程中,对象会自动调用类中的魔术方法,魔术方法内又调用了别的方法,在别的方法中可能存在任意代码执行的命令或代码,导致反序列化漏洞的产生。
上面是创建了animal类,类里面有name和age属性,还有一个__sleep方法
接下来是创建了an1对象,并给对象name和age值,并且将an1序列化,在序列化的时候,会自动调用__sleep方法,当cmd为xiu 的时候会自动调用计算机。
http://192.168.197.136/unserialize.php?u=O:4:“demo”:0:{}&cmd=phpinfo();
下面这个是调用的析构函数,析构函数调用了eval方法,在url传入序列化字符串,当反序列化的时候会自动去调用__destruct()方法,而后在__destruct()方法中又去调用eval方法,显示出phpinfo。
php的反序列化漏洞的成因
程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。一般程序在创建的时候,都会重写析构函数和构造函数,反序列化就是利用这些重写的函数。