前言: 这几天在做题时发现好多知识点都不会,所以就来补充一下知识,今天就先学习学习反序列化的基础知识。
参考视频:https://www.bilibili.com/video/av41677248?from=search&seid=13170057396150899076
0x01、序列化与反序列化
序列化是将变量转换成可保存或传输的字符串的过程。
反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。
0x02、php序列化与反序列化函数
serialize:可以将变量转换成字符串并且在转换中可以保存当前变量的值。
unserialize:可以将serialize生成的字符串变换回变量。
php进行序列化的目的是保存一个对象方便以后重用。
0x03、对象,类
类是具有相同属性和操作的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。而对象就是类的实例化。
例:
<?php
//创建一个person类
class person
{
//属性变量
public $name='';
public $age=0;
//操作方法
public function display()
{
echo $this->name.' is '.$this->age.' years old.<br/>';
}
}
//创建一个对象
$per=new person();
$per -> name = 'xiaoming';
$per -> age = 18;
$per -> display();
?>
0x04、php序列化实例
4.1、serialize()
序列化一个对象将会保存对象的所有变量,但不会保存对象的方法,只会保存类的名字。
例:
<?php
//创建一个person类
class person
{
//属性变量
public $name='';
public $age=0;
//操作方法
public function display()
{
echo $this->name.' is '.$this->age.' years old.<br/>';
}
}
//创建一个对象
$per=new person();
$per -> name = 'xiaoming';
$per -> age = 18;
echo serialize($per);
?>
4.2、unserialize()
反序列化一个对象,这个对象的类必须已经定义过。
例:
<?php
//创建一个person类
class person
{
//属性变量
public $name='';
public $age=0;
//操作方法
public function display()
{
echo $this->name.' is '.$this->age.' years old.<br/>';
}
}
$per = unserialize('O:6:"person":2:{s:4:"name";s:8:"xiaoming";s:3:"age";i:18;}');
$per -> display();
?>
0x05、php魔法函数
php中包含了一些魔法函数,这些函数可以在脚本的任何地方不用声明就可以使用。
与php(反)序列化有关的魔法函数:
__construct() //当一个对象创建时被调用
__destruct() //对象被销毁时触发
__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__toString //把类当作字符串使用时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
魔法函数前面的 '__'
由两个 '_'
组成。
魔法函数实例:
<?php
class person
{
public $name='';
public $age=0;
public function display()
{
echo $this->name.' is '.$this->age.' years old.<br/>';
}
public function __construct()
{
echo '__construct is executed <br/>';
}
public function __destruct()
{
echo '__destruct is executed <br/>';
}
public function __toString()
{
return '__toString is executed <br/>';
}
}
$per1 = new person();
$per1 -> name ='xiaoming';
$per1 -> age = 18;
echo $per1;
?>
0x06、php反序列化漏洞
php反序列化漏洞又称对象注入,可能会导致注入,远程代码执行等安全问题的发生。
PHP反序列化漏洞产生的原因:
如果一个php代码使用了unserialize函数去调用某一类,该类中会自动执行一些
自定义的magic method,这些magicmethod中如果包含了一些危险操作,或者这
些magic method会去调用类中其他危险操作的函数,如果这些危险操作是我们可
控的,那么久可以进行一些不可描述的操作了。
0x07、总结
当存在php反序列化漏洞时,找一个可控的反序列化函数,通过这个函数去调用一些类,在这些类中可能存在一些魔法函数,在这些魔法函数中可能有一些我们可控的危险操作,我们利用这些危险操作,让程序执行反序列化函数时触发这些的危险操作。