简介
文件上传是指用户上传了一个可执行脚本,并通过此脚本文件获得了执行服务器端命令的能力。通过就是上传一句话木马,然后通过菜刀来连接服务器。要完成这个攻击,需要下面的三个条件:
1.上传的文件能够被web容器解释执行,所以文件上传后所在的目录要是web容器所覆盖到的路径。
2.用户能够从web上访问这个文件,如果文件上传了,但用户无法通过web访问,或者无法使得web容器解释这个脚本,那也不能称之为漏洞、
3.用户上传的文件没有被安全检查,格式化,图片压缩等功能改变了内容;如果改变了内容则可能导致攻击不成功。
PS:文件上传功能在大多数的web应用中都存在,比如用户头像上传,文章内容的图片,视频,音频,附件上传,一些cms系统上传模板文件,数据库备份文件,插件文件等地方
防御
在实际的测试过程中,我们总是发现程序对上传了文件做了各种限制,导致文件上传不成功。常用的限制文件上传的方式有:
1.黑名单过滤(根据文件扩展名)
2.白名单过滤(根据文件扩展名)
3.检测上传文件的文件头(服务器端MIME类型检测)
4.服务器内容检测,检测是否有恶意代码
5.服务端目录路径检测(检测和path相关的参数)
绕过限制上传
找到了下面的一个图片,总结的挺全的。
1.黑名单方式
1)文件大小写绕过:尝试使用大小写来进行上传,如ASP,PHp等文件名2)名单列表绕过:用名单里没有的名单进行攻击,例如可以上传php2,php3,php4,inc,pwml,asa,cer等文件。
能被解析的文件扩展名列表:
jsp jspx jspf
asp asa cer aspx
php php2 php3 php4 perl(pl)
exe exee
3)特殊文件名绕过:在windows中空格是不允许的,上传文件以后会自动去掉空格,如上传test.asp_(下划线代替空格)4)0x00截断绕过:假如这时候获取到的文件名是 test.asp[�].jpg(asp后面为 0x00) 而在 gettype()函数里处理方式是从后往前扫描扩展名,所以判断为jpg;在很多语言的函数中,比如在c,PHP等语言的常用字符串处理函数中,0x00被认为是终止符。
5).htaccess文件攻击
但是Apache版本高于2.3.9上传.htaccess就不在生效。(实际测试生效)
配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测
该文件仅在Apache平台上存在,IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。该文件的写法如下:
<FilesMatch "_php.gif">
SetHandler application/x-httpd-php
</FilesMatch>
保存为.htaccess文件。该文件的意思是,只要遇到文件名中包含有”_php.gif”字符串的,统一按照php文件来执行。该文件在Apache里默认是启用的,如果没启用,启用方法见:http://www.jb51.net/article/25476.htm 然后就可以上传一个带一句话木马的文件,例如a_php.gif,会被当成php执行。该方法其实不是漏洞,是Apache的特性。该方法常用于黑客入侵网站之后,不想被发现,留一个隐蔽的后门。在PHP手册中提到一句话,move_uploaded_filesection,there is awarning which states‘If the destination file already exists,it will be overwritten.’服务器端如果采用了黑名单的形式限制上传,但是黑名单中却没有.htaccess文件,那么我们可以上传.htaccess文件覆盖掉原来的文件。
6)解析调用/漏洞绕过
这类漏洞直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞。如下面的解析漏洞
Apache解析漏洞:Apache对于文件名的解析是后往前解析的,直到遇到一个Apache认识的文件类型。比如:phpshell.php.rar.rar.rar.rar,Apache不认识rar这个文件类型,所有会一直遍历到php。Apache认识的文件类型定义在Apache的mime.type文件中。(Apache 1.x,2.x)
nginx和iis7.5/7.0解析漏洞
此解析漏洞其实是php的配置错误导致。
php为了支持path info模式创造了fix_pathinfo这个选项,当它被打开时,fpm就会判断请求的文件是否存在,如果不存在就去掉最后一个开始的内容,再次查看文件是否存在,不存在再去掉从开的内容,循环往复。所以当请求http://192.168.1.100/admin/upload/shell.jpg/.php这么个文件时,fpm会把/.php去掉把shell.jpg当作php执行。
后来出现了seccurity.limit_extensions选项,这个选项默认配置.php文件才能被fpm执行。
利用条件:
1、fast-cgi模式运行
2、Fix_pathinfo为1 (默认为1)
3、seccurity.limit_extensions选项允许。(默认只解析.php)
ISS文件解析漏洞:
1);截断,当文件名为abc.asp;xx.jpg时,iis6会将此文件解析为abc.asp。
2)文件夹拓展名出错,导致/*.asp/目录下的所有文件都作为asp文件进行解析。(iss6)
7)PHP CGI路径解析问题:nginx配置fastcgi使用PHP时,会存在文件解析漏洞。
2.白名单检测
1).htaccess文件攻击
白名单检测可以通过.htaccess的文件方式来进行利用
4.文件头检测
1)伪造一个合法的文件头,而将真实的php代码附在合法的文件头以后。图像文件相关信息检测常用的就是 getimagesize()函数
2)我们可以通过抓包,将content-type字段改为image/gif
POST /upload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gif (原为 Content-Type: text/plain)php system($_GET['command']);?>
--xYzZY-
3) 在木马内容基础上再加了一些文件信息,有点像下面的结构
GIF89a phpinfo();
5.文件加载检测
绕过方法:
针对渲染加载测试:代码注入绕过
针对二次渲染测试:攻击文件加载器
6.配合操作系统文件命令规则
(1)上传不符合windows文件命名规则的文件名
1、文件名长度最大为255个英文字符。(或者是127个中文字符+1个英文字符)
2、全路径最大长度最大为260个字符。
3、访问文件不区分大小写(部分应用程序使用时除外),显示文件时有大小写。
4、开头不能使用空格,其他地方可以。
5、文件名不能包含:< > | / * ? :
test.asp.
test.asp(空格)
test.php:1.jpg
test.php::$DATA
shell.php::$DATA…….
会被windows系统自动去掉不符合规则符号后面的内容。
(2)linux下后缀名大小写
在linux下,如果上传php不被解析,可以试试上传pHp后缀的文件名。
1、文件名最大长度为255
2、全路径长度最大为4096(16级最大文件长度)
3、区分大小写
4、除“/”之外所有字符都可以使用
5、linux不以文件扩展名区分文件类型,对linux来说一切皆文件。
7. zip数据包可能导致的问题
1.未处理解压文件
2.为递归检测上传目录导致绕过
3.条件竞争绕过
4.解压产生异常退出实现逃过
5.解压特殊文件实现绕过(../)
绕过方式做一个总结
防止文件上传的方式
在做实际项目的时候,一般我们只会关注7,8,9。
文件权限做控制,上传文件做控制,访问权限做控制。
总结
本篇文章总结了常见的文件上传方式,以及在一些过滤情况下的绕过方式,最后还说了如何通过正确的方式去防止文件上传漏洞。
如果各位大佬有其他好的方式,欢迎交流
原文始发于微信公众号(信安路漫漫):文件上传常见防御与突破总结
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论