文件上传漏洞
网站存在文件上传漏洞,以后开发项目如果不注意过滤文件上传的类型,很容易被攻击
一句话木马
asp的一句话木马:
1 | #1.eval使用php函数,例如phpinfo(); |
1 | #2.system使用linux系统命令,例如ls,cp,rm |
php的一句话木马:
1 | #说明REQUEST是在网页端输入变量访问,POST是使用像中国菜刀之类的工具链接 |
什么是文件上传漏洞
文件上传在Web业务中很常见,如用户上传头像、编写文章上传图片等在上传文件时候,未对上传得文件进行严格的验证和过滤,就有可能上传恶意的脚本文件、病毒、木马、webshell,从而控制网站甚至服务器。文件上传漏洞本身有很大的危害,webshell更是将这个漏洞的利用无限扩大。大多数的上传漏洞被利用后攻击者都会留下WebShell以方便后续进入系统。
1.WebShell
以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也叫作网页后门。这些文件与网站服务器web目录下正常网页文件混在一起,然后通过浏览器访问这些后门,得到一个命令执行环境,达到控制目的。
2.web容器
是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如tomcat、apache、nginx。
造成文件上传漏洞的原因
1.对于上传的文件的后缀名没有做较为严格的限制
2.对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法)没有做检查
3.全线上没有对上传的文件目录设置不可执行权限
4.对于web server上传文件或者制定目录的行为没有做限制
服务器解析存在的漏洞
1.IIS解析漏洞
IIS 6.0在解析文件时存在以下两个解析漏洞。
1.当建立.asa、.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析。
例如:建立文件夹parsing.asp,在parsing.asp文件夹内新建一个文本文档test.txt,其内容为<%=NOW()%>,然后在浏览器内访问。
“NOW()”是ASP提供获取当前时间的函数,TXT是文本文档格式,IIS是不会去解析此类文件的,应该会直接显示其内容,而在parsing.asp文件夹中,却被当作ASP脚本来解析。
2.当文件为*.asp;1.jpg时,IIS6.0同样会以ASP脚本来执行,如:新建文件test.asp;1.jpg,内容为<%=NOW()%>。
2.apache解析漏洞
Apache是从右到左开始判断解析,如果为不可识别解析,就再往左判断。如xxx.php.owf.rar ,”.owf”和”.rar”这两种后缀是apache解析不了的,apache就会把xxx.php.owf.rar解析成php。
有些程序开发人员在上传文件时,判断文件名是否是PHP、ASP、ASPX、ASA、CER、ASPX等脚本扩展名,如果是,则不允许上传,这时攻击者就有可能上传1.php.rar等扩展名来绕过程序检测,并配合解析漏洞,获取到WebShell。
在某些情况下,不只是php,就连phtml、pht、php3、php4和php5都是Apache和php认可的php程序的文件后缀。
3.Nginx解析漏洞
1.Nginx版本:
1 | Nginx 0.5.* |
以上Nginx容器的版本下,上传一个在waf白名单之内扩展名的文件shell.jpg,然后以shell.jpg.php进行请求
2.Nginx版本:
1 | Nginx 0.8.41 – 1.5.6: |
以上Nginx容器的版本下,上传一个在waf白名单之内扩展名的文件shell.jpg,然后以shell.jpg%20.php进行请求
绕过上传漏洞
1.客户端检测
使用JavaScript检测,在文件未上传时(数据没有发送出去),就对文件进行验证。
绕过方法
1.使用FileBug浏览器插件
FireBug是删除客户端的JavaScript验证
2.BurpSuite代理工具
使用Burp Suite则是按照正常的流程通过JavaScript验证,然后在传输中的HTTP层做手脚。
首先把木马文件扩展名改为一张正常图片的扩展名,比如JPG扩展名,在上传时使用Burp Suite拦截上传数据,再将其中的扩展名JPG修改为PHP,就可以绕过客户端验。
2.服务器端检测
服务端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,甚至有些程序员检测文件中是否嵌入恶意代码。
(1)白名单与黑名单验证
(1)黑名单过滤方法
规定不允许上传的文件扩展名,用户上传的文件与黑名单匹配,相同则拒绝上传。
(2)白名单过滤方式
规定允许上传的文件扩展名,用户上传的文件与白名单匹配,相同允许上传。白名单往往比黑名单更有效。
(2)MIME验证(检测Content-Type)
MIME:在把输出结果传送到浏览器上的时候,浏览器必须启动应用程序来处理这个输出文档。这可以通过多种类型MIME(多功能网际邮件扩充协议)来完成。
在HTTP中,MIME类型被定义在Content-Type header中。
当用户上传文件到服务器端的时候,服务器端的程序会获取上传文件的MIME类型,然后用这个获取到的类型来和期望的MIME类型进行匹配,如果匹配不上则说明上传的文件不合法。
1.绕过方法
设置检测文件的类型,可以通过burpsuite来修改文件的类型进行过滤即可。
白名单的过滤方式与黑名单恰恰相反,黑名单是定义不允许上传的文件扩展名,而白名单则是定义允许上传的扩展名,白名单拥有比黑名单更好的防御机制。如:$WhiteList=array(rar’,jpg’,png,bmpy,gif,jpg;doc);在获取到文件扩展名后对 WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传。
2.MIME验证
MIME类型用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。如GIF图片MIME为image/gif,CSS文件MIME类型为text/ess。
| 文件后缀 | Mime类型 | 说明 |
|---|---|---|
| .flv | flv/flv-flash | 在线播放 |
| .html或.htm | text/html | 超文本标记语言文本 |
| .rtf | application/rtf | RTF文本 |
| .gif | image/gif | GIF图形 |
| .jpeg或.jpg | image/jpeg | JPEG图形 |
| .au | audio/basic | au声音文件 |
| .mid或.midi | audio/midi或audio/x-midi | MIDI音乐文件 |
| .ra或.ram或.rm | audio/x-pn-realaudio | RealAudio音乐文件 |
| .mpg或.mpeg或.mp3 | video/mpeg | MPEG文件 |
| .avi | video/x-msvideo | AVI文件 |
| .gz | application/x-gzip | GZIP文件 |
| .tar | application/x-tar | TAR文件 |
| .exe | application/octet-stream | 下载文件类型 |
| .rmvb | video/vnd.rn-realvideo | 在线播放 |
| .txt | text/plain | 普通文本 |
| .mrp | application/octet-stream | MRP文件(国内普遍的手机) |
| .ipa | application/iphone-package-archive | IPA文件(IPHONE) |
| .deb | application/x-debian-package-archive | DED文件(IPHONE) |
| .apk | application/vnd.android.package-archive | APK文件(安卓系统) |
| .cab | application/vnd.cab-com-archive | CAB文件(Windows Mobile) |
| .xap | application/x-silverlight-app | XAP文件(Windows Phone 7) |
| .sis | application/vnd.symbian.install-archive | SIS文件(symbian平台) |
| .jar | application/java-archive | JAR文件(JAVA平台手机通用格式) |
| .jad | text/vnd.sun.j2me.app-descriptor | JAD文件(JAVA平台手机通用格式) |
| .sisx | application/vnd.symbian.epoc/x-sisx-app | SISX文件(symbian平台) |
(3)目录验证
在文件上传时,程序通常允许用户将文件放到指定的目录中,然而有些Web开发人员为了让代码更“健壮”,通常会做一个操作,如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入。
(4)0x00截断
因为PHP的底层代码是C语言,在C语言中,“\0”是字符串的结束符,如果用户能够传入“\0”,就能实现截断。
00截断绕过上传限制适用的场景为,后端先获取用户上传文件的文件名,如x.php\00.jpg,再根据文件名获得文件的实际后缀jpg;通过后缀的白名单校验后,最终在保存文件时发生截断,实现上传的文件为x.php。
当文件系统读到0x00时,会认为文件名已经结束。
创建一个名为file.php0x00.jpg的文件,但实际上创建的文件是file.php。