介绍

首先php反序列化没有想象中的那么难,你要知道什么是,什么是
魔法方法就很好理解的,先不说反序列化的原理这些

序列化基础

首先我们要知道什么是类,这个需要你们自己去了解了,所以不多说了(随便介绍一下),见谅~

1
class Cls{
2
3
	public $name = '';
4
	public $age  = 0;
5
6
	public function print_name(){
7
8
		echo 'name is -> '.$this->name;
9
		echo "\n";
10
		echo 'age is -> '.$this->age;
11
12
	}
13
14
}
15
16
$my = new Cls(); // 实例化Cls类,就想这个变量是指向了Cls类,可以直接用这个变量操作Cls类
17
$my->name = 'only_free'; // 类中定义了$name属性但他值为空,所以我这里重新赋值
18
$my->age  = 18; // 同上
19
echo $my -> print_name(); // 调用类中的print_name函数

效果:

image_1cjt19n851b6h1lgq14941dmc1gg319.png-125.3kB

序列化这个类

可以看到这里是成功输出了的,那么我们这里来序列化这个类,只需要使用一个函数即可(serialize函数),如下

1
echo "\n".'序列化后到结果:'.serialize($my)."\n";

image_1cjt1gaai1f4219lf1b8dneuvrd1m.png-144.7kB

不懂序列化的作用可以空投到此处:https://blog.csdn.net/wy0123/article/details/79345842

反序列化这个序列化的字符

我们上面那个被序列化后的值为

1
O:3:"Cls":2:{s:4:"name";s:9:"only_free";s:3:"age";i:18;}

那么,我们如何把这些字符都变回类呢,那么就要用到反序列化了,代码如下

1
class Cls{
2
3
	public $name = '';
4
	public $age  = 0;
5
6
	public function print_name(){
7
8
		echo 'name is -> '.$this->name;
9
		echo "\n";
10
		echo 'age is -> '.$this->age;
11
		echo "\n";
12
13
	}
14
15
}
16
17
$xlh = 'O:3:"Cls":2:{s:4:"name";s:9:"only_free";s:3:"age";i:18;}';
18
var_dump( unserialize( $xlh ) );

image_1cjtfje7ueo5ft1pt51sqv4nq2j.png-45.9kB

可以看到我之前定义的$name$age参数都会展示出来的,那么我们再来看下这个反序列化漏洞如何利用

魔术函数介绍

不要想太多为什么他叫魔术函数,其实他就是类中内置(规定好)的函数

首先我们来看看其中一个的__construct()魔术函数可以用来干嘛,代码如下

1
<?php
2
3
class Cls{
4
5
	function __construct(){
6
		echo '使用了__construct()';
7
	}
8
9
}
10
11
$cls = new Cls();
12
echo "\n";

image_1cjtguh609i8dld1lmt5je1sj130.png-61kB

那么这里很容易看明白的了吧,这个__construct魔术方法就是当有变量new这个类的时候就会自动调用,就是说实例化Cls类就会触发__construct方法,那么我序列化是需要用到这个的,下面来看看~

更多的魔术函数可以来这里看看:https://www.cnblogs.com/jakentec/p/3806793.html

序列化漏洞利用

首先,这里漏洞自我感觉还是挺难挖到的(不是难,而是因为利用条件刻薄),待我一一说来~

首先我写了一个小案例(代码执行的漏洞),如下

image_1cjthdab5euv1ltl115bha0pg03q.png-23.8kB

  • bug.php是存在反序列化漏洞的地方
  • class.php是定义一个了一个类(等下会讲的)
  • poc.php是构造的poc

复现过程

1、我们先来看看class.php这个文件

image_1cjtj57j51no91cqb404aoc1isf51.png-89.9kB

可以看到这里有一个类,效果是当这个类被消除的时候就会执行这个函数(当php快要执行完后就会消除这个类,就会执行这个函数),那么我们想,如果我们能够执行这个类,并且把文件名变成任意一个文件的话就可以导致任意文件删除漏洞了,对吧,我们继续来看下

2、查看bug.php里的代码

image_1cjtit7fo10801bc31ihk14411mrs4k.png-136.8kB

3、我们来构造一个利用的poc

前面我们知道了反序列化是可以执行一个类的对吧,那么好玩的来了,我们就可以构造一个操做Delete的类,并且把他要删除的内容为任意一个存在的文件即可,那么我们可以这样

image_1cjtjm38l1m1219f71t951pvn1g0078.png-87.9kB

可以看到我们实例化了类,并且自定义了要删除的文件,然后序列化,并且把序列化的值放入那个反序列化的可控点,我们就可以执行那个删除文件的类,如何我们再自定义文件名,就可以导致任意文件删除了,所以我们现在只要找到反序列(bug.php),然后我们把序列化后的值放上去~

4、将操作类的代码序列化并且放入可控的反序列化处

1
O:6:"Delete":1:{s:4:"file";s:9:"index.php";}

这个是序列化操作类的值,然后放入bug.php文件里

image_1cjvlbe9nikk1f9cpbbk3j7qh9.png-75.8kB

可以看到,我们成功的执行了删除index.php的代码,所以这里是存在反序列化漏洞造成的任意文件删除漏洞~

案例下载地址:

1
链接: https://pan.baidu.com/s/1vbldBSypdozwbqBEYwu1tQ 密码: 6666

总结

所以,反序列化漏洞需要找到一个反序列化可控点,然后找里面类是否使用魔术函数以及类中是否可操作~