【小白必学】文件上传的漏洞介绍及常见防御方法 您所在的位置:网站首页 php绕过eval过滤 【小白必学】文件上传的漏洞介绍及常见防御方法

【小白必学】文件上传的漏洞介绍及常见防御方法

2023-04-08 23:53| 来源: 网络整理| 查看: 265

01 文件上传漏洞原理

在文件上传的功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力,这就是文件上传漏洞。

02 文件上传漏洞触发点

相册、头像上传、视频、照片分享、附件上传(论坛发帖、邮箱)、文件管理器等。

03 文件上传漏洞的形成条件

文件能够通过前端和后端过滤和文件处理

文件内容不会改变,能够被正确存储

存储位置在Web容器控制范围内

攻击者有权限访问存储目录并有权执行文件

只要破坏了其中的任一条件即可防止文件上传漏洞。

04 文件上传漏洞常见防御方法

0.无防护

以下代码实现了一个简单的文件上传功能

index.html

1 2   3   4 复制代码

上传文件的后端处理,基于Spring Boot

1package com.example.fileuploadvul.Controller; 2 3import org.springframework.stereotype.Controller; 4import org.springframework.web.bind.annotation.PostMapping; 5import org.springframework.web.bind.annotation.RequestParam; 6import org.springframework.web.multipart.MultipartFile; 7 8import java.io.File; 9import java.io.IOException; 10 11@Controller 12public class UploadFile { 13    @PostMapping("/upload") 14    public String uploadFile(@RequestParam("uploadfile")MultipartFile file){ 15//获取文件名 16        String filename = file.getOriginalFilename(); 17        //文件保存路径 18        String path="F:\tmp\"; 19        File outfile = new File(path + filename); 20        try { 21            file.transferTo(outfile); 22        }catch (IOException e){ 23            e.printStackTrace(); 24        } 25        return "success"; 26    } 27} 复制代码

上面的代码没有任何的防护功能,存在文件上传漏洞。用户可以随意的上传任何文件、木马。

1.前端进行js校验

增加攻击成本,该种方式容易被绕过。

javascript示例:

1 2     3     4    

5 6 7 8    function judge(){ 9        var file=document.getElementById("checkfile").value; 10        if (file==null||file==""){ 11            alert("请选择要上传的文件"); 12            // location.reload(true); 13            return false; 14        } 15        var isnext=false; 16        //定义允许上传的文件类型 17        var filetypes=[".jpg",".png"]; 18        //提取上传文件的类型,其中这里需要注意用lastIndexOf而非indexOf,否则会被1.php.php绕过 19        var fileend=file.substring(file.lastIndexOf(".")); 20        //判断上传文件类型是否允许上传写法一 21        for (var i=0;i 复制代码

同时绕过:

1@eval($_POST[cmd]); 复制代码

6.对文件的处理逻辑。

若先将文件放入路径,再去检验文件合法性并删除,会存在条件竞争漏洞。

6.1示例:

1if(isset($_POST['submit'])){ 2    $ext_arr = array('jpg','png','gif'); 3    $file_name = $_FILES['upload_file']['name']; 4    $temp_file = $_FILES['upload_file']['tmp_name']; 5    $file_ext = substr($file_name,strrpos($file_name,".")+1); 6    $upload_file = UPLOAD_PATH . '/' . $file_name; 7 8    if(move_uploaded_file($temp_file, $upload_file)){ 9        if(in_array($file_ext,$ext_arr)){ 10             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; 11             rename($upload_file, $img_path); 12             $is_upload = true; 13        }else{ 14            $msg = "只允许上传.jpg|.png|.gif类型文件!"; 15            unlink($upload_file); 16       } 17    }else{ 18        $msg = '上传出错!'; 19    } 20} 复制代码

先用move_uploaded_file 将上传的文件移动到上传目录,再判断后缀名并就删除文件。

我们多线程异步上传文件A并不断地访问自己上传的文件A,可以文件A进行删除之前,成功执行文件A,

若文件A代码为:

1');?> 复制代码

则执行成功可以生成稳定的shell.php

解决方案:经过充分完整的检查之后再上传。

7.禁止上传文件被执行

7.1存储服务器

将存储上传文件的位置设计在另一台只具备存储功能的文件服务器或数据库上,与Web应用服务器分开,这样即使木马被上传进来,也因为文件服务器不能执行脚本而没有办法实施攻击。

7.2设置权限

改存储上传文件的目录的执行脚本的权限。如linux系统下使用chmod命令修改目录的rwx权限。

7.3修改配置

修改.htaccess、apache的httpd.conf配置文件、Nginx增加配置

7.3.1 .htaccess

1 2Order  allow,deny 3Deny  from  all 4 复制代码

7.3.2 修改apache的配置文件httpd.conf

1 2 3    Order  allow,deny 4    Deny  from  all 5 6 复制代码

7.4 隐藏上传文件路径

示例:使用blob把网站上的全部图片链接加密。

后台返回图片:

1protected void Page_Load(object sender, EventArgs e) 2    { 3        string url = Server.MapPath("~/Images/abg.jpg"); 4        Bitmap b = new Bitmap(url); 5        MemoryStream ms = new MemoryStream(); 6        b.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 7        Response.ClearContent(); 8        Response.ContentType = "image/Jpg"; 9        Response.BinaryWrite(ms.ToArray()); 10    } 复制代码

JavaScript代码:

1     2     3        //创建XMLHttpRequest对象 4        var xhr = new XMLHttpRequest(); 5        //配置请求方式、请求地址以及是否同步 6        xhr.open('POST', '/Default2.aspx', true); 7        //设置请求结果类型为blob 8        xhr.responseType = 'blob'; 9        //请求成功回调函数 10        xhr.onload = function(e) { 11            if (this.status == 200) {//请求成功 12                //获取blob对象 13                var blob = this.response; 14                //获取blob对象地址,并把值赋给容器 15                $("#img1").attr("src", URL.createObjectURL(blob)); 16            } 17        }; 18        xhr.send(); 19     复制代码

回到网页查看img标签src的地址:

图片

8.文件二次渲染

1$is_upload = false; 2$msg = null; 3if (isset($_POST['submit'])){ 4    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径 5    $filename = $_FILES['upload_file']['name']; 6    $filetype = $_FILES['upload_file']['type']; 7    $tmpname = $_FILES['upload_file']['tmp_name']; 8 9    $target_path=UPLOAD_PATH.basename($filename); 10 11    // 获得上传文件的扩展名 12    $fileext= substr(strrchr($filename,"."),1); 13 14    //判断文件后缀与类型,合法才进行上传操作 15    if(($fileext == "jpg") && ($filetype=="image/jpeg")){ 16        if(move_uploaded_file($tmpname,$target_path)) 17        { 18            //使用上传的图片生成新的图片 19            $im = imagecreatefromjpeg($target_path); 20 21            if($im == false){ 22                $msg = "该文件不是jpg格式的图片!"; 23                @unlink($target_path); 24            }else{ 25                //给新图片指定文件名 26                srand(time()); 27                $newfilename = strval(rand()).".jpg"; 28                $newimagepath = UPLOAD_PATH.$newfilename; 29                imagejpeg($im,$newimagepath); 30                //显示二次渲染后的图片(使用用户上传图片生成的新图片) 31                $img_path = UPLOAD_PATH.$newfilename; 32                @unlink($target_path); 33                $is_upload = true; 34            } 35        } else { 36            $msg = "上传出错!"; 37        } 38 39    }else if(($fileext == "png") && ($filetype=="image/png")){ 40        if(move_uploaded_file($tmpname,$target_path)) 41        { 42            //使用上传的图片生成新的图片 43            $im = imagecreatefrompng($target_path); 44 45            if($im == false){ 46                $msg = "该文件不是png格式的图片!"; 47                @unlink($target_path); 48            }else{ 49                 //给新图片指定文件名 50                srand(time()); 51                $newfilename = strval(rand()).".png"; 52                $newimagepath = UPLOAD_PATH.$newfilename; 53                imagepng($im,$newimagepath); 54                //显示二次渲染后的图片(使用用户上传图片生成的新图片) 55                $img_path = UPLOAD_PATH.$newfilename; 56                @unlink($target_path); 57                $is_upload = true;                58            } 59        } else { 60            $msg = "上传出错!"; 61        } 62 63    }else if(($fileext == "gif") && ($filetype=="image/gif")){ 64        if(move_uploaded_file($tmpname,$target_path)) 65        { 66            //使用上传的图片生成新的图片 67            $im = imagecreatefromgif($target_path); 68            if($im == false){ 69                $msg = "该文件不是gif格式的图片!"; 70                @unlink($target_path); 71            }else{ 72                //给新图片指定文件名 73                srand(time()); 74                $newfilename = strval(rand()).".gif"; 75               $newimagepath = UPLOAD_PATH.$newfilename; 76                imagegif($im,$newimagepath); 77                //显示二次渲染后的图片(使用用户上传图片生成的新图片) 78                $img_path = UPLOAD_PATH.$newfilename; 79                @unlink($target_path); 80                $is_upload = true; 81            } 82        } else { 83            $msg = "上传出错!"; 84        } 85    }else{ 86        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!"; 87    } 88} 复制代码

绕过方法:

对比上传前后的两个文件,找到没有变动的区域,插入php代码。

《黑客&网络安全入门&进阶学习资源包》分享 (qq.com)

参考文章:

1https://wiki.wgpsec.org/knowledge/ctf/uploadfile.html 2 3https://blog.csdn.net/cldimd/article/details/104992488 4 5https://github.com/c0ny1/upload-labs 6 7https://juejin.cn/post/6989580413333159949 8 9https://blog.csdn.net/liguangyao213/article/details/123430199 10 11https://blog.csdn.net/qq_43277152/article/details/113373721 12 13https://blog.csdn.net/qq_45570082/article/details/108910162 14 15https://xz.aliyun.com/t/3941 16 17https://blog.csdn.net/weixin_64551911/article/details/124627363?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-124627363-blog-105068212.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-2-124627363-blog-105068212.pc_relevant_recovery_v2&utm_relevant_index=5 18 19等。 复制代码


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有