前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >upload-labs上传绕过(下)

upload-labs上传绕过(下)

作者头像
字节脉搏实验室
发布2020-03-19 15:29:38
8030
发布2020-03-19 15:29:38
举报

第十一关:双写绕过

代码语言:javascript
复制
$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","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");


        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $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 = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

trim函数 根据我们的测试,它是将指定的字符串移除,那么在这里我们就可以上传.pphphp即可绕过

第十二关:%00截断上传

从这一关开始,就是白名单上传了。前一期已经对白名单进行了解释,在这就不再BB了

代码语言:javascript
复制
$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类型文件!";
    }
}

在这里,代码虽然对上传进行了白名单限制,但是这里对上传的文件进行文件名重构,那么我们就可以以用这个重构进行绕过

代码语言:javascript
复制
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

虽然问题找到了,但是%00对PHP版本有要求,

(1)php版本必须小于5.3.4

(2)打开php的配置文件php-ini,将magic_quotes_gpc设置为Off

所有我没办法给大家演示,请大家参考一下,

https://blog.csdn.net/weixin_43571641/article/details/83832578

第十三关:00截断

代码语言:javascript
复制
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

代码和上面差不多,只是这里有一小点变化,GET变为POST

把抓取到的数据包发送到repeater模块,修改如下信息然后点击Hex

找到php+所在位置,按照位置修改+对应的hex为00 如上图所示

注:每一个hex值也就是上面的小方块对应右手边的一个字符。

这题和上面一样都需要php版本小于5.3.4,在这我没办法给大家复习,如果有需要,自行安装其它版本的phpstudy吧

第十四关:图片马+文件包含漏洞

先给大家说一下,文件包含漏洞,以后就不再给大家说了程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数

时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含

说白了,就是开发的时候代码写的不够严谨。

这里直接给出了文件包含漏洞,所有我们上传一张图片马即可

我们在同一目录下,存放一句话木马和一张图片

在目录当前运行cmd命令即可

copy 1.jpg/b + 1.php/a 2.jpg

点击下面->文件包含漏洞

访问127.0.0.1/upload-labs/include.php?file=+“图片上传路径”

菜刀连接即可

再这里补充一下文件包含漏洞一些常见操作

1、etc /flag 这里的flag.txt 是自己在upload同级目录下创建的

2、php伪协议(读取php文件)

url?file=php://filter/convert.base64-encode/resource=index.php

得到的结果,base解码即可

参考连接:

https://blog.csdn.net/nzjdsds/article/details/82461043

第十五关:图片马+文件包含漏洞

第十六关:图片马+文件包含漏洞

这两个题都是和第十四关一样的解法,在这就不多说了

第十七关:条件竞争

代码语言:javascript
复制
$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 = '上传出错!';
    }

这里先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,访问webshell。

我们把它转送到Intruder模块

如果效果和我的不一样(才导入过来肯定不一样)记得点击右手边上的Clera

然后我们调整一下Plaloads 意思是啥呢,就是让这个数据包不做变化不断发送同一个包就OK

切记设置上传次数(不要太少)

然后设置线程

点击右上角Start attack跑起来就好

然后我们一直访问可以看见这里没有任何东西(默认提前知道了上传路径)

这就算是成功了 这里没有成功执行php的原因是没有解析,因为源代码是把它当成jpg执行的

所以这里我们结合文件包含试试

附:这里我们其实可以开启两个爆破模块,分别执行俩个操作。第一个是不断上传webshell 另外一个就是访问http://localhost/upload-labs/include.php?file=upload/phpinfo.php

第二个模块肯定是能够返回访问成功的页面

第十八关:条件竞争

代码语言:javascript
复制
//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已经被上传,但没有重命名。';
            break; 
        case -1:
            $msg = '这个文件不能上传到服务器的临时文件存储目录。';
            break; 
        case -2:
            $msg = '上传失败,上传目录不可写。';
            break; 
        case -3:
            $msg = '上传失败,无法上传该类型文件。';
            break; 
        case -4:
            $msg = '上传失败,上传的文件过大。';
            break; 
        case -5:
            $msg = '上传失败,服务器已经存在相同名称文件。';
            break; 
        case -6:
            $msg = '文件无法上传,文件不能复制到目标目录。';
            break;      
        default:
            $msg = '未知错误!';
            break;
    }
}


//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );


......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }


    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }


    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }


    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }


    // if we are here, we are ready to move the file to destination


    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }


    // check if we need to rename the file


    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)


    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
.

分析,本关对文件后缀名做了白名单判断,然后一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名同样存在条件竞争的漏洞。

上传一个图片马,不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功

由于时间原因我就不再演示,参考第17题的利用方式

第二十关:空格绕过(同12题)

代码语言:javascript
复制
$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","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");


        $file_name = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);


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

从源码中我们可以看到,.use.ini没有在白名单中。在这我偷偷窃喜,可惜当我尝试半天之后我终于发现它并不能成功。关于.uer.ini使用方式和原理请参考

https://xz.aliyun.com/t/6091

也可以去BUUCTF上做做web的CheckIn这个题目

我的方式是简单粗暴

访问一下就OK了 如果不能理解请参考上一篇文章的第八关

第二十一关:/ + 数组 绕过

代码语言:javascript
复制
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
    //检查MIME
    $allow_type = array('image/jpeg','image/png','image/gif');
    if(!in_array($_FILES['upload_file']['type'],$allow_type)){
        $msg = "禁止上传该类型文件!";
    }else{
        //检查文件名
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
        if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }


        $ext = end($file);
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix)) {
            $msg = "禁止上传该后缀文件!";
        }else{
            $file_name = reset($file) . '.' . $file[count($file) - 1];
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $msg = "文件上传成功!";
                $is_upload = true;
            } else {
                $msg = "文件上传失败!";
            }
        }
    }
}else{
    $msg = "请选择要上传的文件!";
}

可以发现$file_name经过reset($file) . '.' . $file[count($file) – 1];处理。

如果上传的是数组的话,会跳过$file = explode('.', strtolower($file));。并且后缀有白名单过滤

而最终的文件名后缀取的是$file[count($file) – 1],因此我们可以让$file为数组。$file[0]为phpinfo.php/,也就是reset($file),然后再令$file[2]为白名单中的jpg。此时end($file)等于jpg,$file[count($file) – 1]为空。而 $file_name = reset($file) . '.' . $file[count($file) – 1];,也就是phpinfo.php/.,最终move_uploaded_file会忽略掉/.,到这里我们就上传成功了

本题参考文章为:https://xz.aliyun.com/t/4029

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 字节脉搏实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第十二关:%00截断上传
  • 第十三关:00截断
  • 第十四关:图片马+文件包含漏洞
  • 第十五关:图片马+文件包含漏洞
  • 第十六关:图片马+文件包含漏洞
  • 第十七关:条件竞争
  • 第十八关:条件竞争
  • 第二十关:空格绕过(同12题)
  • 第二十一关:/ + 数组 绕过
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档