某开源企业站CMS审计报告
字数 1170 2025-08-29 08:32:30

某开源企业站CMS安全审计报告分析

前言

本文对某国产开源企业级CMS系统进行了详细的安全审计,发现了多个高危漏洞,包括重安装漏洞导致Getshell、SQL注入、任意文件删除等。以下是详细的分析过程和利用方法。

系统入口分析

入口文件index.php关键代码:

<?php
if( !file_exists(dirname(__FILE__) . "/include/config.db.php") ) {
    header("Location:install/index.php");
    exit();
}
require_once( "include/common.inc.php" );
$mod = str_replace( '../', '', $mod );

if( empty( $mod ) ) {
    $mod = 'index';
}

$action_file = WEB_INCLUDE . '/action/' . $mod . '.php';
file_exists($action_file) && require_once($action_file);

$cls_tpl = cls_app:: get_template( $mod );
$cls_tpl->display();
?>

安全观察

  1. $mod = str_replace( '../', '', $mod ); 使用简单的字符串替换来防止目录穿越,但可以使用..././形式绕过
  2. 文件包含限制后缀必须为.php,且前缀固定,无法直接利用伪协议

全局变量注册问题

common.inc.php中存在全局变量注册:

$req_data = array();
foreach( array('_GET', '_POST', '_COOKIE') as $_request ) {
    foreach( 
$$
_request as $_k => $_v ) {
        ${$_k} = _get_request($_v);
        if( '_COOKIE' != $_request ) {
            $req_data[$_k] = _get_request($_v);
        }
    }
}
unset($_GET, $_POST);

风险

  • 将GET、POST、COOKIE参数注册为全局变量,可能导致变量覆盖漏洞

重安装漏洞(Getshell)

漏洞位置

install_action.php中的安装完成处理:

function install_end() {
    //安装收尾
    //把安装文件的名字换了
    @rename('index.php', 'index.php_bak');
}

问题

  • 只重命名了前端文件,后端逻辑文件仍然存在
  • 知道安装文件位置即可重新安装

配置文件写入漏洞

install_action.php中的数据库配置写入:

function write_db_config($db_type, $db_host, $db_name, $db_pass, $db_table, $db_tablepre) {   
    global $db_code;
    $db_config = "";
    $db_config .= "<?php\n\n";
    $db_config .= "\$db_type = '" . $db_type . "';\n";
    $db_config .= "\$db_host = '" . $db_host . "';\n";
    $db_config .= "\$db_name = '" . $db_name . "';\n";
    $db_config .= "\$db_pass = '" . $db_pass . "';\n";
    $db_config .= "\$db_table = '" . $db_table . "';\n";
    $db_config .= "\$db_ut = '" . $db_code . "';\n";
    $db_config .= "\$db_tablepre = '" . $db_tablepre . "';\n\n";
    $db_config .= "?>";
    require_once("../include/class/class.file.php");
    $cls_file = new cls_file('../include/config.db.php');
    $cls_file-> set_text($db_config);
    return $cls_file-> write();
}

利用方法
通过控制tablepre参数注入PHP代码:

tablepre=dcr_qy_';?><?php phpinfo()?>

影响

  • 写入的配置文件会被所有页面包含,相当于后门
  • 可执行任意PHP代码

SQL注入漏洞

install_action.php中存在直接拼接SQL语句:

$db_table = $_POST['table'];
$sql_db_exists = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='$db_table'";

风险

  • 直接拼接用户输入到SQL语句,导致SQL注入

任意文件删除漏洞

漏洞1:文件管理功能

fmanage_action.php中文件删除功能未过滤路径:

action=del_file&cpath=../../../../../../../1.txt

利用方法
通过控制cpath参数删除任意文件

漏洞2:cls_dir类中的删除功能

cache_clear.php引用了cls_dir类:

$cls_dir = new cls_dir();
$cls_dir-> delete_dir( WEB_CACHE  . "/template/{$tpl_dir}" );

利用方法
通过控制tpl_dir参数删除任意目录

失败的审计尝试

数据库连接控制

db.class.php中的构造函数:

function __construct( $db_type, $db_host, $db_name, $db_pass, $db_table, $db_ut ) {
    $this->db_type = $db_type;
    $this->host = $db_host;
    $this->name = $db_name;
    $this->pass = $db_pass;
    $this->table = $db_table;    
    $this->ut = $db_ut;
    if( !$this->conn ) {
        $this->connect();
    }
}

