介绍
序列化:变量转换为可保存或传输的字符串的过程;
反序列化:把序列化的字符串再转化成原来的变量使用
作用:可轻松地存储和传输数据,使程序更具维护性
序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构
示例代码
<?php
class User
{
public $username = 'admin';
public $password = '123456';
}
// 序列化操作
$user = new User();
$str_ser = serialize($user);
echo "序列化结果为:\n";
var_dump($str_ser);
echo "反序列化结果为:\n";
// 反序列化操作
$str_uns = 'O:4:"User":2:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";}';
$str = unserialize($str_uns);
var_dump($str);
?>
序列化格式
魔术方法
__construct() 当创建对象时触发,一般用于初始化对象,对变量赋初值;
__sleep() 使用serialize()时自动触发 ;
__wakeup() 使用unserialize()时自动触发;
__destruct() 当一个对象被销毁时触发;
__toString() 以处理字符串的方式处理一个类时会触发;
__invoke() 以调用函数的方式调用一个对象时会触发该函数;
__call() 在对象上下文中调用不可访问的方法时触发 ;
__callStatic() 在静态上下文中调用不可访问的方法时触发;
__get() 用于从不可访问的属性读取数据;
__set() 用于将数据写入不可访问的属性;
__isset() 在不可访问的属性上调用isset()或empty()触发 ;
__unset() 在不可访问的属性上使用unset()时触发;
魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)
原理
PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果。漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通。
触发条件
unserialize函数的变量可控,php文件中存在可利用的类,类中有魔法函数
需要注意的特点
序列化对象:
private变量会被序列化为:\x00类名\x00变量名
protected变量会被序列化为:\x00*\x00变量名
public变量会被序列化为:变量名
PHP session
PHP session
反序列化漏洞,就是当【序列化存储Session
数据】与【反序列化读取Session
数据】的方式不同导致session
反序列化漏洞的产生
session的反序列化漏洞利用
session的反序列化漏洞,就是利用
php
处理器和php_serialize
处理器的存储格式差异而产生.