File Upload
文件上传漏洞,英文名File Upload,通常是由于对上传文件的类型、内容没有进行严格的过滤、检查,导致攻击者恶意上传木马以便获得服务器的webshell权限。因此文件上传漏洞带来的危害常常是毁灭性的,Apache、Tomcat、Nginx等都曝出过文件上传漏洞。
文件上传漏洞可以说是危害很大了,因为可以直接通过此漏洞getshell。漏洞原因简单点说就是由于开发人员或者网站运维人员的一些失误导致用户上传的文件可以被服务器当作脚本(可执行文件)解析执行。但是想要成功利用这个漏洞至少需要满足三个条件:
1.有效上传点
2.上传文件能够被解析执行
3.上传的文件能够被访问到(路径可知)
Low
我们看一下源码,看是否有相应的防御和过滤(路径如下):
可以看到,服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。
basename(path,suffix) 函数:
函数返回路径中的文件名部分,如果可选参数suffix为空,则返回的文件名包含后缀名,反之不包含后缀名。
我们这里上传php的一句话木马,发现上传成功,口令为liuhui111,并且显示上传的路径。我这里的1.php,里面写入php的一句话木马,关于一句话木马,可以参考我前面的博客:基础知识补充及Sqli-labs Less-5-10:
然后用中国菜刀访问,关于中国菜刀,请参考我前面的博客:基础知识补充及Sqli-labs Less-5-10:
访问之后,菜刀里面会跳出一个新的页面,显现出文件里面的内容:
Medium
我们把等级改为中级,然后进入File Upload页面:
尝试一下上传一句话木马的文件,结果发现报错了:
我们打开代码,发现了其中的一些防御机制:
Medium级别的代码对上传文件的类型、大小做了限制,要求文件类型必须是jpeg或者png,大小不能超过100000B(约为97.6KB)。所以我们当然把文件格式修改为png或者jpeg就行得通了,文件的大小肯定在范围内,因为只有一句话木马。
我们上传文件:
我们打开菜刀,尝试访问新更改的文件,发现访问不了:
因为无法解析一句话木马成php文件,不能成功获取webshell权限,所以我们这里应该使用另外的方法进行绕过:
法一:文件包含+文件上传
中国菜刀的原理是向上传文件发送包含liuhui111参数的post请求,通过控制liuhui111参数来执行不同的命令,而这里服务器将木马文件解析成了图片文件,因此向其发送post请求时,服务器只会返回这个“图片”文件,并不会执行相应命令。
打开中国菜刀,右键添加,在地址栏中输入
http://192.168.1.1/DVWA-master/vulnerabilities/fi/?page=hthttp://tp://192.168.1.1/DVWA-master/hackable/uploads/1.png
参数名为liuhui111,脚本语言选择php:
然后拿到webshell:
法二:抓包修改文件类型
上传1.png,然后用Burp Suite抓包,
把图中标记的部分的文件类型,修改为php,然后点Forward把数据包发送:
然后我们打开菜刀,获取web shell权限:
法三:截断绕过规则
在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,可以在文件名中使用%00截断,所以可以把上传文件命名为1.php%00.png。然后我们上传文件,并使用代理在Burp Suite上面抓包,我们看到文件类型的信息还是image/png,而文件名已经变为新更改的1.php%00.png:
我们点击Forward把数据包放过去,然后在DVWA上面查看结果,发现上传成功:
接下来还是使用中国菜刀获取为web shell,不再赘述。
High
还是一样,修改等级后上传一下,看看能不能上传成功,发现果然不行,提示我们上传的文件还是只能是图片格式:
没有办法,我们打开源码看看它是如何防御的:
里面使用了一系列的函数,所以我们需要了解一下这些函数的作用:
strrpos(string,find,start)
函数返回字符串find在另一字符串string中最后一次出现的位置,如果没有找到字符串则返回false,可选参数start规定在何处开始搜索。
getimagesize(string filename)
函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
可以看到,High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”*.jpg”、”*.jpeg” 、”*.png”之一。同时,getimagesize()函数更是限制了上传文件的文件头必须为图像类型。所以有一件事可以确定,我们要想办法绕过获取web shell,但是必须上传图片格式的文件,这是无法避免的,所以我们有如下方法可以使用:
法一:伪装文件头
我们需要将上传文件的文件头伪装成图片,从而绕过上传文件的格式限制。找一张真正的图片,命名为1.jpg,木马文件命名为2.php首先利用copy命令将一句话木马文件2.php与正常的图片文件1.jpg合并(事实上我这里在C盘中就有一张图片名为1.jpg,我在相同目录下的1.php里加了一句话木马)
打开cmd 输入 copy 1.jpg/b+2.php/a 3.jpg (注: 1.jpg是图片,2.php是一句话木马,3.jpg就是含有木马的图片):
我们发现已经存在新的文件3.jpg了:
然后我们发现上传3.jpg成功了,没有被拦截,接下来用菜刀访问不再赘述。
法二:找个图片,用记事本打开,添加一句话木马
我们把3.jpg文件格式改为txt,以文本形式打开,发现了有意思的事:
后面出现了一句话木马,细细一想也是,没有一句话木马我们无法得到web shell,那么我们直接在图片的文本最后加一句话木马不就行了吗,事实证明可行,这里不再赘述。
Impossible
in_get(varname)
函数返回相应选项的值
imagecreatefromjpeg ( filename )
函数返回图片文件的图像标识,失败返回false
imagejpeg ( image , filename , quality)
从image图像以filename为文件名创建一个JPEG图像,可选参数quality,范围从0(最差质量,文件更小)到100(最佳质量,文件最大)。
imagedestroy( img )
函数销毁图像资源
可以看到,Impossible级别的代码对上传文件进行了重命名(为md5值,导致%00截断无法绕过过滤规则),加入Anti-CSRF token防护CSRF攻击,同时对文件的内容作了严格的检查,导致攻击者无法上传含有恶意脚本的文件。