一、原理
文件上传漏洞是由于应用程序对用户上传文件文件名、后缀、文件内容、MIME 类型、文件路径校验不严,导致恶意脚本上传至网站目录并被服务器解析执行,进而实现 getshell、控制服务器。
二、探测
1. 手工探测
-
寻找上传点位:头像上传、附件上传、图片上传、文档上传、编辑器上传(FCK、KindEditor、UEditor)。
-
基础测试:
上传txt正常→上传php,观察返回报错(禁止后缀 / 上传成功 / 改名存储)。
上传正常图片1.jpg,记录上传路径、返回 URL。
-
抓包:拦截上传数据包,修改文件名、Content-Type。
2. 工具探测
Burp:上传数据包批量改后缀爆破;
AWVS、Xray、Nessus:自动化扫描上传漏洞;
爬虫爬取全站上传接口
三、利用
前提:恶意文件上传到网站可解析目录(wwwroot、web、upload),且中间件 (Apache/Nginx/IIS) 支持对应脚本解析。
1.直接上传脚本
上传shell.php,访问http://xxx/upload/shell.php执行一句话木马。
<?php @eval($_POST['cmd']);?>
2.图片马 + 文件包含漏洞组合
图片马:1.jpg内嵌入 php 一句话,单独访问无法解析;配合文件包含漏洞?file=upload/1.jpg触发解析。
3.上传大马:体积较大的 webshell,带文件管理、数据库操作。
四、绕过
1.前端 JS 校验绕过
原理:只在浏览器前端用 js 限制后缀,后端无校验
绕过:
- 禁用浏览器 JS 再上传 php;
- Burp 抓包,先传合法 jpg,拦截后修改文件名为 shell.php。
2.黑名单后缀绕过
1.后缀大小写绕过:Shell.PHp、aSp,Windows 系统文件名不区分大小写;
2.空格 / 点绕过(Windows):shell.php. (末尾点 + 空格,系统自动去除末尾点和空格);
3.双写绕过:.pphphp经服务器处理后为.php;
4.Apache解析漏洞:Apache解析文件名从右往左识别,直到识别到可用的后缀名,如.php.hah可绕过对.php的检测并且会被当作.php文件解析;
5..htaccess文件:.htaccess文件是当前目录的分布式配置文件,可上传自定义的.htaccess文件改变解析文件的配置,如修改配置把.jpg文件当作.php文件解析,这时上传的.jpg合法文件会被当作非法的.php文件执行;
AddHandler application/x-httpd-php .jpg .png
6..user.ini文件:.user.ini可配置执行.php文件时自动包含指定文件,如上传配置为包含.jpg文件的.user.ini文件后,访问index.php时将自动包含.jpg文件(版本php>5.3);
//.user.ini文件内容如下在执行.php文件时可自动包含3.jpg文件
auto_prepend_file=3.jpg
7.特殊后缀绕过:.php3/.phtml/.phps/.php5/.pht等后缀名绕过;、
3.白名单后缀绕过
①**%00截断**:服务器解析文件后缀时是从右往左的,而解析文件名时是从左往右的,当文件名中包含%00时,可将通过检测的合法后缀截断并暴露出隐藏在文件名中的非法后缀,从而绕过检测实现非法文件的上传,取截断后文件名存储
如上传的文件hello.php%00.jpg能通过检测并在被截断后当作hello.php文件上传
②0x00截断:原理与%00截断一致,区别是%00截断是针对文件名在url(即get请求)中的绕过,而0x00截断针对文件名在请求体(即post请求)中的绕过
0x00截断并非直接加0x00,而是要加空格%20并将空格对应的20编码改为00(在bp中操作);
原理:0x00 截断字符串,后端取截断前文件名存储
文件名:shell.jpg%00.php,保存为 shell.php
4.MIME校验绕过
(校验 Content-Type: image/jpeg)
| .html文件 | text/html |
|---|---|
| .txt文件 | text/plain |
| .php文件 | application/octer-stream |
| .jpg文件 | image/jpg |
| .png文件 | image/png |
| .gif文件 | image/gif |
数据包修改 Content-Type:
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/jpeg
原本后端限制非图片 MIME 禁止上传,修改 MIME 即可绕过。
5.文件头校验
只校验图片头,如 FFD8FF (JPG)、8950PNG
图片马绕过:
- cmd:copy 1.jpg /b + shell.php /a shell.jpg
- 文件头部添加图片二进制头,后半段写入一句话;
单独访问是图片,配合文件包含、解析漏洞执行脚本。
6.路径可控 / 目录穿越绕过
上传文件名可控,../穿越到网站根目录:文件名改为../shell.php,上传后跳出 upload 目录,保存到网站根目录直接解析。
7.web解析漏洞
Apache:xxx.php.aaaa,从右向左找已知后缀,文件被解析为xxx.php。
Nginx:xxx.jpg/aa.php,xxx.jpg%00.phpNginx 把 jpg 当作 php 解析;
在任意文件名后加/任意文件名.php(或加%00.php)可被解析为.php文件,如hello.jpg加/xx.php(或加%00.php)后可被解析为.php文件;
IIS6.0:目录解析:服务器默认会把.asp目录下的文件都解析为.asp文件,如xx.asp/xx.jpg中xx.jpg会被解析为xx.asp文件
文件解析:服务器默认不解析;号后的内容,如xx.asp;.jpg会被解析为xx.asp文件;
IIS7.0:在任意文件名后加/任意文件名.php可被解析为.php文件,如hello.jpg加/xx.php后可被解析为.php文件
8.二次渲染绕过
网站后端会重新生成缩略图(二次渲染图片),普通图片马被清除 php 代码;
绕过:寻找特殊图片格式(GIF),构造恶意 GIF,二次渲染后恶意代码保留。
五、防御
存储位置隔离:将上传文件的存储位置与服务器分离,以防止恶意文件执行。
文件重命名:上传的文件应重新命名,包括文件名和文件后缀名,以避免直接利用上传文件的漏洞。
使用白名单:只允许:jpg/png/gif/pdf/doc文件上传,黑名单不全面
文件类型检测:使用文件类型检测,如getimagesize和exif\_imagetype,来验证上传文件的真实性。
内容检测:对上传文件的内容进行检测,确保不包含恶意代码