短视频程序源码,文件上传漏洞及防御方法

短视频程序源码,文件上传漏洞及防御方法

一、文件上传漏洞原理

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

二、文件上传漏洞触发点

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

三、文件上传漏洞的形成条件

文件能够通过短视频程序源码前端和后端过滤和文件处理

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

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

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

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

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

无防护

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

index.html

1<form action="/upload" method="post" enctype="multipart/form-data">
2  <input type="file" name="uploadfile" >
3  <input type="submit">
4</form>

 

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

 1package com.example.fileuploadvul.Controller;23import org.springframework.stereotype.Controller;4import org.springframework.web.bind.annotation.PostMapping;5import org.springframework.web.bind.annotation.RequestParam;6import org.springframework.web.multipart.MultipartFile;78import 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<form action="/upload" method="post"  onsubmit="return judge()" enctype="multipart/form-data">2    <input type="file" name="uploadfile" id="checkfile" >3    <input type="submit" value="提交">4    <p id="msg"></p>5</form>6<script type="text/javascript">78    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<filetypes.length;i++){
22            if (filetypes[i]==fileend){
23                isnext=true;
24                break;
25            }
26        }
27        if (!isnext){
28            document.getElementById("msg").innerHTML="文件类型不允许";
29            // location.reload(true);
30            return false;
31        }else {
32            return true;
33        }
34        //判断上传文件类型是否允许上传写法二
35        if (fileend.indexOf(filetypes) == -1) {
36           var errMsg = "该文件不允许上传";
37            alert(errMsg);
38            return false;
39        }
40    }
41</script>

 

绕过方法:

这里限制了只能上传.jpg .png文件,但是攻击者可以用burpsuite拦截修改包进行绕过。

 


如图,上传一个内容为php的jpg文件,然后在此处将filename修改为1.php,即可绕过前端js验证。

 


另外也可以利用插件禁用js后进行提交。

2、名单/黑名单

(1)黑名单
java示例:

 1@Controller2public class UploadFile {3    @PostMapping("/upload")4    public String uploadFile(@RequestParam("uploadfile")MultipartFile file, Model model){5        boolean flag=true;6        String filename = file.getOriginalFilename();7        System.out.println(filename);8        String suffix=filename.substring(filename.lastIndexOf("."));9        String[] blacklist={".jsp",".php",".exe",".dll","vxd","html"};//后缀名黑名单
10        for (String s : blacklist) {
11            if (suffix.equals(s)){
12                flag=false;
13                break;
14            }
15        }
16        if (flag){
17            String path="src\main\resources\static\upload";
18            File fileDir = new File(path);
19            File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
20            try {
21                file.transferTo(outfile);
22                return "success";
23            }catch (IOException e){
24                e.printStackTrace();
25            }
26        }
27        else {
28            model.addAttribute("msg","非法文件类型");
29        }
30        return "index";
31    }
32}

 

php示例:

 1$is_upload = false;2$msg = null;3if (isset($_POST['submit'])) {4    if (file_exists(UPLOAD_PATH)) {5        $deny_ext = array('.asp','.aspx','.php','.jsp');6        $file_name = trim($_FILES['upload_file']['name']);7        $file_name = deldot($file_name);//删除文件名末尾的点8        $file_ext = strrchr($file_name, '.');9        $file_ext = strtolower($file_ext); //转换为小写
10        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
11        $file_ext = trim($file_ext); //收尾去空
12
13        if(!in_array($file_ext, $deny_ext)) {
14            $temp_file = $_FILES['upload_file']['tmp_name'];
15            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
16            if (move_uploaded_file($temp_file,$img_path)) {
17                $is_upload = true;
18            } else {
19                $msg = '上传出错!';
20            }
21        } else {
22            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
23        }
24    } else {
25        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
26    }
27}

 

绕过方法:

 


如图成功上传了phps文件。

黑名单容易出现大小写(pHp)、特殊可解析后缀(pht)、.htaccess、点、空格、::DATA、双写等绕过问题。

另外可能使用Intruder模块进行枚举后缀名,如使用字典

 

 



另外,“判断文件后缀名是否存在黑名单中的字符,将对应的字符串替换为空”这种方式也是不可取的。

String[] blacklist={“jsp”,“php”,“exe”,“dll”,“vxd”,“html”};//后缀名黑名单

