PHP反序列化漏洞研究及原理

前言:

反序列化是OWASP 2017中的一个比较大威胁的漏洞
而且一般安全类的问代码级的漏洞一般会问到这个,所以记录一下。

什么是反序列化?

首先引进两个函数,serialize(序列化函数)和unserialize(反序列化函数)
序列化与反序列化作用:

序列化:

对象转换为字符串的过程

这么讲可能有点晦涩难懂,上代码,看注释应该能看懂
(下图就是将xiaoming对象转化为网页上显示的字符串,这就是序列化)

 <?php
 class student//定义类
 {
	public $username='xiaoming';//定义对象
 }
$s=new student();
$s_serialize=serialize($s);//序列化student
print_r($s_serialize);//输出序列化后的student
echo"</br>";
?>

这段php代码在网站上运行后显示是这样的
在这里插入图片描述

反序列化:

字符串转换为对象的过程
(比如说我要将上面网页上显示的字符串显示为xiaoming对象,这就是反序列化)
代码:

 <?php
 class student//定义类和对象
 {
	public $username='xiaoming';
 }
 $student='O:7:"student":1:{s:8:"username";s:8:"xiaoming";}';//输入序列化后的student
 $s_unserialize=unserialize($student);//反序列化student类
 print_r($s_unserialize);//输出反序列化后的student
 echo"</br>";
?>

这段php代码在网页上显示是这样的:
在这里插入图片描述
这就是序列化与反序列化

漏洞:

那么反序列化漏洞在哪里呢?
反序列化函数unserialize在运行时会调用很多种类函数,比如他调用了wakeup函数(这里写了wakeup函数后显示界面不会发生变化)
wakeup简介:
魔法函数一般是以__开头,通常会因为某些条件而触发不用我们手动调用

 <?php
 class student//定义类和对象
 {
	public $username='xiaoming';

	function __wakeup()//调用wakeup函数
	{
		$myfile=fopen("shell.php","w") or die("unable to open the file!");//打开名叫shell.php的文件,w是以写的形式打开
		fwrite($myfile,$this->username);//fwrite是写,把username的值写入到shell.php文件里
		fclose($myfile);//关闭文件
	}
 }
$s=new student();
$s_serialize=serialize($s);//序列化student
print_r($s_serialize);//输出序列化后的student
echo"</br>";
?>

OK,在简单理解wakeup函数之后呢,我们便很快能够发现问题所在了
因为username的值可以写入到shell.php文件中,那么我们如果构造一个名为<?php phpinfo()?>的username呢?
如果把它写入到shell.php中,再访问shell.php,我们是不是就可以看到网站php的版本等内容了?
话不多说,马上实行

 <?php
 class student//定义类和对象
 {
	public $username='xiaoming';

	function __wakeup()//调用wakeup函数
	{
		echo $this->username."</br>";
		$myfile=fopen("shell.php","w") or die("unable to open the file!");//打开名叫shell.php的文件,w是以写的形式打开
		fwrite($myfile,$this->username);//fwrite是写,把username的值写入到shell.php文件里
		fclose($myfile);
		echo"</br>";
	}
 }
 $student='O:7:"student":1:{s:8:"username";s:18:"<?php phpinfo() ?>";}';//这里把小明改为了phpinfo,以便把phpinfo写入到shell.php中
 $s_unserialize=unserialize($student);
 print_r($s_unserialize);
 echo"</br>";
 
?>

在运行后代码显示的页面如下
在这里插入图片描述
为什么username的值没了呢?
查看源代码后发现是这样,并没有消失
在这里插入图片描述
接下来我们访问shell.php,发现显示了php的版本信息(有些信息打码了)

在这里插入图片描述

附录:

除此之外

__construct() ,__destruct(),__toString(), __sleep() 等等

这几个函数也会构成反序列化漏洞,这里不一一解释了,原理差不多

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值