PHP反序列化
0x01、PHP面向对象编程
1、面向对象的基本概念
在面向对象的程序设计(英语:Object-oriented programming,缩写:OOP)中,对象是一个由信息及对信息进行处理的描述所组成的整体,是对现实世界的抽象。
对象的主要三个特性:
对象的行为:可以对对象施加那些操作,开灯,关灯就是行为。
对象的形态:当施加那些方法是对象如何响应,颜色,尺寸,外型。对象的表示:对象的表示就相当于身份证,具体区分在相同的行为与状态下有什么不同。
2、类和对象
类——定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
对象——是类的实例。
成员变量——定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
成员函数——定义在类的内部,可用访问对象的数据。
<?php class TestClass
{
//一个变量
public $variable='This is a string';
//一个简单的方法
public function PrintVariable()
{
echo $this->variable;
//创建一个对象
$object = new TestClass();
//调用一个方法
$object->PrintVariable();
?>
3、magic函数
- 类可能会包含一些特殊的函数叫magic函数,magic函数命名是以符号"_"开头的,这些函数在某些情况下会自动调用
- _construct:构造函数,当一个对象创建时调用
- _destruct:析构函数,当一个对象被销毁时调用
- _toString:当一个对象被当作一个字符串时使用
_sleep
:在对象序列化的时候,会调用一个_sleep()方法- wakeup:对象重新醒来,即由二进制串重新组成一个对象的时候,则会自动调用PHP的另一个函数_wakeup()
0x02、PHP序列化和反序列化
1、什么是序列化
- 有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化(也叫序列化)
- 有两种情况我们必须把对象序列化
- 把一个对象在网络中传输的时候
- 把对象写入文件或是数据库的时候
2、序列化和反序列化过程
- 序列化:
就是把对象转化为二进制的字符串,使用serialize()函数 - 反序列化:
把对象转化的二进制字符串再转化为对象,使用unserialize()函数
3、序列化
<?php
//一个类
class User
{
//类的数据
public $age = 0;
public $name= ";
//输出数据
public function printdata()
{
echo 'User'.$this->name.' is '.$this->age.'years old.<br/>';
}
}
//创建一个对象
$usr = new User();
//设置数据
$usr->age = 18;
$usr->name='vergilben';
//输出数据
$usr->printdata();
//输出序列化后的数据
echo serialize($usr)
?>
4、反序列化
<?php
//一个类
class User
{
//类的数据
public $age=0;
public $name = ";
//输出数据
public function printdata()
{
echo'User '.$this->name.' is '.$this->age.'years old.<br/>;
}
}
//重建对象
$usr = unserialize('O:4:"User":2:{s:3:"age";i:18;s:4:"name";s:9:"vergilben":)}');
//输出数据
$usr->printdata();
?>
5、_sleep magic方法和_wakeup magic方法
_sleep magic方法在一个对象被序列化时调用
_wakeup magic方法在一个对象被反序列化时调用
<?php
class test
{
public $variable = 'BUZZ';
public $variable2= 'OTHER';
public function printvariable()
{
echo $this->variable.'<br/>';
}
public function _wakeup()
{
echo'_wakeup'.'<br/>';
}
public function _sleep()
{
echo'_sleep'.'<br/>';
return array('variable','variable2');
}
}
$object = new test()
//序列化一个对象,会调用_sleep
$serialized=serialize($object);
//输出序列化后的字符串
print 'Serialized:'.$serialized.'<br/>';
//重建对象,会调用_wakeup
$object2 = unserialize($serialized);
//调用printvariable,会输出数据(BUZZ)
$object2->printvariable();
?>
0x03、php反序列化漏洞
序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的且后台不正当的使用了PHP中的魔法函数就会导致安全问题
当传给unserialize()的参数可控时,我们可以通过传入一个精心构造的序列化字符串,从而控制对象内部的变量甚至是函数。
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}