某CMS快乐审计
字数 1275 2025-08-09 13:33:57
某CMS文件上传漏洞审计与利用教学文档
漏洞概述
本文档详细分析某CMS存在的多个文件上传漏洞点,通过后台功能实现getshell。主要涉及三个功能点的漏洞利用:主题上传、插件列表上传和系统升级上传。
漏洞点分析
1. 常规文件上传防护机制
在admin/controller/Index.php文件中,CMS对文件上传进行了以下防护:
// 文件合法性检查
if (!$this->isValid()) {
$this->error = 'upload illegal files';
return false;
}
// 上传验证
if (!$this->check()) {
return false;
}
防护特点:
- 使用白名单校验文件后缀
- 检查文件合法性
- 无法直接绕过白名单上传恶意文件
2. 通过压缩包上传getshell的三个途径
2.1 主题上传漏洞
路径:系统设置->主题上传
关键代码:
// 实例化ZipArchive类
$zip = new ZipArchive;
// 打开压缩包,使用OVERWRITE或CREATE模式
if ($zip->open($zipFile, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) === TRUE) {
// 解压到指定目录
$zip->extractTo($this->runtime_path . 'transfer/theme/' . $fileName);
$zip->close();
}
利用特点:
- 使用
ZIPARCHIVE::CREATE和ZIPARCHIVE::OVERWRITE模式 - 解压路径为:
/runtime/transfer/theme/zip文件名 - 实际解压文件会出现在:
/public/theme/[主题名]
2.2 插件列表上传漏洞
路径:网站相关->插件列表
关键代码:
// 在admin/controller/index.php#2649
// 首先验证管理员权限
$this->checkUser();
// 解压插件压缩包
$zip = new ZipArchive;
if ($zip->open($filePath) === TRUE) {
$zip->extractTo($this->root_path . 'plugins/' . $pluginName);
$zip->close();
}
利用特点:
- 需要管理员权限
- 自动创建插件存储文件夹
- 解压路径为:
/plugins/[插件名] - 如果插件目录不存在会自动创建
2.3 系统升级上传漏洞
路径:系统设置->系统升级
关键流程:
- 首先调用
upgradepackage方法上传升级包 - 然后调用
upgrading方法处理升级包
关键代码:
// 获取更新文件路径
$updateFile = $this->Catfish->get('update_file_path');
// 解压升级包
$zip = new ZipArchive;
if ($zip->open($updateFile) === TRUE) {
$zip->extractTo($this->root_path);
$zip->close();
}
利用特点:
- 需要分两步操作:先上传,再解压
- 解压路径直接为网站根目录
- 官方升级包结构导致文件解压到根目录
- 可上传包含webshell的伪造升级包
漏洞利用步骤
1. 主题上传getshell
- 登录后台,进入"系统设置->主题"
- 准备包含webshell的zip压缩包(如shell.php)
- 上传压缩包
- 访问webshell路径:
/public/theme/[主题名]/shell.php
2. 插件列表getshell
- 登录管理员账号,进入"网站相关->插件列表"
- 准备包含webshell的zip压缩包
- 上传压缩包
- 访问webshell路径:
/plugins/[插件名]/shell.php
3. 系统升级getshell
- 登录后台,进入"系统设置->系统升级"
- 准备包含webshell的zip压缩包(模拟升级包结构)
- 先调用
upgradepackage方法上传 - 再调用
upgrading方法解压 - 访问webshell路径:
/shell.php(直接位于根目录)
防护建议
-
对解压操作增加以下防护:
- 检查压缩包内文件类型
- 限制解压路径
- 禁止解压php等可执行文件
-
升级ZipArchive使用方式:
// 安全示例
$zip = new ZipArchive;
if ($zip->open($file) === TRUE) {
for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
// 检查每个文件类型
if (preg_match('/\.(php|phtml|htaccess)/i', $filename)) {
die('危险文件类型');
}
}
// 限制解压路径
$zip->extractTo($safe_path);
$zip->close();
}
- 对系统升级功能增加签名验证,确保只处理官方升级包
总结
该CMS存在多处通过压缩包上传导致的getshell漏洞,主要原因是对ZipArchive解压操作缺乏足够的安全检查,特别是:
- 未检查压缩包内文件类型
- 解压路径控制不严格
- 系统升级功能未验证升级包来源
审计此类漏洞时应重点关注所有使用ZipArchive类的地方,特别是涉及解压操作的功能点。