文件上传在web中运用非常的广泛,可以说是web开发必备功能,比如注册网站时上传头像,某些论坛中图片,文件上传等,本来这项工能是为了给用户提供方便,但如果因为某些原因产生漏洞,被骇客利用,就会对服务器产生严重破坏。
导致文件上传漏洞的原因有很多,根据网上的资料,我主要找到以下几类:
1、服务器配置不当;
比如:开启http put方法,在没有上传页面的情况下也能上传文件。
2、服务端过滤不严格被绕过;
服务器上对文件上传做了部分过滤或者直接没有过滤导致的文件上传。
比如:采用黑名单过滤.php,但没有过滤.PHp,就会产生漏洞。
3、文件解析导致的文件上传漏洞
比如:Apache的左解析特性,就是当文件的最后一个后缀名无法识别时,向左解析第二个后缀名,就像a.php.xxx,Apache 不认识.xxx所以会直接解析为a.php。
4、文件路径截断
比如:00截断,像1.php%00.jpg上传时过滤器认为你上传的文件后缀名为.jpg,而实际上web解析的时候解析到的是1.php。至于原因在文章后面讲解,莫慌。
5、逻辑漏洞产生文件上传
当然,现在知道了文件上传时个漏洞,也知道了一些产生的原因,那他究竟有多大危害?
当我们利用文件上传漏洞上传了一个webshell并成功连接。接下来就可以修改网页内容;钓鱼,挂马,进行提权;上传系统病毒、木马进行挖矿;控制服务器,搭建跳板进行内网渗透。相比于SQL注入等高危漏洞,文件上传漏洞的危害只强不弱。
网站和web应用程序都是由编程语言所写,所以网站想要将编程语言变为我们看到的web界面就需要解析这些代码,怎么解析?当然是需要对应语言的解释器,比如php解释器。而且网站都有自己可以通过web访问的目录,比如phpstudy的www目录,在这个目录下的文件可以通过url直接访问,当有用户访问的时候,浏览器就会调用解释器去编译执行这个文件。所以,如果我们利用上传漏洞上传了一个.php的木马,然后去访问这个木马就可以以此执行木马文件达到控制目标的作用。
(1)定义
通过JavaScript,HTML5等语言在用户进行了选择,但并未上传的时候对用户选择的文件进行后缀名验证,本身和服务器没有交互,可以通过抓包的方式判断,一般有白名单校验和黑名单校验两种形式。
白名单校验:除了开发者所规定的后缀名外,其他后缀名一律阻拦。
黑名单校验:除了开发者所规定的后缀名校验外,其他后缀名一律通过。
(2)绕过方法
1> 禁用javascript
在chorme浏览器下设置:设置--网站设置--最下面JavaScript--点选不允许网站使用JavaScript
2> 修改客户端代码
有的时候网站上传功能也使用了JavaScript功能,这时我们就不能直接禁用JavaScript。而是需要另寻出路,比如修改一下前端代码。
F12查看源码,找到对应位置,分析过滤方式
如果是白名单过滤,将要上传的文件后缀名加入进去;
如果是黑名单过滤,将要上传的文件后缀名删除;
3>burp抓包
我们创建一个.jpg或.png的图片文件,将内容改为php的木马,然后上传,用burp抓包,并将后缀名改回来,改为.php然后上传。
1、 MIME文件类型绕过
MIME 是什么
MIME:是一个客户端软件,用来区分不同种类的数据,客户端和服务器进行数据传输的时候用MIME来确定接受数据类型和发送数据类型。
一般图片MIME类型有image/jpeg、image/png等,服务端通过HTTP 包的Content-Type字段来判断文件的类型是否合法。
绕过方法:
我们先上传一个正常的图片,burp抓包,查看上传正常图片的MIME值是什么。
然后上传木马(比如:a.php)依旧用burp抓包,将MIME的值改为正常上传图片的值,放包上传就可以绕过检测。
2、 文件头判断
文件头是什么
探讨这个问题之前首先我们得知道,所有的文件最终都是以二进制的形式保存在内存中,不管是.zip还是.png,之所以会被解析为不同的类型,是因为每一个文件都有自己的标志,用来告诉系统自己是何种类型的数据。一般这个标志都在文件的开头位置,我们用十六进制的方式打开就可以看到。
常见的文件头部
GIF:47 49 46 38
png:89 50 4E 47
JPEG:FF D8 FF E0
文件头绕过
有时服务器会检测文件头部的标示,以此来判断是否符合规则,我们只需要在上传之前在文件头之前加上相应的标志码就可以绕过检测。
增加png文件头部之后
网站黑名单过滤中有可能会存在考虑不全而有部分后缀名没有被过滤的情况,或者未考虑大小写情况,比如php4,php5,PHp等。当然,如果上传之后发现无法利用,证明此方法也是不可行的。
1、00截断原理
谈到00截断,一般就是0x00截断,%00截断,但是他们的原理是什么呢?
其实归根结底来说就是解析之后他们的作用,%00被url解析后都变为了字符NULL,相当于是空。也就是说,当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。系统按照16进制读取文件,遇到ascii码为0的地方就停止,而这个ascii码为0的位置在16进制的00位置,0x表示十六进制,所以会截断解析后面的文件名。
%00截断
这里进行了白名单过滤,然后对文件名进行了重构,试试用这个进行绕过
因为这里对上传的图片进行了重命名,所以如果直接修改文件名00截断的话是没有用的,所以我们直接修改save_path这个文件存储路径,可以看到,解析以后%00变为了空,所以系统就会将后面的部分舍弃,变为/upload/shel.php。
0x00截断
图片来自 upload-labs(12-21)通关教程_墨子辰的博客-CSDN博客
这里代码和上一张差不多,使用post方式来进行传输,对图片名进行了重构,所以我们还是从文件路径下手,这里将文件路径改为/upload/a.php+然后打开十六进制。
将+位置改为00 ,这里是16进制表示的,所以0x没有必要。
1、IIS6.0解析漏洞绕过
文件名漏洞:
正常命名:a.jpg
绕过命名:as.asp;.jpg
这种命名方式IIS在解析的时候,会直接打开并用解析器解析。
文件夹名漏洞:
正常命名:../b/a.jpg
绕过命名:../b.asp/a.jpg(或者用00截断也可以)
这种命名方式IIS在解析的时候,会直接打开并用解析器解析。
2、windows系统解析漏洞
windows下回自动忽略掉空格和点,所以我们在绕过的时候,可以选择使用
a.php (空格)或者a.php.绕过上传限制
3、apache左解析漏洞
apache在解析文件的时候如果文件名不认识,比如:a.php.xxx就会向左解析为a.php
可以利用这个漏洞绕过检测机制。
4、nginx解析漏洞
在我们上传了一个图片码,并且通过各种方式拿到图片码路径的时候,就可以用.php的方式解析
比如:上传的图片码为a.jpg,那么访问的时候就可以访问a.jpg/.php就会使用php解析器解析a.jpg。
以上内容是我根据网上大神们的文章加上自己的理解总结的学习笔记,如果有什么错误的地方,希望大家可以帮忙指出。