文件上传/JS/MIME/黑名单/白名单/htaccess/00截断详解篇[代码审计]

文件上传漏洞定义

        文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力,这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理,解析文件,如果服务器的处理逻辑做的不够安全,则会导致严重的后果

文件上传漏洞危害

  1.         上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行
  2.         上传文件是病毒或者木马时,主要用于诱骗用户或者管理员下载执行或者直接自动运行
  3.         上传文件是Flash的策略文件crossdomain.xml,黑客用以Flash在该域下的行为(其他通过类似方式控制策略文件的情况类似)
  4.         上传文件是钓鱼图片或为了包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈,除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢出服务器的后台处理程序,如图片解析模块;或者上传一个合法的文本文件,其内容包含了PHP脚本,再通过"本地文件包含漏洞(Local File Include)"执行此脚本

上传漏洞产生原因

        一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以上传的地方将恶意代码植入到服务器中,再通过url去访问可以执行代码

                造成文件上传漏洞的原因是:

                        服务器配置不当

                        开源编辑器上传漏洞

                        本地文件上传限制被绕过

                        过滤不严格被绕过

                        文件解析漏洞导致文件执行(文件包含漏洞)

                        文件路径截断(00截断)

JS前端验证绕过

        客户端校验:一般都是再网页上写一段JavaScript脚本,校验上传文件的后缀名,只有白名单形式也有黑名单形式,判断方式:在浏览器加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包

        js源代码分析

<script type="text/javascript">
    function cheakFile(){      
        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;
        }
    }
</script>

document.getElementsByName('upload_file')[0].value

  • 意思返回带有指定名称的对象 该对象在from标签已经被定义        
<from acrion="index.php" method="post" enctype="multipart/form-data" name="upload_file" onsunbmit = "return checkFile()">
  • var后面跟自定义函数值

file.substring(file.lastIndexOf("."));

  • substring()方法用于提取字符串中介于两个下标就是说不显示配合lastIndexOf返回一个指定的字符串值最后出现的位置,在一个字符串中指定位置从后向前搜索

if(allow_ext.indexOf(ext_name) == -1)

        indexOf方法可返回某个指定的字符串值在首次出现的位置

                如果要检索的字符串没有出现.则该方法返回-1

                如果文件里面没有.jpg|.png|.gif则执行var errMsg="该文件不允许上传...."

ext_name=file.substring(file.lastIndexOf("."))

        显示提交的文件.后面的文件格式

绕过方法:

        通过火狐插件NOscript插件或者禁用IE中JS脚本

        通过F12查看器删除οnsubmit="return checkFile()"

        通过F12控制器重定向checkFile   输入 funtion checkFile{}

        通过burp抓包改包,先上传一个jpg格式的木马吗,通过burp将其改为asp/php/jsp后缀名即可

HTTP请求包

  •         Content-Length:即上传内容大小
  •         MAX_FILE_SIZE:即上传内容的最大长度
  •         filename:即上传文件名
  •         Content-Type:文件上传类型
  •         请求包中的乱码字段,即是所上传文件的内容

MIME-Type介绍

        MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开,多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式

        常见的MIME-Type

                

常见的MIME-Type
PDF文档.pdf application/pdf
Microsoft Word文档.word application/msword
PNG图像.png image/png
GIF图像.gif image/gif
JPEG图像.jpeg,.jpg image/jpeg
au声音文件.au audio/basic
MIDI音乐文件mid,midi audio/midi,audio/x-midi
RealAudio音乐文件.ra,.ram audio/x-pn-realaudio
MPEG文件.mpg,.mpeg video/mpeg
AVI文件.avi video/x-msvideo

        MIME-Type代码分析

                使用源代码分析  使用$_FILE['upload_file']['type']获取上传文件的MIME-Type类型,其中upload_file是在表单中定义的

