不安全的文件上传漏洞
1.概述
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。 如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
--验证文件类型、后缀名、大小;
--验证文件的上传方式;
--对文件进行一定复杂的重命名;
--不要暴露文件上传后的路径;
--等等...
Unsafe file upload漏洞目录:
- client check 客户端验证
- MIME type 多用途互联网邮件扩展类型
- getmagesize
2.实验演示
我们发现只能上传图片,查看源码,是对文件的扩展名进行了判断
那其实我们是可以直接更改前端代码,比如删掉扩展名判断的函数
然后上传其他类型文件,发现上传成功
当然也可以上传其他木马文件进行攻击!!
多用途互联网邮件扩展类型(MIME),是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定的应用是程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
常见的MIME类型有:
- 超文本标记语言文本 .html text/html
- 普通文本 .txt text/plain
- RTF文本 .rtf image/gif
- JPEG图形 .ipeg .jpg image/jpeg
- GIF图形 .gif image/gif
我分别上传一次允许被上传的图片文件和不允许上传木马文件进行对比
发现Content-Type不一样,那我们就可以通过更改这个值,就可以成功绕过了
(3)getimagesize
getimagesize(string filename) 函数
函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。即函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。
可以看到,High级别的代码读取文件名中最后一个”.”后的字符串, 即取最后一个后缀,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”*.jpg”、”*.jpeg” 、”*.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。
我们尝试上一关的方法
服务端有可能直接判断文件后缀类型了, 我们将后缀改为jpg继续试试:
即使脚本类型为jpg的, 但是当内容非图片格式的时候, 也不能上传。
有两种方法绕过:
- 添加jpg图片的格式头到脚本
GIF89 <?php phpinfo(); ?>
- jpg+php组合拳
用命令:
echo '<?php phpinfo(); ?>' >> 1g.jpg
将一句话木马写到图片1g.jpg的末尾
然后上传即可绕过检测
但是服务器将木马文件解析成了图片文件,因此向其发送执行该文件的请求时,服务器只会返回这个“图片”文件,并不会执行相应命令。我们需要利用 文件包含漏洞 可以将图片格式的文件当做php文件来解析执行:
http://127.0.0.1/pikachu-master/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2020/4/3/4297605e4fd433f3445241700590.jpg&submit=提交查询