ClassCMS1.3自解压任意文件上传漏洞分析
字数 1248 2025-08-03 10:57:09
ClassCMS1.3自解压任意文件上传漏洞分析
0x01 漏洞概述
ClassCMS1.3存在一个自解压任意文件上传漏洞,攻击者可通过构造恶意请求上传任意文件(如PHP木马),从而获取服务器权限。该漏洞源于对请求URL过滤不严谨以及逻辑处理存在缺陷。
0x02 环境搭建
-
准备环境:
- PHPStudy 2016版本
- PHP 5.6.27
-
部署步骤:
- 部署CMS源码
- 访问
http://[IP]/index.php进行安装 - 输入配置信息(需提前新建好数据库)
0x03 漏洞复现步骤
-
登录后台
-
进入"应用商店"主页
-
选择任意应用,点击"下载"
-
抓包修改请求:
- 第二个数据包通过URL参数传递下载链接
- 解码后可看到请求下载1.0版本的zip包
-
攻击准备:
- 创建包含一句话木马的PHP文件并压缩为zip
- 使用Python开启HTTP服务:
python -m SimpleHTTPServer 80 - 修改请求中的URL为恶意zip包链接
- 修改
classhash参数(作为解压目录名,需唯一)
-
上传结果:
- 木马上传成功路径:
http://[IP]/class/[classhash]/1.php - 执行命令:
http://192.168.150.9/class/test123/1.php?1=phpinfo();
- 木马上传成功路径:
0x04 漏洞分析
关键代码路径
- 入口文件:
index.php→ 包含cms.php - 路由文件:
route.php- 路由规则:
文件:方法:参数 - 漏洞触发路径:
shop/shop.php的downloadClass方法
- 路由规则:
漏洞函数分析
function downloadClass() {
// 1. 检查classhash参数格式
if(!is_hash(@$_POST['classhash'])) {
Return ;
}
$classhash=$_POST['classhash'];
$url=$_POST['url'];
// 2. 检查是否已存在相同classhash
if(C('cms:class:get',$classhash)) {
echo(json_encode(array('msg'=>'应用已存在','error'=>1)));
Return ;
}
// 3. 检查服务器环境
if (!function_exists("curl_init")){
echo(json_encode(array('msg'=>"服务器未安装Curl组件,无法下载应用文件",'error'=>1)));
Return ;
}
if(!function_exists('zip_open') || !class_exists('ZipArchive')) {
echo(json_encode(array('msg'=>"未安装zip组件,无法解压安装包",'error'=>1)));
Return ;
}
// 4. 设置解压路径
$classdir=classDir($classhash);
$path=$GLOBALS['C']['SystemRoot'].$GLOBALS['C']['CacheDir'].DIRECTORY_SEPARATOR.'shop'.DIRECTORY_SEPARATOR;
// 5. 下载文件
if(!C('this:download',$url,$classfile)) {
echo(json_encode(array('msg'=>"下载失败",'error'=>1)));
Return ;
}
// 6. 解压文件
if(C('cms:class:unzip',$classfile,$classdir)) {
@unlink($classfile);
if(C('cms:class:refresh',$classhash)) {
echo(json_encode(array('msg'=>"下载完成,请在应用管理页面中安装此应用")));
Return ;
}else {
echo(json_encode(array('msg'=>"安装包格式错误,请重试",'error'=>1)));
Return ;
}
}else{
@unlink($classfile);
echo(json_encode(array('msg'=>"安装包解压失败,请重试",'error'=>1)));
Return ;
}
}
关键漏洞点
-
URL参数未过滤:
- 攻击者可完全控制
$_POST['url']参数 - 可指定任意远程zip文件URL
- 攻击者可完全控制
-
解压函数无过滤:
cms/class.php中的unzip方法直接使用ZipArchive或zip_open解压- 未检查压缩包内容是否合法
-
refresh方法验证缺陷:
is_hash()函数验证不严格:/^[A-Za-z]{1}[A-Za-z0-9_]{0,31}$/- 即使验证失败,文件已被解压到服务器
0x05 漏洞修复建议
-
对
$_POST['url']参数进行严格过滤:- 限制只能下载特定域名或路径的文件
- 检查文件扩展名
-
解压前验证压缩包内容:
- 检查压缩包内文件类型
- 禁止解压PHP等可执行文件
-
加强
is_hash()验证:- 使用更严格的正则表达式
- 解压前验证目录名合法性
-
设置解压目录权限:
- 限制解压目录的写入权限
- 禁止从解压目录执行PHP文件
0x06 总结
该漏洞利用链清晰:
- 通过应用商店功能触发下载
- 控制下载URL指向恶意zip包
- 利用解压功能将恶意文件释放到服务器
- 通过web直接访问上传的恶意文件
漏洞的根本原因在于对用户输入缺乏充分验证,特别是在文件操作相关功能中。开发时应遵循"不信任任何用户输入"的原则,对所有可能影响系统安全的操作进行严格验证。