1.什么是文件上传漏洞?这个网站漏洞的原理是啥?
文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。
当用户点击上传按钮后,后台会对上传的文件进行判断比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。
如果说后台对上传的文件没有进行任何的安全判断或者判断条件不够严谨,则攻击着可能会上传一些恶意的文件,比如一句话木马,从而导致后台服务器被webshell。
和SQL注入漏洞相比较而言,上传漏洞更加危险,因为该漏洞可以直接上传一个WebShell到服务器上。
2.为什么会产生这个漏洞被黑客攻击?最直接的原因是啥?
- 服务器配置不当(iis6.0 put 直接写文件)
- 本地文件上传限制被绕过(javascript验证)
- 服务端过滤不严格被绕过 ()
- 文件路径截断 (0x00)
- 文件解析漏洞导致文件执行(iis,apache,nginx)
- 开源编辑器上传漏洞(fckeditor 自定义文件名,文件夹结合iis6.0解析漏洞,杀伤力*ewebeditor :可以登录后台,配置允许上传的文件类型.asp)
3.怎么发现这个漏洞?怎么去验证漏洞是否存在?怎么利用这个漏洞?
客户端check文件上传
案例:
网页提示只能上传图片!!!
- 浏览选择我们将要上传的脚本文件,还没点击上传按钮网页就弹框提示“上传的文件不符合要求”
这里并没有与后端进行数据传输可以肯定前端JS校验。右键查看网页源代码:
<p class="title">这里只允许上传图片o!</p> <form class="upload" method="post" enctype="multipart/form-data" action=""> <input class="uploadfile" type="file" name="uploadfile" onchange="checkFileExt(this.value)"/><br /> <input class="sub" type="submit" name="submit" value="开始上传" /> </form> </div> </div><!-- /.page-content --> </div> </div><!-- /.main-content --> <script> function checkFileExt(filename) { var flag = false; //状态 var arr = ["jpg","png","gif"]; //取出上传文件的扩展名 var index = filename.lastIndexOf("."); var ext = filename.substr(index+1); //比较 for(var i=0;i<arr.length;i++) { if(ext == arr[i]) { flag = true; //一旦找到合适的,立即退出循环 break; } } //条件判断 if(!flag) { alert("上传的文件不符合要求,请重新选择!"); location.reload(true); } } </script>
分析:
3.选中浏览按钮右键检查元素 ,将 onchange="checkFileExt(this.value)"
删除即可上传成功。
后端代码
<div class="page-content">
<div id="usu_main">
<p class="title">这里只允许上传图片o!</p>
<form class="upload" method="post" enctype="multipart/form-data" action="">
<input class="uploadfile" type="file" name="uploadfile" onchange="checkFileExt(this.value)"/><br />
<input class="sub" type="submit" name="submit" value="开始上传" />
</form>
<?php
echo $html;//输出了路径,暴露了
?>
</div>
</div><!-- /.page-content -->
</div>
</div><!-- /.main-content -->
<script>
function checkFileExt(filename)
{
var flag = false; //状态
var arr = ["jpg","png","gif"];
//取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
//比较
for(var i=0;i<arr.length;i++)
{
if(ext == arr[i])
{
flag = true; //一旦找到合适的,立即退出循环
break;
}
}
//条件判断
if(!flag)
{
alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>
前端校验绕过思路:
- 直接审查元素,删除判断的JS。
- 在上传的过程中BURP截获数据包修改传递内容。
服务端 MIME类型校验
案例:
检测原理:
当用户上传文件到服务器端的时候,服务器端的程序会获取上传文件的MIME类型,然后用这个获取到的类型来和期望的MIME类型进行匹配,如果匹配不上则说明上传的文件不合法。服务端检测MIME类型的代码如下:
// var_dump($_FILES);
$mime=array('image/jpg','image/jpeg','image/png');//指定MIME类型,这里只是对MIME类型做了判断。
$save_path='uploads';//指定在当前目录建立一个目录
$upload=upload_sick('uploadfile',$mime,$save_path);//调用函数
- 网页提示 : 这里只允许上传图片,不要乱搞!浏览选择php脚本进行上传提示:上传的图片只能是jpg,jpeg,png格式的!
- 绕过限制 上传php脚本
有这么一段数据包:
Content-Disposition: form-data; name="uploadfile"; filename="shell.php"
Content-Type: application/octet-stream
因为服务端检测的是文件的MIME类型,而对这个MIME类型的的值的获取是通过HTTP请求字段里的Content-Type字段 ,
所以绕过的方法就是通过修改Content-Type的值,比如修改为image/jpeg;image/png;image/gif等等允许上传类型对应的MIME值。。。。如图
成功
getimagesize()类型验证
检测原理
Getimagesize ( ) 返回结果中有文件大小和文件类型,如果用这个函数来获取类型,从而判
断是否是图片的话,会存在问题。
是否可以绕过呢?可以,因为图片头可以被伪造。
通过头部文件的16进制码来判断
是png/jpg头部的特征。。
绕过思路:
- 伪造图片绕过验证;
制作图片马直接进行上传。上传成功显示路径 文件保存的路径为:uploads/2020/08/08/1849085f2e1e7af13ba546043343.png
- 上传之后。发现没办法对图片直接进行利用。
配合本地文件包含漏洞进行利用。
include进行包含,包含的时候发现有正确的代码,造成执行。
include和require的区别 : 前者遇到错误会警告,程序继续执行。后者遇到语法错误终止程序。
查找路径方法../../一级一级的猜测。
在这里木马都是上传到同级目录里的 。
4.漏洞利用的条件是啥?漏洞危害的范围?漏洞导致的危害有多大?
利用条件
一是文件可上传(感觉这一句是废话)。
二是上传文件路径可知,如果路径不可知就没法访问,亦无法配合诸如文件包含漏洞进行文件执行。
三是上传文件可以被访问。
四是上传文件可以被执行,当然这一步也不是必需的,比如配合文件包含漏洞。
危害
- 网站被控制,对文件增删改查,执行命令,链接数据库
- 如果服务器长久未更新,可以利用exp提权,导致服务器沦陷
- 同服务器的其他网站沦陷
5.如果在甲方公司出现漏洞问题,公司站点受到此攻击,我应该如何快速定位到问题进行修复防止被入侵?
???暂时没有案例
6.如何提前防范这个漏洞?如何做好加固?
- 文件的上传目录设为不可执行
- 可以使用黑名单以及白名单结合的方式限制文件上传
- 使用JS对文件的大小、拓展名进行剑测
- 使用取随机文件名,可以是md5也可以是时间