文件上传漏洞绕过与防护
一、前言
文件上传是 Web 渗透中非常常见的高危入口。如果后端对上传文件校验不严格,攻击者可能上传 WebShell、HTML 钓鱼页面、恶意脚本或可被解析执行的文件。
在红队和渗透测试中,文件上传漏洞的价值在于:它可能从一个普通 Web 功能变成服务器命令执行入口。
本文总结文件上传漏洞的判断、绕过思路和防护建议,仅用于靶场和授权环境。
二、常见上传场景
常见功能点:
- 头像上传
- 附件上传
- 富文本图片上传
- 简历上传
- Excel/Word 导入
- 插件上传
- 压缩包上传
- 后台模板上传
常见接口参数:
1 | file |
看到这些功能时,可以重点关注文件类型限制、保存路径、访问路径和是否能被解析执行。
三、漏洞判断流程
1. 上传普通文件
先上传正常图片:
1 | test.jpg |
观察:
- 是否上传成功。
- 返回文件路径。
- 文件是否可访问。
- 文件名是否被重命名。
- 保存目录是否可执行脚本。
2. 测试后缀限制
尝试上传:
1 | test.php |
如果直接上传成功,并且能访问执行,说明风险非常高。
3. 测试内容校验
有些系统只检查文件后缀,不检查内容;有些系统检查 MIME 或文件头。
可以构造图片马:
1 | GIF89a |
如果服务器将该文件作为 PHP 解析,就可能执行其中的 PHP 代码。
四、常见绕过方式
1. 前端校验绕过
如果只在前端 JavaScript 校验文件类型,可以直接用 Burp Suite 修改请求包。
例如前端只允许:
1 | jpg |
可以先选择 1.jpg,拦截请求后改成:
1 | 1.php |
如果后端没有再次校验,就能绕过。
2. MIME 类型绕过
后端可能只判断:
1 | Content-Type: image/jpeg |
上传 PHP 文件时修改请求头:
1 | Content-Type: image/jpeg |
但真实防护不能只依赖 MIME,因为该字段可被客户端控制。
3. 黑名单后缀绕过
如果只禁止 .php,可以尝试:
1 | .phtml |
具体是否解析取决于服务器配置。
4. 双后缀绕过
1 | shell.jpg.php |
有些系统只检查最后一个后缀,有些解析器可能按中间后缀处理,需要结合实际环境判断。
5. 大小写绕过
1 | shell.PHP |
如果后端判断时没有统一转小写,可能被绕过。
6. 文件头绕过
部分系统检查图片文件头,可以在文件开头添加图片标识:
1 | GIF89a |
然后追加脚本内容。
7. 压缩包上传风险
如果系统支持 zip 上传并自动解压,要关注:
- 解压路径是否可控。
- 是否存在 Zip Slip。
- 是否能解压出脚本文件。
- 是否会覆盖已有文件。
Zip Slip 风险示例路径:
1 | ../../../../var/www/html/shell.php |
五、解析漏洞与配置问题
有时上传本身没有问题,真正的问题在 Web 服务器解析配置。
1. 上传目录可执行
上传目录应只存静态资源,不能执行脚本。
高风险配置:
1 | /uploads/shell.php 可以被 PHP 解析 |
2. Nginx 解析配置不当
如果 Nginx 与 PHP-FPM 配置不当,可能出现路径解析问题。
防护重点:
- 严格设置
SCRIPT_FILENAME。 - 禁止上传目录执行 PHP。
- 不将任意路径交给 PHP-FPM。
3. Apache 解析风险
Apache 中如果启用了特殊解析规则,某些多后缀文件可能被当作脚本解析。
例如:
1 | shell.php.jpg |
具体行为取决于配置。
六、上传后利用验证
上传成功后需要确认:
1 | 文件保存路径 |
常见验证内容:
1 | phpinfo(); |
或:
1 | echo "ok"; |
授权测试中不要随意上传破坏性 WebShell,验证风险即可。
七、真实风险
文件上传漏洞可能导致:
- WebShell 写入
- 服务器命令执行
- 网站被篡改
- 钓鱼页面托管
- 内网入口建立
- 敏感文件读取
- 横向移动
在渗透测试报告中,不应只写“上传成功”,而要说明上传后能造成什么影响。
八、防护建议
1. 后端白名单校验
只允许业务需要的类型:
1 | jpg |
不要使用黑名单作为主要防护。
2. 校验文件内容
结合文件头、图片解析库、MIME、扩展名多重判断。
图片上传可以重新编码:
1 | 用户上传图片 -> 服务端重新生成图片 -> 保存新文件 |
这样可以破坏图片马中的脚本内容。
3. 重命名文件
上传后使用随机文件名:
1 | uuid.jpg |
不要保留用户原始文件名。
4. 上传目录禁止执行
Nginx 示例:
1 | location ^~ /uploads/ { |
Apache 可以通过 .htaccess 或主配置禁止脚本执行。
5. 文件存储隔离
- 上传文件放到静态文件服务器。
- 上传目录与代码目录分离。
- 不让上传文件被脚本引擎解析。
6. 权限控制
- 上传目录不给执行权限。
- Web 用户使用低权限账号。
- 限制文件大小。
- 限制上传频率。
九、测试清单
文件上传测试时可以按这个清单走:
1 | 是否只前端校验 |
十、总结
文件上传漏洞的核心不只是“能不能传 PHP”,而是完整判断:
1 | 上传入口 -> 校验逻辑 -> 存储路径 -> 访问路径 -> 解析环境 -> 可造成的影响 |
红队面试中,如果能把上传漏洞从发现、绕过、验证、风险到修复建议说完整,会比单纯背几个后缀更有说服力。