潜在利用思路

  • 如果能控制类实例化参数,可控制数据库连接
  • 结合MySQL任意文件读取漏洞
  • 但审计发现实例化参数不可控

SMTP服务SSRF尝试

class.email.php中的SMTP连接:

function smtp_ok() {
    $response = str_replace("\r\n", "", fgets($this->sock, 512));
    if (!ereg("^[23]", $response)) {
        fputs($this->sock, "QUIT\r\n");
        fgets($this->sock, 512);
        cls_app::log("Error: Remote host returned \"" . $response . "\"\n");
        return false;
    }
    return true;
}

限制

  • 目标服务必须在连接时返回以2或3开头的响应
  • 大多数内网服务不满足此条件

总结与修复建议

高危漏洞总结

  1. 重安装漏洞导致Getshell

    • 安装后未完全删除安装文件
    • 配置文件写入未过滤PHP代码
  2. SQL注入

    • 直接拼接用户输入到SQL语句
  3. 任意文件删除

    • 两处未过滤的文件/目录删除操作

修复建议

  1. 安装完成后完全删除安装目录
  2. 配置文件写入时过滤特殊字符或使用序列化存储
  3. 所有SQL查询使用参数化查询
  4. 文件操作前验证路径合法性
  5. 禁用全局变量注册功能
  6. 加强输入过滤,特别是文件路径相关操作

参考

CMS官网: http://www.dcrcms.com/

某开源企业站CMS安全审计报告分析 前言 本文对某国产开源企业级CMS系统进行了详细的安全审计,发现了多个高危漏洞,包括重安装漏洞导致Getshell、SQL注入、任意文件删除等。以下是详细的分析过程和利用方法。 系统入口分析 入口文件 index.php 关键代码: 安全观察 : $mod = str_replace( '../', '', $mod ); 使用简单的字符串替换来防止目录穿越,但可以使用 ..././ 形式绕过 文件包含限制后缀必须为 .php ,且前缀固定,无法直接利用伪协议 全局变量注册问题 common.inc.php 中存在全局变量注册: 风险 : 将GET、POST、COOKIE参数注册为全局变量,可能导致变量覆盖漏洞 重安装漏洞(Getshell) 漏洞位置 install_action.php 中的安装完成处理: 问题 : 只重命名了前端文件,后端逻辑文件仍然存在 知道安装文件位置即可重新安装 配置文件写入漏洞 install_action.php 中的数据库配置写入: 利用方法 : 通过控制 tablepre 参数注入PHP代码: 影响 : 写入的配置文件会被所有页面包含,相当于后门 可执行任意PHP代码 SQL注入漏洞 install_action.php 中存在直接拼接SQL语句: 风险 : 直接拼接用户输入到SQL语句,导致SQL注入 任意文件删除漏洞 漏洞1:文件管理功能 fmanage_action.php 中文件删除功能未过滤路径: 利用方法 : 通过控制 cpath 参数删除任意文件 漏洞2:cls_ dir类中的删除功能 cache_clear.php 引用了 cls_dir 类: 利用方法 : 通过控制 tpl_dir 参数删除任意目录 失败的审计尝试 数据库连接控制 db.class.php 中的构造函数: 潜在利用思路 : 如果能控制类实例化参数,可控制数据库连接 结合MySQL任意文件读取漏洞 但审计发现实例化参数不可控 SMTP服务SSRF尝试 class.email.php 中的SMTP连接: 限制 : 目标服务必须在连接时返回以2或3开头的响应 大多数内网服务不满足此条件 总结与修复建议 高危漏洞总结 重安装漏洞导致Getshell 安装后未完全删除安装文件 配置文件写入未过滤PHP代码 SQL注入 直接拼接用户输入到SQL语句 任意文件删除 两处未过滤的文件/目录删除操作 修复建议 安装完成后完全删除安装目录 配置文件写入时过滤特殊字符或使用序列化存储 所有SQL查询使用参数化查询 文件操作前验证路径合法性 禁用全局变量注册功能 加强输入过滤,特别是文件路径相关操作 参考 CMS官网: http://www.dcrcms.com/