CMS代码审计之emlog 6.0
字数 1424 2025-08-18 11:37:57
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 语句中,未做任何过滤
关键代码:
// 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;
// ...
}
利用方法:
- 创建文件夹
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 语句:
set global general_log='on';
SET global general_log_file='C:/phpStudy/PHPTutorial/WWW/emlog/eval.php';
SELECT '<?php phpinfo();?>';
- 访问生成的
eval.php文件
4. 存储型 XSS 漏洞
漏洞位置:/admin/link.php
漏洞分析:
- 在添加链接功能中,
siteurl参数仅经过addslashes转义 - 输出时未进行 HTML 实体编码或过滤
- 虽然通过正则检查要求 URL 以
http或ftp开头,但可通过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);//
三、修复建议
-
SQL 注入:
- 对所有用户输入进行严格的过滤和转义
- 使用预处理语句替代直接拼接 SQL
-
文件上传:
- 对解压后的文件内容进行安全检查
- 限制可上传的文件类型
- 设置文件权限
-
数据库备份:
- 限制数据库备份功能的使用权限
- 禁用可能导致安全问题的 SQL 语句
-
XSS 防护:
- 对所有输出到页面的内容进行 HTML 实体编码
- 使用白名单验证 URL 格式
- 过滤危险的协议如
javascript:
四、总结
本次审计发现的漏洞大多需要管理员权限才能利用,实际危害有限。但作为代码审计学习案例,这些漏洞展示了常见的安全问题类型和审计方法。建议开发者遵循安全编码规范,对所有用户输入保持警惕,实施多层防御策略。