WEB安全:文件上传漏洞
文件上传漏洞过程
用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。
一般的情况有:
- 上传文件WEB脚本语言,服务器的WEB容器解释并执行了用户上传的脚本,导致代码执行;
- 上传文件FLASH策略文件crossdomain.xml,以此来控制Flash在该域下的行为;
- 上传文件是病毒、木马文件,攻击者用以诱骗用户或管理员下载执行;
- 上传文件是钓鱼图片或为包含了脚本的图片,某些浏览器会作为脚本执行,实施钓鱼或欺诈;
上传漏洞需要具备以下几个条件:
- 上传的文件具备可执行性或能够影响服务器行为,所以文件后所在的目录必须在WEB容器覆盖的路径之内;
- 用户可以从WEB上访问这个文件,从而使得WEB容器解释执行该文件;
- 上传后的文件必须经过安全检查,不会被格式化、压缩等处理改变其内容;
常见,绕过文件上传检查功能
常见的文件上传检查针对文件类型进行,攻击者可以使用手动修改POST包然后添加%00字节用于截断某些函数对文件名的判断。如xxx.php[\0].JPG,对于一个只允许上传JPG格式的服务器,此文件可以绕过文件上传检查,但是对于服务器端解释来说,函数会被[\0]截断,导致成为xxx.php代码。除了修改文件名来绕过类型检查外,还可以修改文件头来伪造文件头,欺骗文件上传检查。
如何安全上传文件
针对文件上传漏洞的特点和必须具备的三个条件,我们阻断任何一个条件就可以达到组织文件上传攻击的目的:
- 最有效的,将文件上传目录直接设置为不可执行,对于Linux而言,撤销其目录的'x'权限;实际中很多大型网站的上传应用都会放置在独立的存储上作为静态文件处理,一是方便使用缓存加速降低能耗,二是杜绝了脚本执行的可能性;
- 文件类型检查:强烈推荐白名单方式,结合MIME Type、后缀检查等方式;此外对于图片的处理可以使用压缩函数或resize函数,处理图片的同时破坏其包含的HTML代码;
- 使用随机数改写文件名和文件路径,使得用户不能轻易访问自己上传的文件;
- 单独设置文件服务器的域名;
各种形式的文件上传漏洞总结
1.在很早以前,很多上传文件过滤是用的是javascript,所以改一下javascript或直接nc发包就行了。有的是判断后缀,有的只是判断id,比如:
“uploadfile” style=”file” size=”uploadfile” runat= “lbtnUpload” runat= “JavaScript”>
只是简单的对ID进行验证,只要构造javascript:lbtnUpload.click();满足条件达到上传木马的效果。成功以后查看源代码
a “lbtnUpload” “javascript:__doPostBack(‘lbtnUpload’,”)”script ‘javascript’
2.IIS6的目录解析问题如/a.aspx/a.jpg,在某些特殊情况下会应用到,在很早的时候由我同事1982发现的。
3.某些上传文件的被动过滤有缺陷,有的只过滤asp,却忘了.asa、.cdx、cer等等,php的话就尝试php2、.php3、.php4 等等,相关实例有动力文章(Powereasy),具体参考http://www.sebug.net/vulndb/4326/
4.结束符%00截断最后的后缀,最早是老外发现,当时非常流行,主流bbs程序都有此漏洞,比如dvbbs就存在此漏洞,非常经典!
5.iis的文件名解析漏洞,比如a.asp;.gif,分号本身以及后面的都会被系统忽略,国人kevin1986发现的,非常经典!
6.apache文件名解析漏洞,比如a.php.gif或a.php.aaa,最早看到国内的superhei先提出的。不过在新版 apache/php给补了。
7.二次上传漏洞,最新的上传漏洞方法,主要是利用逻辑漏洞,比如无惧无组件上传代码:
view sourceprint?1 fileExt=lcase(Mid(ofile.filename,InStrRev(ofile.filename,".")+1)) arrUpFileType=split(UpFileType,"|")'获得允许上传的所有文件扩展名 for i=0 to ubound(arrUpFileType)'判断上传的文件扩展名是否在允许的范围内 if fileEXT=trim(arrUpFileType(i)) then EnableUpload=true exit for end if
这里的EnableUpload只验证了一次就变为了true,第一次上传合法文件使其变为true,第二次再上传webshell,利用这个漏洞需要上传组件支持一次多文件上传。
有此类逻辑漏洞的不在少数,比如fckeditor最新版中,由于Fckeditor对第一次上传123.asp;123.jpg 这样的格式做了过滤。也就是IIS6解析漏洞。
上传第一次,被过滤为 123_asp;123.jpg 从而无法运行。但是第2次上传同名文件123.asp;123.jpg后。由 于”123_asp;123.jpg”已经存在。
文件名被命名为123.asp;123(1).jpg 123.asp;123(2).jpg这样的编号方式。其他的还有fckeditor 2.4 提交1.php再提交1.php+空格,详见http://superhei.blogbus.com/logs/4603932.html 《又见fckeditor》superhei一文。
8.关键字一次性替换,比如有的后台增加.asa上传类型asa被过滤替换为空字符,但用.asasaa被过滤其中的asa剩下.asa就绕过了, 比如还有科讯Kesion CMS,漏洞在http://localhost/User/UpFileSave.asp?user_upfile.asp,文件名最后保证 是.asachr0.jpg或者.cerchr0.jpg就行了。
9.上传程序存在sql注入。比如fckeditor 2.1.6就可以通过sql注入增加一个.asp上传类型。还有PunBB pun_attachment上传附件扩展sql注射漏洞,详见http://sebug.net/vulndb/12538/。
10.小数点或空格被忽视,这个也是利用了win系统特性了,比如a.asp.和a.asp空格、a.php.
11.超长文件名截断文件后缀,各系统版本的超长文件名长度可能各不相同,最常见的是应用在本地包含漏洞方面,由于php新版过滤了%00,所以用 a.php?files=../../../../../../../../../etc/passwd…………………………………(N个 点).html,推荐用.和/或空格来试。在win下:
echo aaaa>a.asp若干个空格.gif dir a.asp 2010-03-15 17:41 2,852 a.asp
12.只校验了文件头和文件完整性
有的上传程序校验文件头,并只允许上传图片文件类型且验证图片文件完整性(仅伪造文件头还是不行),但没有验证文件后缀,也没有强制更改上传文件的 后缀。我们可以新建一个几kb大小以内的jpg图片文件(颜色填充),然后用ue以十六进制打开文件,在文件内容末尾加些空格后再加上一句话木马< ?fputs(fopen("c.php","w"),"“)?>存为 aaa.php上传。如果有验证文件后缀,也可以结合以上方法绕过文件的后缀验证。