一文详述文件上传漏洞
字数 2187 2025-08-29 08:29:36
文件上传漏洞全面解析与防御指南
一、漏洞概述
文件上传漏洞是指由于程序员未对上传的文件进行严格的验证和过滤,导致攻击者可以向服务器上传可执行的动态脚本文件(如webshell),从而获取服务器控制权限。
危害
- 控制整个网站甚至服务器
- 上传的恶意脚本(webshell)可以:
- 查看服务器信息
- 浏览目录结构
- 执行系统命令
- 进一步渗透内网
二、文件上传流程
- 客户端准备:用户选择文件
- 上传请求:表单提交文件数据和字段
- 服务器接收:解析HTTP请求,提取文件内容
- PHP中文件信息存储在
$_FILES数组 - 文件内容临时存储在服务器临时目录
- PHP中文件信息存储在
- 文件验证:服务器进行安全性和合法性检查
- 文件存储:验证通过后移动到指定位置
- 响应客户端:返回上传结果
三、PHP中的$_FILES数组
| 键名 | 说明 |
|---|---|
| name | 原始文件名(如example.jpg) |
| type | MIME类型(如image/jpeg),来自HTTP头,不可靠 |
| size | 文件大小(字节) |
| tmp_name | 服务器临时存储路径 |
| error | 错误代码 |
错误代码表
| 值 | 错误代码常量 | 含义 |
|---|---|---|
| 0 | UPLOAD_ERR_OK | 上传成功 |
| 1 | UPLOAD_ERR_INI_SIZE | 超过php.ini限制 |
| 2 | UPLOAD_ERR_FORM_SIZE | 超过HTML表单限制 |
| 3 | UPLOAD_ERR_PARTIAL | 文件部分上传 |
| 4 | UPLOAD_ERR_NO_FILE | 没有文件上传 |
| 6 | UPLOAD_ERR_NO_TMP_DIR | 缺少临时目录 |
| 7 | UPLOAD_ERR_CANT_WRITE | 写入失败 |
| 8 | UPLOAD_ERR_EXTENSION | PHP扩展阻止上传 |
四、漏洞分类
1. 直接文件上传漏洞
- 无任何限制
- 无文件类型、大小、扩展名、内容检查
2. 有条件的文件上传漏洞
- 前端验证不足:仅JS验证,可构造HTTP请求绕过
- 文件头检测缺陷:仅检测Magic Number
- 文件名过滤不严:后缀过滤规则不完善
- 权限认证缺失:匿名用户可上传
- 中间件/系统误配置:如允许.php文件执行
五、常见可执行脚本后缀
| 类型 | 后缀 |
|---|---|
| ASP | .asp, .asa |
| PHP | .php, .php3, .php.a, .phtml |
| ASPX | .aspx, .ashx |
| JSP | .jsp |
| 其他 | .cdx, .cer, .shtml |
六、攻击方法与绕过技术
1. 基础绕过技术
- 前端JS验证绕过:
- 删除前端检测代码
- 先改后缀上传再抓包改回
- Content-Type绕过:伪造MIME类型
- 黑名单绕过:
- 使用中间件支持的其他后缀(如.phtml, .php5)
- 大小写混合(如.PHP)
- 添加空格(如"webshell.php ")
- 文件名末尾加点(如"webshell.php.")
- NTFS交换数据流(如"webshell.php::$DATA")
- 多重后缀(如"webshell.php. .")
- 双写后缀(如"webshell.pphphp")
2. 高级绕过技术
- .htaccess文件攻击:
或<FilesMatch "jpg"> SetHandler application/x-httpd-php </FilesMatch>AddType application/x-httpd-php .jpg - %00截断:
- GET型:
/upload/webshell.php%00 - POST型:需解码%00为null字符
- GET型:
- 图片马:
- 制作:
copy pic.jpg /b + webshell.php /a webshell.jpg - 配合文件包含漏洞使用
- 制作:
- 二次渲染绕过:
- 对比原图和渲染后图片,在不变区域插入代码
- GIF图片效果最佳
- 条件竞争:
- 服务器先移动文件再检查
- 持续上传使webshell在存活期被访问
3. 解析漏洞利用
- Apache解析漏洞:
- 从右向左解析,如
test.php.abc可能被解析为PHP
- 从右向左解析,如
- Nginx解析漏洞:
1.jpg%00php1.jpg/1.php
- PHP CGI漏洞:
- 换行解析(CVE-2017-15715):
xxx.php\x0A
- 换行解析(CVE-2017-15715):
七、防御措施
1. 权限管理与认证
- 严格访问控制,仅允许认证用户上传
- 最小权限原则
2. 上传目录配置
- 禁止执行权限
- 隔离存储
3. 文件类型与内容检测
- 白名单机制(推荐图片格式)
- 验证文件内容(Magic Number)
- 设置合理文件大小限制
4. 文件名处理
- 强制随机重命名
- 统一安全后缀
- 后缀验证
5. 其他措施
- 输入验证与过滤
- 详细日志记录
- 分片上传与临时存储
- 定期安全审查
八、测试方法
- 识别上传接口:头像、编辑器等上传点
- 基础测试:直接上传常见脚本文件
- 绕过测试:
- 修改MIME类型
- 特殊后缀名
- 文件内容混淆
- 批量测试:使用字典测试各种后缀名
测试字典示例:
.php .php5 .php4 .php3 .php2 .html .htm .phtml .pht .pHp .phP .pHp5 .pHp4 .pHp3 .pHp2 .Html .Htm .pHtml .jsp .jspa .jspx .jsw .jsv .jspf .jtml .jSp .jSpx .jSpa .jSw .jSv .jSpf .jHtml .asp .aspx .asa .asax .ascx .ashx .asmx .cer .aSp .aSpx .aSa .aSax .aScx .aShx .aSmx .cEr .sWf .swf .htaccess
通过全面了解文件上传漏洞的原理、攻击方法和防御措施,可以有效提升Web应用的安全性。