几处cms路径穿越
字数 1090 2025-08-29 08:31:35
CMS路径穿越漏洞分析与防御教学
前言
本教学文档详细分析了几种CMS系统中存在的路径穿越漏洞,这些漏洞可能导致任意文件读取、删除或下载等严重安全问题。所有案例均来自实际审计经验,并已提交CNVD。
漏洞类型一:任意文件读取和删除
漏洞分析
受影响CMS:某持续更新的CMS系统
漏洞位置:后台模板管理功能
关键代码:
function addFile() {
$root = app()->getRootPath() . 'public' . DIRECTORY_SEPARATOR;
$dir = rtrim(I('get.path'));
if (strpos($dir, 'template') === false) {
exit('error|目录错误!');
}
$path = $root . str_replace('/', DIRECTORY_SEPARATOR, $dir);
$info['content'] = file_get_contents($path); // 读取文件内容
}
漏洞原理:
- 系统通过
get.path参数获取用户输入 - 仅检查路径中是否包含"template"字符串
- 直接拼接用户输入到根路径后
- 使用
file_get_contents()读取文件内容
利用方法:
使用template/..进行路径穿越,绕过检查:
原始路径:template/valid/path
攻击路径:template/../../etc/passwd
防御方案
- 使用
realpath()函数解析规范路径 - 检查最终路径是否在允许的目录范围内
- 使用白名单限制可操作的文件类型
- 避免直接拼接用户输入到文件路径
漏洞类型二:任意文件下载
漏洞分析
受影响CMS:某持续更新的CMS系统
漏洞位置:后台数据还原功能中的备份下载
关键代码:
public function downfile(string $name) {
$file_name = $name; // 直接使用用户输入
$file_sub_path = $this->config['path'];
$file_path = $file_sub_path . $file_name; // 直接拼接
$fp = fopen($file_path, "r"); // 打开文件
// ...文件下载逻辑...
}
漏洞原理:
- 文件名参数
$name直接来自用户输入 - 未进行任何过滤或检查
- 直接拼接路径并打开文件
利用方法:
构造恶意文件名进行路径穿越:
正常请求:downfile?name=backup.zip
攻击请求:downfile?name=../../config/database.php
防御方案
- 使用
basename()函数获取文件名部分 - 检查文件扩展名是否在允许范围内
- 限制下载目录为特定备份目录
- 实现文件下载令牌机制
漏洞类型三:两处任意文件删除
漏洞分析
受影响CMS:某已停止更新的老系统
第一处漏洞
漏洞位置:后台附件管理-图片管理
关键代码:
// ids和path参数直接使用
$ids = explode(',', $_POST['ids']);
$this->pagebls['path'] = $_POST['path']; // 未过滤
利用方法:
修改ids参数为:ids=../s,txt
第二处漏洞
漏洞位置:后台模板管理
关键代码:
// id[]参数直接使用
$idd = $_POST['id'];
$this->pagebls['path'] = $_POST['path']; // 未过滤
利用方法:
修改id参数为:id[]=../s.txt
防御方案
- 对所有文件操作参数进行严格过滤
- 实现文件操作前的路径合法性检查
- 限制删除操作只能针对特定目录
- 对敏感操作实施二次确认机制
通用防御措施
-
输入验证:
- 使用白名单而非黑名单
- 对路径参数实施严格正则检查
- 过滤所有特殊字符和路径遍历序列(../)
-
路径处理:
- 使用
realpath()规范化路径 - 检查最终路径是否在允许范围内
- 使用chroot或open_basedir限制访问范围
- 使用
-
权限控制:
- 文件操作使用最低必要权限
- 实现操作日志记录
- 对敏感操作实施多因素认证
-
安全编码:
- 避免直接拼接用户输入到文件路径
- 使用框架提供的安全文件操作函数
- 定期进行代码安全审计
总结
路径穿越漏洞通常源于对用户输入的不当处理,通过严格的输入验证、安全的路径处理方法和最小权限原则,可以有效预防此类漏洞。开发人员应特别注意所有涉及文件操作的代码,确保每个用户提供的路径参数都经过适当验证和过滤。