php反序列化

前言

web的学习由于各种因素鸽了一段时间,正好趁放假时间比较多重新捡一下,有朝花夕拾那感觉了。这篇文章介绍的是web漏洞中比较经典的反序列化漏洞,本文为参考y4tacker的总结而写,点击此处移步到原文。

反序列化简单介绍

序列化是数据传输的一种格式,可以将php中的一些数据结构(如数组、类等)变为字符串进行传输,而反序列化为上述过程的逆过程。

示例程序

1
2
3
4
5
6
7
8
9
<?php
class test{
public $hello="Hello";
public $world="World";
}

$Test=new test();
echo serialize($Test);
?>

程序运行的结果如下:

1
O:4:"test":2:{s:5:"hello";s:5:"Hello";s:5:"world";s:5:"World";}

简单解释

O代表Object——类,后面的4代表类名的长度,紧接着是类名,之后是类成员变量的个数(注意:序列化后的内容只有成员变量,没有成员函数),花括号里面先是成员变量的类型,s代表string——字符串,紧接着是变量名长度,之后是变量名,后面是变量类型,紧接着是变量长度之后是变量的值,后面的以此类推。

注意不同类型(public,private,protected)序列化的不同之处;
注意输出的时候一般需要url编码

魔术方法

这里为方便就直接copy了y4tacker的介绍了:

1
2
3
4
5
6
7
8
9
10
11
__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发

反序列化绕过的一些trick

反序列化字符串逃逸

POP链

原生类利用

phar反序列化

session反序列化


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!