<?php
      if (isset($_POST["submit"])){
        $file_name = $_FILES['upfile']['tmp_name'];
        $allow_ext = array('image/png','image/gif','image/jpeg','image/bmp');
        $file_ext = $_FILES['upfile']['type']
        echo $file_ext
        if (in_array($file_ext,$allow_ext))
        {
            $uploaddir = 'uploads/';
            if (file_exists($uploaddir)){

                if(move_uploaded_file($_FILES['upfile']['tmp_name'],$uploaddir.'/.$_FILES['upfile']['tmp_name'],$uploaddir.'/.$_FILES['upfile']['name'])){
        echo '文件上传成功,保存于:'.$uploaddir.$_FILES['upfile']['name']."\n"
    }
        }else{
                exit($uploaddir.'文件夹不存在,请手工创建');
    }
}
 
    else
            echo '此文件不允许上传',"\n"
       }
?>

MIME代码分析

isset()函数用于检测变量是否已设置并且非NULL

        如果已经使用了unset()释放了一个变量之后,再通过isset()判断将返回FALSE

        若使用isset()测试一个被设置成NULL的变量,将返回FALSE

        同时要注意的是null字符("\0")并不等同于PHP的NULL变量

$_FILES[字段名][name]-- 保存的文件在上传者机器的文件名

$_FILES[字段名][tmp_name]-- 保存的是文件上传服务器临时文件夹之后的文件名

upfile是html<input type="file" name="upfile"/>

in_array()函数搜索数组中是否存在指定的值

        注释:如果search参数是字符串且type参数被设置为TRUE,则搜索区分大小写

        $uploaddir='upload/';   设置变量为upload/路径

