漏洞描述
文件上传是Web应用必备功能之一,如头像上传,附件分享等。如果服务器配置不当或者没有进行足够的过滤,Web用户就可以上传任意文件,包括恶意脚本文件,exe程序等等,这就造成了任意文件上传漏洞。
漏洞原理
大部分的网站和应用系统都有上传功能,而程序员在开发文件上传功能时,并未考虑文件格式后缀的合法性校验或者是否只在前端通过js进行后缀检验。
漏洞危害
可能会导致用户信息泄露,被钓鱼,甚至使攻击者可以直接上传WebShell到服务器,进而得到自己想要的信息和权限。最终达到对数据库执行、服务器文件管理、服务器命令执行等恶意操作,甚至完全控制服务器系统。
上传一个一句话木马的php文件
发现只能上传图片
修改文件的后缀名为.png,然后进行抓包。
修改上传文件的后缀名。
上传成功
使用中国蚁剑进行连接
虚拟终端
clientcheck.php
说明:这里过滤方式是白名单过滤,但是放在了前端进行校验。前端的一切过滤都可以被绕过。
MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型)
是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
MIME 在传输数据时使用两个主要的元素:类型和子类型。前面是数据的大类别,例如声音audio、图像image等,后面定义具体的种类,常见的MIME类型,比如:
超文本标记语言文本.html texthtml
普通文本.txt text/plain
RTF文本.rtf application/rtf
GIF图形.gif image/gif
JPEG图形.ipeg.jpg image/jpeg
说明:服务端会对上传的数据中的content-type字段进行检测,判断其是否为指定的文件格式。
随便上传一个文件,回显出限制上传的文件格式。
这里只能上传jpg,jpeg,png格式的文件,典型的白名单。
这里我们上传一个wuhu.php文件,然后点击开始上传的时候抓包。
修改Content-Type值为:image/jpeg
然后文件就上传成功了,页面显示出了文件的上传路径。
使用中国蚁剑进行连接
servercheck.php
说明:$mime是一个包含合法MIME类型的数组,也就是MIME类型白名单。然后将这个白名单作为参数传入了upload_sick()函数进行服务器端的检测。
uploadfunction.php
upload_sick()函数的定义如下,该函数不安全之处在于两点:
仅检查了MIME类型,可以通过抓包修改进行绕过。
保存文件的时候没有重命名文件,这样即使网页不回显文件保存路径,也有很大概率可以被攻击者猜测到。
如果上传文件的路径被攻击者获得了,那么就可以连接shell了。
使用getimagesize() 进行文件内容检测,只检测文件头部。
文件幻数
getimagesize()函数判断一个文件是否是图片的时候,采用的是文件幻术。
所有的GIF文件都是47 49 46 开头的。
这里我们上传一个以png结尾的一句话木马,然后使用bp抓取数据包,在文件内容里面的头部添加GIF89a。
上传成功
虽然上传成功了,但是现在蚁剑还是连接不上,需要结合文件包含漏洞去实现。
http://192.168.188.183/pikachu/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2023/09/09/76459764fc0cb7785d8730212793.png&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2
蚁剑连接成功
getimagesize.php
说明:指定了两个白名单,$_type是文件后缀名的白名单,$_mime是MIME type的白名单,然后将两个白名单和一些其他参数一起传入到uploadfunction.php文件中的upload()函数。
uploadfunction.php
说明:在upload()函数中使用了getimagesize()方法来判断是否是图片,使用文件幻数也可以进行绕过。
可参考我写的另一篇文章里面对改漏洞有详细说明:任意文件上传。