关于File Upload的一些思考
字数 1803 2025-08-18 11:39:11
文件上传漏洞绕过技术详解
一、文件上传安全概述
文件上传是Web渗透中最简单直接的方式之一,但实际环境中很少遇到完全不校验的情况。服务端常见的检测点按顺序可分为:
- 前端JS校验
- 防护检测(WAF)
- 服务端检测
本文将重点讲解如何绕过服务端代码的检测。
二、服务端检测的三个关键点
服务端代码通常检测请求包中的三个关键点:
- MIME类型检测
- 文件后缀检测
- 文件内容检测
1. MIME类型检测绕过
MIME类型检测通常只校验HTTP头中的Content-Type字段,绕过方法非常简单:
- 将请求包中的Content-Type字段改为允许的类型,如
image/jpeg - 这种检测方式极其不可靠,因为攻击者可以轻易伪造
示例PHP代码漏洞:
if ($_FILES['file']['type'] == "image/jpeg") {
// 允许上传
}
2. 文件后缀检测绕过
文件后缀检测分为白名单和黑名单两种方式,绕过方法多样:
2.1 服务器解析漏洞
Apache解析漏洞:
- 解析文件时从右往左判断,遇到不认识的后缀就跳过
- 可利用
.php.123形式绕过(取决于配置) - CVE-2017-15715:可使用
%0a换行符绕过
Nginx和IIS7.5/7.0解析漏洞:
- 由PHP配置错误导致(
fix_pathinfo=1) - 请求如
shell.jpg/.php时,FPM会去掉/.php将shell.jpg当作PHP执行 - 利用条件:
- Fast-CGI模式运行
Fix_pathinfo=1(默认)seccurity.limit_extensions选项允许(默认只解析.php)
IIS5.x-6.x解析漏洞:
- 以
*.asp命名的文件夹下所有文件都以ASP执行 *.asp;*.jpg形式会忽略;后的内容
2.2 文件命名规则绕过
Windows命名规则:
- 文件名最大255字符,全路径最大260字符
- 不区分大小写
- 不能包含:
\ / : * ? " < > |等字符 - 分号
;也可用于绕过
Linux命名规则:
- 文件名最大255字符,全路径最大4096字符
- 区分大小写
- 除
/外所有字符都可使用 - 可尝试
\、&&、;等命令分隔符绕过
2.3 00截断
- 使用
%00或0x00表示ASCII的chr(0)(结束符) - 限制条件:
- PHP版本<5.3.4
- JDK版本<1.7.0_40
magic_quotes_gpc=off(未过滤chr(0))
2.4 长度截断
- 当文件名超过系统最大长度时,超出部分会被截断
- 使用二分法测试最大长度
2.5 竞争上传
- 当代码先保存文件再校验时存在时间竞争漏洞
- 上传恶意文件同时不断请求该文件
2.6 双上传
- 当代码只对一处文件名做校验时
- 使用BurpSuite改包或修改前端代码实现双上传
2.7 可解析后缀
不常见的可解析后缀包括:
ph(p[1-7]?|t(ml)?)、shtml、pwmlasa、asax、cer、cdx、aspx、ascx、ashx、asmx、asp{80-90}jspx、jspf、jspa、jsw、jsv、jtml
2.8 .htaccess和user.ini利用
- .htaccess:上传配置文件将图片内容用PHP解析
- user.ini:把图片内容附加在PHP脚本前后(类似
require())
2.9 误用函数
empty()、isset()、strpos()、rename()、iconv()、copy()等函数使用不当可能导致漏洞
3. 文件内容检测绕过
3.1 图片马
- 通过制作图片马绕过文件幻数、文件信息、文件渲染检测
- 生成方法:
copy 1.jpg /b + 2.php /a 3.jpg
3.2 二次渲染绕过
- 二次渲染会去除图片中多余内容(包括恶意代码)
- 需要特殊技术制作能过二次渲染的图片马
三、防御建议
- 使用白名单而非黑名单
- 文件重命名(避免用户控制文件名)
- 限制上传目录的执行权限
- 校验文件内容而不仅依赖扩展名
- 对上传文件进行病毒扫描
- 设置合理的文件大小限制
- 不要信任任何客户端提交的数据
四、总结
文件上传漏洞的绕过技术多种多样,攻击者会利用服务器配置错误、代码逻辑缺陷、系统特性等多种方式进行绕过。防御方需要从多个层面进行防护,不能仅依赖单一检测机制。