免责声明:本文所涉及的技术、工具、代码仅用于网络安全学习、靶场练习及授权渗透测试,所有操作均应在合法合规的前提下进行。未经授权对目标系统进行扫描、测试、入侵、攻击等行为,均为违反《中华人民共和国网络安全法》及相关法律法规,后果由操作者自行承担。请恪守网络安全道德准则,梳理正确安全观念,学习安全技术只为守护网络安全。
前言:序列化漏洞是Web安全领域最经典、最高频、最易理解却最难防御的漏洞类型,尤其在PHP生态中,几乎是CTF竞赛、代码审计、实战渗透的必考点。
一、PHP序列化于反序列化核心原理
1.1 基础定义
- 序列化:使用serialize()函数,将变量、数组、对象转化为可储存、可传输的字符串。
- 反序列化:使用unserialize()函数,将序列化字符串还原为原始数据结构。
漏洞本质:用户可控数据直接传入unserialize()函数,攻击者构造恶意序列化字符串,触发代码执行、文件读取、命令执行、权限绕过等危害。
1.2 核心函数
serialize($variable); //变量/对象---->序列化字符串
unserialize($variable); //序列化字符串-->还原为原始数据结构
1.3 序列化格式规则
PHP序列化有固定结构格式,是构造Payload的基础:
- 字符串:s:长度:“值”;
- 整数:i:数值;
- 对象:o:类名长度:“类名”:属性个数:{属性定义};
举例
<?php
echo serialize('yang');
//输出:s:4:"yang";
?>
- s:字符串类型
- 4:字符串长度
- “yang”:字符串内容
二、无类序列化漏洞(入门)
无类序列化不涉及自定义类,仅对普通字符串、数字进行反序列化后比较,是最基础的漏洞形式。
典型题目代码
<?php
error_reportingg(0);
include "flag.php";
$KEY = "yang";
$str = $_GET['x'];
if(unserialize($str) === $KEY){
eoch $flag;
}
show_source(_FILE_);
?>
解题思路
- 对$KEY的值进行序列化
- 通过GET参数传入序列化字符串
- 条件成立直接获取flag
最终Payload
http://xxx.xxx.xxx.xxx/1.php?x=S:5:"yang";
经典陷阱:变量赋值顺序陷阱
<?php
//漏洞代码:$KEY在判断后赋值,实际值为空字符串
if (unserialize($cookie)==="$KEY"){
echo $flag;
}
$KEY = 'ISecer:www.isecer.com';
?>
正确Payload:序列化空字符串
s:0:"";
三、类序列化与魔术方法(漏洞核心)
类序列化是PHP反序列化漏洞的高阶形态,通过自定义类的魔术方法自动触发恶意行为。
3.1 类序列化示例
<?php
class Person{
public $name = 'yang';
public $age = 18;
}
$p = new Person();
echo serialize($p);
//输出:0:6:“Percon”:2:{s:4:“name”;s:5:“derry”;s:3:“age”;i:18;}
?>
3.2 必背魔术方法(漏洞触发点)
魔术方法在特定时机自动调用,是反序列化漏洞的核心利用入口:
| 魔术方法 | 触发时机 | 实战利用价值 |
|---|---|---|
| __construct() | 对象创建时 | 初始化执行 |
| __destruct() | 对象销毁时 | 最高频利用 |
| __wakeup() | 反序列化开始时 | 需绕过(CVE-2016-7124) |
| __sleep() | 序列化时 | 过滤绕过 |
| __toString() | 对象当字符串输出时 | XSS、文件读取 |
| __get() | 访问不可访问属性时 | 代码执行 |
| __set() | 设置不可访问属性时 | 变量篡改 |
| __call() | 调用不存在方法时 | 方法劫持 |
举例:_destruct()触发命令执行
<?php
class Test{
function _desetruct(){
system('whoami');
}
}
//攻击者传入恶意序列化字符串即可执行命令
unserialize($_GET['p']);
?>
四、CVE-2016-7124:_wakeup绕过漏洞
漏洞原理
当序列化字符串中声明的属性个数>真实属性个数时,PHP会跳过_wakeup方法执行。
影响版本
PHP 5<5.6.25;PHP 7<7.0.10
利用方法
原序列化字符串:o : 4 : "name":2:{...}
绕过payload: o : 4 : "name":3:{...}
仅需将属性数量改大即可跳过_wakeup。
五、原生类反序列化漏洞(无自定义类也能利用)
PHP内置原生类自带魔术方法,无需自定义类即可构建Payload,常见于无源码场景。
常用原生类
- Exception/Error:自带_toString()→用于XSS
- SoapClient:可触发SSRF
- DirectoryIterator:可读取文件
举例:原生类XSS利用
<?php
highlight_file(_FILE_);
$a = unseralize($_GET['k']);
echo $a;
?>
构建Payload
<?php
$e = new Exception("<script>alert(1)</script>");
echo urlencode(serialize($e));
?>
传入Payload即可触发XSS。
六、序列化漏洞实战速查技巧
- 漏洞前提:可控数据必须传入unserialize()
- 优先寻找:_destruct()、_wakeup、_toString()
- 属性格式:private/protected需加%00类名%00
- wakeup绕过:直接修改属性个数大于真实属性个数
- 无类利用:优先尝试Exception等原生类
- 比较绕过:区分===强比较与==弱比较类型
七、总结
PHP反序列化漏洞的核心逻辑是:可控数据进入反序列化点→触发魔术方法→执行恶意代码。

9871

被折叠的 条评论
为什么被折叠?



