DVWA文件上传风险防御绕过:双层扩展名与解析风险
【免费下载链接】DVWA 项目地址: https://gitcode.com/gh_mirrors/dvwa/DVWA
一、风险场景与危害
当用户上传头像时,服务器仅验证文件扩展名就允许存储,攻击者可构造shell.php.jpg文件绕过检测,Web服务器若存在解析风险(如Apache对*.php.*文件的错误解析),将执行恶意代码。据OWASP统计,文件上传风险在Web应用漏洞中占比达17.3%,是最容易被利用的高风险漏洞之一。
读完本文你将掌握:
- 4种防御级别代码的安全缺陷分析
- 双层扩展名构造的3种实战技巧
- 解析风险触发的2个核心条件
- 企业级防御方案的5个关键组件
二、防御代码安全缺陷分析
2.1 Low级别:无防御机制
$target_path .= basename($_FILES['uploaded']['name']);
move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path);
缺陷分析:
- 直接使用原始文件名,未过滤扩展名
- 无MIME类型验证
- 无文件内容检测
攻击方式:直接上传shell.php即可执行
2.2 Medium级别:基础过滤失效
if(($uploaded_type == "image/jpeg" || $uploaded_type == "image/png") &&
($uploaded_size < 100000)) {
move_uploaded_file(...);
}
缺陷分析:
- 仅验证
$_FILES['type'](可被篡改) - 未验证文件扩展名
- 无内容检测
绕过方法: 修改HTTP包Content-Type为image/jpeg,上传shell.php
2.3 High级别:扩展名验证漏洞
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1);
if(strtolower($uploaded_ext) == "jpg" || ...) {
if(getimagesize($uploaded_tmp)) {
move_uploaded_file(...);
}
}
缺陷分析:
- 使用
strrpos()提取扩展名存在逻辑漏洞 - 未重命名上传文件
- 未检测文件内容伪装
双层扩展名绕过: 构造文件名shell.php.jpg,strrpos()提取到jpg扩展名通过验证,但服务器可能解析为PHP文件
2.4 Impossible级别:企业级防御
$target_file = md5(uniqid() . $uploaded_name) . '.' . $uploaded_ext;
// 验证扩展名+MIME+内容
if(($uploaded_type == 'image/jpeg' || ...) && getimagesize(...) {
// 图片重新编码
$img = imagecreatefromjpeg($uploaded_tmp);
imagejpeg($img, $temp_file, 100);
imagedestroy($img);
rename($temp_file, $target_path . $target_file);
}
防御机制:
- 文件名随机化(MD5+UUID)
- 多维度验证(扩展名+MIME+内容)
- 图片重新编码(清除恶意代码)
- CSRF令牌保护
三、双层扩展名攻击技术详解
3.1 构造原理
正常文件:image.jpg → 扩展名.jpg
攻击文件:shell.php.jpg → 提取到.jpg扩展名通过验证
实际解析:shell.php.jpg → 服务器可能执行.php部分
3.2 实战构造方法
| 构造方式 | 示例文件名 | 适用场景 |
|---|---|---|
| 基础双层 | shell.php.jpg | Apache解析风险 |
| 空格后缀 | shell.php.jpg[空格] | Windows系统截断 |
| 特殊字符 | shell.php%00.jpg | 空字节截断(PHP<5.3.4) |
3.3 解析风险触发条件
常见解析风险:
- Apache:
*.php.*文件被解析为PHP - Nginx:
*.php后接空格/特殊字符 - IIS:
*.asp;1.jpg被解析为ASP
四、防御方案对比分析
| 防御措施 | Low | Medium | High | Impossible | 有效性 |
|---|---|---|---|---|---|
| 扩展名验证 | ❌ | ❌ | ✅ | ✅ | 基础防护 |
| MIME类型验证 | ❌ | ✅ | ❌ | ✅ | 增强防护 |
| 文件内容检测 | ❌ | ❌ | ✅ | ✅ | 核心防护 |
| 文件名重命名 | ❌ | ❌ | ❌ | ✅ | 关键防护 |
| 文件内容重编码 | ❌ | ❌ | ❌ | ✅ | 终极防护 |
| CSRF保护 | ❌ | ❌ | ❌ | ✅ | 辅助防护 |
五、企业级防御实现方案
5.1 防御架构
5.2 关键代码实现
1. 安全的扩展名验证:
$allowed_exts = ['jpg', 'jpeg', 'png'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if(!in_array($ext, $allowed_exts)) {
die("不允许的文件类型");
}
2. 文件内容重新编码:
// 清除图片中的恶意代码
function sanitize_image($tmp_path, $ext) {
if($ext == 'jpg' || $ext == 'jpeg') {
$img = imagecreatefromjpeg($tmp_path);
imagejpeg($img, $tmp_path, 100);
} elseif($ext == 'png') {
$img = imagecreatefrompng($tmp_path);
imagepng($img, $tmp_path, 9);
}
imagedestroy($img);
return $tmp_path;
}
3. 随机文件名生成:
$safe_filename = md5(uniqid(rand(), true)) . '.' . $ext;
$target_path = UPLOAD_DIR . DIRECTORY_SEPARATOR . $safe_filename;
六、总结与展望
文件上传风险防御是一场持续的攻防对抗,双层扩展名攻击结合服务器解析风险形成了复杂的攻击链。企业应实施纵深防御策略:
- 多维度验证(扩展名+MIME+内容)
- 文件重命名与隔离存储
- 内容重新编码清除恶意代码
- Web服务器安全配置
- 实时监控与日志分析
随着AI技术的发展,基于机器学习的恶意文件检测将成为下一代防御主流,通过分析文件特征、行为模式识别未知威胁。
下期预告:《文件上传风险自动化检测:从黑盒到灰盒测试实战》
点赞+收藏本文,私信"dvwa"获取风险测试靶场搭建指南,包含4个级别的完整测试用例与防御代码库。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



