反序列化
反序列化
一、类与对象
php类与对象举例
<?php
class animal {
public $name = 'dahuang';//define a virable
public function sleep(){//define a simpe method
echo $this->name . " is sleeping...\n";
}
}
$dog = new animal();
$dog->sleep();
?>
PHP常见的magic方法:
方法名 触发点
__construct 在创建对象时候初始化对象,一般用于对变量赋初值
__destruct 和构造函数相反,在对象不再被使用时(将所有该对象的引用设为null)或者程序退出时自动调用
__toString 当一个对象被当作一个字符串被调用,把类当作字符串使用时触发,返回值需要为字符串
__wakeup() 使用unserialize时触发,反序列化恢复对象之前调用该方法
__sleep() 使用serialize时触发 ,在对象被序列化前自动调用,该函数需要返回以类成员变量名作为元素 的数组 (该数组里的元素会影响类成员变量是否被序列化。只有出现在该数组元素里的类成员变 量才会被序列化)
__destruct() 对象被销毁时触发
__call() 在对象上下文中调用不可访问的方法时触发,即当调用对象中不存在的方法会自动调用该方法
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据,即在调用私有属性的时候会自动执行
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__invoke() 当脚本尝试将对象调用为函数时触发
实例
<?php
class animal {
public $name = 'dahuang';//define a virable
public function sleep(){//define a simpe method
echo $this->name . " is sleeping...\n";
}
public function __construct(){
echo "the method:__construct is called\n";
}
public function __destruct(){
echo "the method:__destruct is called\n";
}
public function __toString(){
return "the method:__toString is called\n";
}
}
$dog = new animal();
$dog->sleep();
echo $dog;
?>
二、PHP 对象序列化
在PHP网站中的定义
所有PHP里面的值都是可以使用函数serialize()来返回一个包含字节流的字符串表示。
unserialize()函数能够重新把字符串。
变回PHP原来的值。序列化一个对象将会保存对象的所有变量,但不会保存对象的方法,只会保存类的名字。
简单的理解序列化:就是把一个类的实例变成一个字符串;
简单的理解反序列化:就是把一个特殊的字符串转换成一个实例。
现在,我们将0x02中的dog对象进行序列化,即将最后一行代码:echo $dog;
改为echo serialize( $dog);
输出结果:高亮部分即为序列化的dog对象
序列化后的字符串格式如下:
0:6:"animal":1:{s:4:"name";s:7:"dahuang";}
对象类型:长度:"名字":类中变量的个数:{类型:长度:"名字";类型:长度:"值";......}
序列化格式中的字母含义:
a - array b - boolean
d - double i - integer
o - common object r - reference
s - string C - custom object
O - class N - null
R - pointer reference U - unicode string
三、PHP反序列化漏洞/PHP对象注入
例题:
题目非常明了,只有一个类site 和一个魔法函数_destruct
unserialize(反序化前自动调用_destruct)
关键 在$a($this->title)
明显的是a参数执行(this->title)
所以在这里可以构造命令执行,利用assert函数执行system系统命令。
在线php网站运行
O:4:"site":3:{s:3:"url";s:14:"www.whalwl.com";s:4:"name";s:6:"assert";s:5:"title";s:10:"system(ls)";}
放在Hackbar里 post参数dage