if(move_upload_files)($_FILES['upfile']['tmp_name'],$uploaddir.'/.$_FILES['upfile']['name'])

        文件upfile的临时文件名上传至upload/upfile

绕过MIME类型检测方法

        上传一个php文件 进行抓包在Content-Type:application/octet=tream修改image/jpeg并且将文件后缀名更改为php就可以了

application/octet-stream介绍

        当浏览器在请求资源是,会通过http返回头中的content-type决定如何显示/处理将要加载的数据,如果这个类型浏览器能够支持阅览,浏览器就会直接展示该资源,比如png,jpeg,video等格式,在某些下载文件的场景中,服务端可能会返回文件流,并在返回头中带上Conten-Type:application/octet-stream告知浏览器这是一个字节流,浏览器一般不会自动执行或询问执行,设置HTTP头Conten-Disposition值为attachment的文件一样来对待这类文件,即浏览器会触发下载行为

        简单来说,浏览器并不认得这个是什么类型,也不知道应该如何展示,只知道这是一种二进制,因此遇到Content-Type为application/octet-stream的文件时,浏览器会直接把他下载下来.这个类型一般会配合另一个响应头Content-Disposition,该响应头指示回复的内容该以何种形式展示,是以内联形式(即网页或者网页的一部分)还是以附件的形式下载并保存到本地

文件上传 黑名单检查

        黑名单检查:基于程序定义不能出现文件名中的后缀名构成,如果用户上传的文件后缀名为黑名单中的内容那么将无法上传

        黑名单存在绕过的可能性,因为很有可能不能涵盖所有的看一看被解析的文件后缀名,例如asp网站中能被解析为asp出现执行的后缀名有cer等

        如果文件后缀名匹配到正则表达式,那么使用php解析,例如:php3 php4 php 5 php7 pht phtml如果服务器基于黑名单检测而又没有完全限制以上后缀名 那么此时上传以后这些后缀名结尾的文件都将被作为php文件解析 触发文件上传漏洞       

<?php
$uploaddir='uploads/';
if(isset($_POST['submit'])){
    if(file_exists($uploaddir)){
        $deny_ext = array('.php','.php3','.php5','php7','phtml');
        $file_ext = strrchr($_FILES['upfile']['name'],'.');
        if(!in_array($file_ext,$deny_ext)){
            if(!in_array($file_ext,$deny_ext)){
                if(move_uploaded_files($_FILES['upfile']['tmp_name'],$uploaddir.'/'.$_FILES['upfile']['name'])){
        echo '文件上传成功'
    }
}else{
        echo '此文件不允许上传';
    }
}else{
        exit($uploaddir.'文件夹不存在,请手工创建!')    
}
?>

黑名单绕过方法

        在burpsuite上传文件数据包的filename="xxx.$php$"php当作模糊测试点进行爆破

        爆破字典为php phtml php3 php7 php5 php4 ptml pht phtml

白名单检查

        白名单检测,表示只有当上传的文件符号白名单内容时,文件才能上传成功

                白名单相比于黑名单更加安全,指定用户上传文件类型要比限制用户用户不能上传类型更为可靠,但是白名单也会存在被绕过的风险,例如:一个站点存在文件上传功能,可以上传JPEG文件,同时也存在一个文件包含漏洞,或者.httaccess,00截断等

白名单代码审计

<?php
$uploaddir='upload/';
if(isset($_POST['submit'])){
    if(file_exists($uploaddir)){
        $allow_ext = array('.jpg','jpeg');
        $file_ext = strrchr($_FILES['upfile']['name'],'.');

        if(in_array($file_ext,$allow_ext)){
            if(move_uploaded_file($_FILES['upfile']['tmp_name'],$uploaddir.'/'.$_FILES['upfile']['name'])){
        echo '文件上传成功'
    }
}else{
        echo '此文件不允许上传'
    }
}else{
        exit($uploaddir.'文件不存在')
    }
}
?>

此时可以探测站点是否存在文件包含漏洞,从而利用文件包含漏洞加载图片作为php脚本执行

绕过白名单检测方法

        在php中,具include,include_once,require,require_once函数可以包含其他文件,无论文件是什么类型(后缀名),只要文件内容符合PHP脚本语法规则就会被解释执行

00截断

        00截断是操作系统层的漏洞,由于操作系统是c语言或汇编语言编写,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾,操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号,因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的,00截断通常来绕过web软waf软waf的白名单限制

        php环境00截断的条件

                php版本小于5.3.29

                magic_quotes_gpc = Off

php环境00截断详解

<?php
var_dump($_FILES['upfile_file']);//打印接收的文件变量数组
echo "<br>";
$file_ext = substr($_FILES['upload_file']['name'],strrops($_FILES['upload_file']['name'],".")+1);//截断文件名后缀
var_dump($file_ext);
echo "<br>";
$tmp_file = $FILES['upload_file']['tmp_name']  //文件临时存储位置
vardump($tmp_file);
echo "<br>";
$img_path = $_POST['save_path']."/".rand(100.999).date("YmdHis").".".$file_ext; //将上传目录,随机数,时间戳和扩展名拼接为文件保存路径
var_dump($img_path);
echo "<br / >";
move_upload_file($tmp_file,$img_path); //将临时文件移动到文件保存路径上
?>

%00截断绕过

        在url中%00表示ascll码中的0,而ascll中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为去读已结束

        比如

                https://xxxx/upfiles/?filename=test.txt                此时输出的是test.txt

         加上%00

                https://xxxx/upfiles/?filename=test.php%00txt  此时输出的是test.php

        就可以绕过了后缀限制,可以上传webshell

.htaccess文件是什么

        htaccess文件是Apache服务器中的一个配置文件,他负责相关目录下的网页配置,通过htaccess文件,可以帮助我们实现:网页301重定向,自定义404错误页面,改变文件扩展名,允许或组织特定的用户或者,目录的访问,禁止目录列表,配置默认文档等功能

        htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置,通过htaccess文件可以帮我们实现:网页301重定向,自定义404错误页面,改变文件扩展名,允许/阻止特定的用户或者目录的访问,禁止目录列表,配置默认文档

.htaccess绕过

        根据htaccess文件的特性,这道题可以重写文件的解析规则进行绕过,先上传一个名为.htaccess文件,将原有的文件替换掉,其内容如下

AddType application/x-httpd-php .jpg

        意思是将jpg文件进行php解析

        然后上传一个带木马的jpg文件访问即可得到webshell

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值