前言
学习对大多数人来说是枯燥的,请静下心来
php反序列化漏洞基础
php反序列化漏洞概述
php反序列化漏洞主要
是由unserialize函数引发而来的(为什么是主要?后面会详细讲解),该漏洞主要发生在反序列化
过程中一些魔术方法的自动调用上,而这些调用可能会超出开发者的预期,造成一定的危害,比如文件读取,RCE(命令执行)、SSRF等等一系列危险的操作(靶机的话可以去BUUCTF、CTFshow等平台上去找,加深理解)。
serialize与unserialize
string serialize( mixed $value)
产生一个可存储的值的表示,返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。 serialize() 可处理除了 resource (资源)之外的任何类型
。甚至可以 serialize() 那些包含了指向其自身引用的数组。(相当于把一张床为了方便放进房间先将其拆分成一些部件)
mixed unserialize( string $str)
unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值,同时既然resource(资源)
不可以被序列化,自然也没有其被反序列化一言 (相当于把床的各种部件组装重新变为床)。
PS:学习总得学会自己去摸索一些新的东西,授人以鱼不如授人以渔,下面是php手册的百度网盘链接(也有较新的版本可以去官网自行查找)
链接:https://pan.baidu.com/s/12DHiSY8a7VeK_92YEHU0Lw?pwd=92xc
提取码:92xc
php序列化代号与释义
代号标记 | 英文解释 | 中文翻译 |
---|---|---|
a | array | 数组 |
b | boolean | 布尔型数据 |
d | double | 双精度浮点型数据 |
i | integer | 整型数据 |
o | common object | 对象,PHP4以后被“O”取代 |
r | reference | 引用 |
s | string | 字符串 |
C | custom object | 自定义对象,PHP5引入 |
O | class | 类 |
N | null | 空值 |
R | pointer reference | 指针引用 |
U | unicode string | unicode字符串 |
下面我们来简单的序列化一个类
<?php
class cat {
public $food;
private $action;
protected $hobby;
public function __construct() {
$this->food = 'fish';
$this->action = 'eat';
$this->hobby = 'play';
}
}
$a = new cat();
echo serialize($a);
运行结果如下:
可以发现三个红框内的属性名的变化
这里我们需要指出,并不是所有的php序列化字符串的各个字符都是完全可见的
上面那个例子中三个属性的修饰符并不一样
当修饰符为public时,序列化后属性名就是属性名
当修饰符为private时,序列化后会变成%00类名%00属性名
,
当修饰符为protected时,序列化后会变成%00*%00属性名
,
(这里的%00为空白符,空字符也有长度,其长度为1,%00虽然不会显示,但是在发送请求时,仍然需要将%00加进去)
所以一般在对含有private
,protected
所修饰的属性时会对序列化结果进行url编码
,在反序列化时也要进行相应的解码
<?php
class cat {
public $food;
private $action;
protected $hobby;
public function __construct() {
$this->food = 'fish';
$this->action = 'eat';
$this->hobby = 'play';
}
}
$a = new cat();
$b = urlencode(serialize($a));
echo $b;
var_dump(unserialize(urldecode($b)));
运行结果如下:
O%3A3%3A%22cat%22%3A3%3A%7Bs%3A4%3A%22food%22%3Bs%3A4%3A%22fish%22%3Bs%3A11%3A%22%00cat%00ac