• 注册
  • BBS web安全 关注:71 内容:84

    upload-labs上传绕过(下)

  • 查看作者
  • 打赏作者
  • 拉黑名单
  • 当前位置: 字节脉搏 > 网络安全 > web安全 > 正文
    脚本小子
    VIP
    夜行字节(字节脉搏实验室)

    第十一关:双写绕过

    $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即可绕过

    upload-labs上传绕过(下)

    upload-labs上传绕过(下)

    第十二关:%00截断上传

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

    $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类型文件!";
        }
    }

     

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

    $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

    upload-labs上传绕过(下)

    所有我没办法给大家演示,请大家参考一下,https://blog.csdn.net/weixin_43571641/article/details/83832578

    第十三关:00截断

    $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

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

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

    upload-labs上传绕过(下)

    upload-labs上传绕过(下)

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

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

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

     

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

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

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

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

    upload-labs上传绕过(下)

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

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

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

    upload-labs上传绕过(下)

    upload-labs上传绕过(下)

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

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

    upload-labs上传绕过(下)

    upload-labs上传绕过(下)

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

    upload-labs上传绕过(下)

    菜刀连接即可

     

     

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

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

    upload-labs上传绕过(下)

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

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

    得到的结果,base解码即可

    upload-labs上传绕过(下)

     

    参考连接:https://blog.csdn.net/nzjdsds/article/details/82461043

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

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

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

    第十八关:条件竞争

    $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。

    upload-labs上传绕过(下)

    我们把它转送到Intruder模块

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

    upload-labs上传绕过(下)

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

    upload-labs上传绕过(下)

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

    upload-labs上传绕过(下)

    然后设置线程

    upload-labs上传绕过(下)

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

    upload-labs上传绕过(下)

    upload-labs上传绕过(下)

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

    upload-labs上传绕过(下)

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

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

    upload-labs上传绕过(下)

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

     

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

     

    第十九关:条件竞争

    //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的问题,从而上传成功

     

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

     

    第二十关:空格绕过

    本题和12题一样的做法

    $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这个题目

     

    我的方式是简单粗暴

    upload-labs上传绕过(下)

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

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

     

    $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会忽略掉/.,到这里我们就上传成功了

    upload-labs上传绕过(下)

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

    请登录之后再进行评论

    登录
  • 做任务
  • 帖子间隔 侧栏位置: