Upload-labs(Pass-17--Pass-21)

 Pass-17

二次渲染+图片马/条件竞争

二次渲染就是在我们上传的图片后,网站会对图片进行二次处理,比如对图片的尺寸、格式、以及网站对图片进行定义的一些要求等进行处理,并且服务器会对里面的内容进行二次替换更新,在处理完后,会生成一个合规的图片在网站上显示出来。

imagecreatefromjpeg()函数,二次渲染是由Gif文件或 URL 创建一个新图象。成功则返回一图像标识符/图像资源,失败则返回false,导致图片马的数据丢失,上传图片马失败。

查看源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.'/'.basename($filename);

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
                $msg = "该文件不是jpg格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);
                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefrompng($target_path);

            if($im == false){
                $msg = "该文件不是png格式的图片!";
                @unlink($target_path);
            }else{
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
            $msg = "上传出错!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
        if(move_uploaded_file($tmpname,$target_path)){
            //使用上传的图片生成新的图片
            $im = imagecreatefromgif($target_path);
            if($im == false){
                $msg = "该文件不是gif格式的图片!";
                @unlink($target_path);
            }else{
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
            $msg = "上传出错!";
        }
    }else{
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

提示


网上大佬的二次渲染专用图片https://wwe.lanzoui.com/iFSwwn53jaf

本次关卡对上传的图片进行了处理,先进行二次渲染才进行的放入的,而渲染把图片马的当中的后门清除掉。所以本关的关键在于避开二次渲染。

二次渲染不是全部渲染,只渲染部分,所以把经过渲染的文件与未渲染的文件进行比较就可以得出不渲染的区域,随后把后门写在这里即可

上传文件,并修改url访问后

可以看到这里只是显示了图片的内容,没有解析到图片中的PHP代码。

因为系统把我上传的图片重新渲染了一遍,或者说是压缩了我所上传图片的内容。

接下来先把被渲染的图片下载下来,直接右键图片,点击“另存图像为”

将两个图像使用010工具中的比较文件打开

将被渲染后的图片与原来的图片进行对比,利用工具可以明显的看到渲染前后图像文件的异同

复制一句话木马的16进制

在已经被渲染的图像里面,未被渲染的区域插入一句话木马

保存后,上传被渲染过且被修改过的一句话木马图像

查看图像路径

访问文件路径时需要构造URL

利用文件包含漏洞upload-labs/include.php?file=upload/文件名

成功访问

文件上传:Upload靶场11到17关详解。_文件上传emeditor图片马-CSDN博客

Pass-18

(条件竞争)

查看源码

提示

上传图片木马配合解析漏洞进行getshell

准备工作:

新建一句话木马18.php,代码为:

<?php fputs(fopen('../upload/shell18.php','w'),'<?php phpinfo();?>');?>

只要被成功当作PHP文件解析,就会生成shell18.php 文件

上传文件18.php,并且使用bp抓包

点击右键或使用ctrl+i发送到lntruder

 bp设置无限发送空的Payloads,来让它一直上传该文件

打开python脚本并运行

python代码

​
import requests
url = "http://upload-labs-master/upload/18.php"
while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break
    else:
        print("发包中")

​

在python脚本运行后,burpsuite开始无限制重放数据包

直到python脚本出现OK,才关闭burpsuite

打开根目录,可以看见shell18文件已经被成功上传

使用文件包含漏洞upload-labs/include.php?file=upload/构造url

成功访问

Pass-19

(条件竞争+白名单+其他漏洞配合)

查看源码

//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" );
  
  }
......
......
...... 
};

1.正常
2.文件已经被上传,但没有重命名。
3.上传失败,上传目录不可写。
4.上传失败,无法上传该类型文件。
5.上传失败,上传的文件过大。
6.上传失败,服务器已经存在相同名称文件。
7.文件无法上传,文件不能复制到目标目录。
8.未知错误!

对于文件类型检查:
(白名单)
“.doc”, “.xls”, “.txt”, “.pdf”, “.gif”, “.jpg”, “.zip”, “.rar”, “.7z”,“.ppt”,
“.html”, “.xml”, “.tiff”, “.jpeg”, “.png”

提示仍是代码审计

本关的页存在着条件逻辑漏洞,我们可以采用条件竞争的方式来绕过

上传图片马,在系统没有将图片马重命名之前,用文件包含漏洞将其解析,从而生成一个含有一句话木马的1.php文件。

查找许多资料后,仍然无法做出upload-labs-Pass-19

文件上传upload-labs 第19关 Apache解析漏洞配合条件竞争_upload-labs第19关-CSDN博客

upload-labs_pass19_条件竞争+apache解析漏洞_apache解析 upload-labs-CSDN博客

先暂告一段落,进一步深入了解后,再做尝试。

Pass-20

(黑名单+上传路径可控)

查看源码

提示

因为文件名可控,这题利用move_uploaded_file的一个特性,会自动忽略后面的/.

apache2.4.0~2.4.29版本 判断后缀时会带上末尾的换行符,也就是说.php%0A这个后缀和.php一样都会被apache当作php文件解析

可以在文件名后加/.这两个符号来绕过黑名单的限制。

上传一张图片马,代码如下

<?php phpinfo();?>

把文件保存改为1.php/.

上传成功后直接访问

成功

具体原理还不是太懂。

upload靶场后面几个题难度比较大,但不是越后面的题就越难,拿到题目后多加尝试,总会有解法的。

Pass-21

(MIME验证+白名单+上传路径可控)

查看源码

$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 = "请选择要上传的文件!";
}

提示

补充知识:

end(array)函数,输出数组中的当前元素和最后一个元素的值。

reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值

count(array)函数,计算数组中的单元数目,或对象中的属性个数

explode(separator,string[,limit]) 函数,把字符串打散成数组。

题解

首先准备一张图片马phpinfo.png

<?php
phpinfo();
?>

上传后用bp拦截

修改后放行

找到一张大佬做的较为详细的图片

放行后,发现文件上传成功

成功访问

写在最后

极为艰难的勉强参照着大佬们的博客,将upload靶场上的题目全部做完一遍。尤为感受到,所知俞多,方知所知俞少之感。在文件上传的路上,在web的路上,在ctf的路上,在网络攻防的路上。都还有很长的一段路要走。一段煎熬,困难,波折,孤独的路,但我相信,前行总有曙光。如同此刻的夜晚,偶有残星闪烁,月牙勾起尖角,黑夜笼罩着黑夜。而明天,太阳照常升起。

静谧的夜晚,纷乱的思绪。反正也没什么人看见,我为我,写点东西。

晚安。2024.4.12

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值