1String[] blacklist={"jsp","php","exe","dll","vxd","html"};//后缀名黑名单
2for (String s : blacklist) {
3    if (suffix.indexOf(s)!=-1){
4        suffix=suffix.replace(s,"");//后缀存在黑名单字符串,则将字符串替换为空
5    }
6}

 

这种方式可以通过双写 phphpp 进行绕过。

(2)白名单

java示例:

 1String fileSuffix = fileName.substring(fileName.lastIndexOf("."));2String[] white_suffix = {"gif","jpg","jpeg","png"};3Boolean fsFlag = false;4for (String suffix:white_suffix){5    if (contentType.equalsIgnoreCase(fileSuffix)){6        fsFlag = true;7        break;8    }9}
10if (!fsFlag){
11    return "suffix not allow";
12}

 

php示例:

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

 

对后缀进行白名单限制不易被绕过。

因此建议使用白名单而非黑名单。

3、检查文件类型MIME Type

java示例:

 1//1、MIME检测2    String contentType = file.getContentType();3    String[] white_type = {"image/gif","image/jpeg","image/jpg","image/png"};4    Boolean ctFlag = false;5    for (String suffix:white_type){6        if (contentType.equalsIgnoreCase(suffix)){7            ctFlag = true;8            break;9        }
10    }
11    if (!ctFlag){
12        return "content-type not allow";
13    }

 

php示例:

1if (($_FILES['upload_file']['type'] == 'image/jpeg') || 
2($_FILES['upload_file']['type'] == 'image/png') || 
3($_FILES['upload_file']['type'] == 'image/gif'))

 

增加攻击成本,该种方式容易被绕过。
绕过方法:
如图可以直接修改包。

 


4、使用随机数改写文件名

php示例:

1if(in_array($file_ext,$ext_arr)){
2     $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
3     rename($upload_file, $img_path);
4     $is_upload = true;

 

java示例:

1String uuid = UUID.randomUUID().toString();
2fileName = uuid+fileName.substring(fileName.lastIndexOf("."));

 

能够增加攻击成本,另外可以防范某些特殊名称文件(shell.php.rar.rar)

5、对文件内容进行校验

对文件头进行校验

1.jpg    FF D8 FF E0 00 10 4A 46 49 46
2.gif    47 49 46 38 39 61
3.png    89 50 4E 47

 

以图片为例,可以截取文件的头部几个字节进行校验,如使用getimagesize(不建议使用)

增加攻击成本,易被绕过,攻击者同样可以在文件的头部增加如下字节:

 


对文件内容进行检测

绕过:

1<script language='php'>@eval($_POST[cmd]);</script>

 

绕过php:

1<?= @eval($_POST['cmd']);?>

 

同时绕过:

1<script language='pHp'>@eval($_POST[cmd]);</script>

 

6、对文件的处理逻辑。
若先将文件放入路径,再去检验文件合法性并删除,会存在条件竞争漏洞。

示例:

 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;78    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、禁止上传文件被执行

(1)存储服务器

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

(2)设置权限

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

(3)修改配置

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

htaccess

1<FilesMatch ".(?i:php|php3|php4|php5)">
2Order  allow,deny
3Deny  from  all
4</FilesMatch>

 

修改apache的配置文件httpd.conf

1<Directory D:\wwwroot\public\uploads>
2<FilesMatch ".(?i:php|php3|php4|php5)">
3    Order  allow,deny
4    Deny  from  all
5</FilesMatch>
6</Directory>

 

隐藏上传文件路径

示例:使用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    <img id="img1" src="">2    <script type="text/javascript">3        //创建XMLHttpRequest对象4        var xhr = new XMLHttpRequest();5        //配置请求方式、请求地址以及是否同步6        xhr.open('POST', '/Default2.aspx', true);7        //设置请求结果类型为blob8        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    </script>

 

回到网页查看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'];89    $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代码。

以上就是短视频程序源码,文件上传漏洞及防御方法, 更多内容欢迎关注之后的文章

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/793493.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows11安装Jenkins

Windows11安装Jenkins 1. 下载安装JDK11 从2022年 6 月 28 日发布的 Jenkins 2.357 和2022年9 月发布的 LTS 版本开始,Jenkins 需要 Java 11 才能使用,放弃 Java 8,如果用JDK1.8,那么Jenkins版本需要是2.357版本之前。 JDK11下载渠道oracle官网:https://www.oracle.com/ja…

PART1-Oracle关系数据结构-数据字典与动态性能视图

6. 数据字典与动态性能视图 6.1. 数据字典概述 Oracle数据库的一个重要组成部分是其数据字典,这是一个只读的表集合,提供了有关数据库的管理元数据。数据字典包含如下信息:数据库中每个模式对象的定义,包括列的默认值和完整性约束信息 分配给模式对象的空间量以及当前使用的…

最让程序员破防的12句话,你来补充下一句。

1、这个应该很简单吧,要那么久? 2、之前有一个类似的功能,拿过来改一下就好了。 3、产品说这个功能,已经给客户沟通好了,你想办法看怎么实现。 4、这个需求真的是最终版了。 5、要不我们还是使用上一版设计? 6、先做出来看看,不合适再改。 7、我就要这种效果,怎么实现是…

Delphi怎样安装和配置第三方控件并处理找不到文件

一、提示信息:[dcc64 Error] E1026 File not found: ‘***.res’ 二、解决方法: 1、正解:应当去看官方的安装说明文档,比如若你用自动或手动方式安装和部署TMS FlexCel Studio for VCL and FireMonkey *.*.*.*.exe时,你应当仔细阅读官方的安装说明:http://www.tmssoftwar…

五子棋AI:实现逻辑与相关背景探讨(上)

绪论本合集将详细讲述如何实现基于群只能遗传算法的五子棋AI,采用C++作为底层编程语言 本篇将简要讨论实现思路,并在后续的文中逐一展开了解五子棋 五子棋规则五子棋是一种经典的棋类游戏,规则简单却充满策略性。游戏在一个1919的棋盘上进行(也可以使用1313或1515的棋盘)。…

常用delphi IDE环境配置

目录 常用delphi XE IDE环境配置,大家都需要熟练 一、android SDK : 二、环境变量 User System Overrides :覆盖用户操作系统的全局配置参数:System Variables 操作系统层面的全局变量: 其中:重要的,和自己个性化的: 三、自己的类库路径 四、测试工程默认路径 五、…

如果没有热风枪,如何组合热缩管的5种简单方法

转载自:https://mil.sohu.com/a/779354413_120429259当谈到收缩热缩管时,没有什么比热风枪更好的了。但如果你没有,你该怎么办? 请放心,您仍然可以在没有热风枪的情况下使用热缩管。它可以响应多种热源,因此您可以使用许多替代工具。 在本文中,我列出了一些最流行的热收…

17_电话号码的字母组合

17_电话号码的字母组合 【问题描述】 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。示例一: 输入:digits = "23" 输出:["ad","ae&q…

读软件设计的要素03概念的组合

概念的组合1. 概念的组合 1.1. 概念不像程序那样,可以用较大的包含较小的1.1.1. 每个概念对用户来说都是平等的,软件或系统就是一组串联运行的概念组合1.2. 概念是通过操作来同步组合的1.2.1. 同步并不增加新的概念操作,但会限制已有的操作,从而消除一些独立概念可能会出现…

南沙信C++陈老师解一本通题: 1101:不定方程求解

​ 【题目描述】给定正整数a,b,c。求不定方程 ax+by=c关于未知数x和y的所有非负整数解组数。【输入】一行,包含三个正整数a,b,c 两个整数之间用单个空格隔开。每个数均不大于1000。【输出】一个整数,即不定方程的非负整数解组数。【输入样例】 2 3 18 【输出样例】 4 #in…

musl libc 与 glibc 在 .NET 应用程序中的兼容性

musl Linux 和 glibc 是两种不同的 C 标准库实现,它们在多个方面存在显著差异。历史和使用情况:glibc 是较早且广泛使用的 C 标准库实现,具有较长的开发历史和广泛的社区支持。它被大多数 Linux 发行版采用,特别是在桌面和服务器环境中。 musl 是一个相对较新的实现,旨在提…

JDBC,SQL注入,事务,C3P0于Druid连接池(最详细解析)

JDBCJDBC(Java DataBase Connectivty,Java数据库连接)API,是一种用于执行Sql语句的Java API,可以为关系型数据库提供统一的访问,其由一组Java编写的类和接口组成.JDBC驱动程序起初,SUN公司推出JDBC API希望能适用于所有数据库,但实际中是不可能实现的,各个厂商提供的数据库差异…