文件上传漏洞


前言

现代互联网的Web应用程序中,上传文件是一种常见的功能,因为它有助于提高业务效率,如企业的 OA 系统,允许用户上传图片、视频、头像和许多其他类型的文件。然而向用户提供的功能越多,Web应用受到攻击的风险就越大,如果Web应用存在文件上传漏洞,那么恶意用户就可以利用文件上传漏洞将可执行脚本程序(WebShell)上传到服务器中,获得网站的权限,然后可以进一步对服务器进行入侵,扩大控制权限。

1.提问:什么是文件上传漏洞?
文件上传就是将本地文件上传至服务器上进行保存。其漏洞产生原因是没有对上传的文件进行严格校验,那么可能会导致用户上传脚本文件,然后用户再通过访问这些文件的方式,来达到执行该脚本文件,从而控制服务器的目的。

2.提问:文件上传的业务逻辑?

当我们找到上传的入口,上传文件至服务器上进行保存,可能会回显文件上传的路径,如果回显了文件上传路径,那么我们就可以根据回显的文件上传路径进行访问,那么我们就可以在浏览器中访问到服务器上的这个文件。

3.提问:什么是一句话木马?
一段简单的代码,就相当于植入的木马。这里的php代码:<?php @eval($_POST['shell']);?> 其中shell是一个变量,用post方法获取shell属性值,eval是执行代码。即Web服务器对shell取值以后,然后通过eval()函数执行shell里面的内容。注意POST也可替换成GET,但同时shell的传递方式也要改为GET形式性。
我们在靶场练习的步骤:首先利用一些方法来把这个文件代码上传成功,然后利用一些工具进行测试连接,为shell变量提供变量值,这里的变量值就是一些命令,这样的好处就是省去我们自己敲代码的时间。


一、文件上传的验证机制有哪些?(前端校验、后端校验)

1、前端校验

前端页面在提交上传文件时,会有文件类型的校验,如果不是指定的文件类型,就拒绝提交。解决办法就是可以编辑一下页面JS,或者使用BP工具抓包修改内容就能绕过了。

(1)方法一:修改JS其中关键的检测函数

以第一关为例:
在这里插入图片描述
checkfile()是检测函数,我们把它删除掉即可,改成return true。(如何快速找到checkfile函数:点击左上角的方框箭头,然后点击页面的上传按钮即可。)
在这里插入图片描述

然后上传php文件即可成功。
在这里插入图片描述
右击鼠标,选择复制图像链接。
在这里插入图片描述
打开哥斯拉工具
在这里插入图片描述
在这里插入图片描述

(2)方法二:BP工具

客户端直接发送请求包,我们可以通过Burp抓到正常上传的请求报文后,修改报文的内容后,直接通过Burp发送到服务端,这样就可以跳过网页中JS的验证。将1.png修改成1.php,将content-type类型修改为application/x-php。

在这里插入图片描述

2、后端校验

黑白名单、后端检查的内容、代码逻辑

后端检查文件后缀名之黑名单黑名单限制 - 利用后端解析差异
., 空格,::$DATA
白名单
后端检查Content-Type
后端检查文件头内容
我们据此可以修改响应的内容,进行绕过上传文件。
后缀名大小写绕过
重写绕过
利用操作系统特性绕过
利用缺陷的文件上传验证
文件类型验证缺陷 - 通过不常见的后缀绕过 比如:php3,php5等等
上传目录限制文件类型 - 尝试利用目录遍历将文件上传到其他目录
后缀限制 - 通过.htaccess 欺骗服务器扩展任意自定义文件后缀到已知的MIME类型;利用.user.ini 包含jpg文件到任意已存在php文件中
利用%00绕过PHP
黑名单过滤后缀 - 通过双写绕过
文件内容检查 - 通过添加允许文件头格式绕过
通过条件竞争实现文件上传

二、upload-labs靶场练习

1、第1关(js检测绕过)

在这里插入图片描述
修改前端代码

2、第2关(MIME验证绕过)

(1) 源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

(2)绕过原理与方法

根据代码:

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

可以看出这里是规定了content-type的类型,所以我们上传符合格式的文件:image/png、image/gif。然后利用burp抓包,进而修改filename值(文件后缀名)即可。
在这里插入图片描述
利用bp抓包,将文件后缀名改为php
在这里插入图片描述

(3)总结

注意conten-type类型不需要修改,只需要修改filename值即可。

3、第3关(黑名单验证,特殊后缀)

(1) 源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

如果继续按照第二关做法:
在这里插入图片描述
会出现红色提示。这是因为对文件名后缀有了限制。
在对文件名后缀做处理:转换为小写、去除字符串、首位去空

       
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值