upload-labs-master文件上传靶场第七关详解

一.前言

  upload-labs-master是文件上传靶场,里面目前总共有19关,github地址https://github.com/c0ny1/upload-labs,今天要说的是这个靶场的第七关的解法

二.正文

先看下第七关长什么样

和其他几关一样,咱们先直接看下源码吧

$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_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不怎么会但是作者已经把改写的注释已经写上了,所以我就照着作者的注释说一下

$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_ext = strrchr($file_name, '.'); 
#这个需要解释下了,strrchr的作用先说下,strrchr() 函数查找字符在指定字符串中从后面开始的第一次出现的位置,如果成功,则返回从该位置到字符串结尾的所有字符,如果失败,则返回 false。与之相对应的是strstr()函数,它查找字符串中首次出现指定字符的位置
举个栗子:

<?php
echo strrchr( '123456789.xls' , '.' ); //程序从后面开始查找 '.' 的位置,并返回从 '.' 开始到字符串结尾的所有字符
  程序的输出结果是:.xls
  ?>
  $file_ext = strtolower($file_ext); //转换为小写,比如你后缀写成Php,想用大小写绕过的时候就不行了,这段代码将所有的大写转换成小写
  $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
  $file_ext = trim($file_ext); //首尾去空,将你后缀名里的前后空格都去掉

看看上面的代码都限制了多少吧,大小写,加空格,加字符串,黑名单,好多限制。。。。。

这个时候可以采用一种方法来绕过,因为靶场是搭建在windows上的,所以windows有一个特性,windows系统自动去掉不符合规则符号后面的内容,什么意思呢?举个栗子

比如你新建了一个1.txt文件,然后你将名称改为1.txt.试试,虽然会有下面的警告,但是windows还是会默认去掉后面的.,名字还是变成了1.txt

这个时候我们就可以利用.来绕过限制了,因为strrchr函数会将上传的文件名后缀处理为.php.,当上传到win机器上时又会将后面的.去掉,然后后缀就又会被还原成.php,这样就可以执行了,下面演示一下

首先上传1.php文件并抓包,在burp修改文件后缀名为.php.

拿c刀连接下试试

连接成功,我们上传的webshell已经成功连接上了

 

posted @ 2018-10-23 22:55  Id3al  阅读(1207)  评论(0编辑  收藏  举报