BUUCTF n1book [第二章 web进阶]文件上传

花了一天多才搭好docker的环境,然后再来写这道只能说自己搭环境也太香啦 不过这道题也花了一点点点时间琢磨

题目分析

打开题目,发现是一如既往的文件上传界面
在这里插入图片描述
习惯性抓个包,界面源码已经完全暴露了,太长了这里就不放了(根据以往的经验和参考其他的师傅的wp 小小地分析了一下)

  <?php
header("Content-Type:text/html; charset=utf-8");
// 每5分钟会清除一次目录下上传的文件

//会包含文件pclzip.lib.php,感觉这个php里面是有一些针对zip包进行解压等的操作的
require_once('pclzip.lib.php');

//要是没上传文件,就输出上传页面
if(!$_FILES){
echo '省略的HTML'
    show_source(__FILE__);
}else{
    $file = $_FILES['file'];

//限制上传的文件名不为空
    if(!$file){
        exit("请勿上传空文件");
    }
    $name = $file['name'];

    $dir = 'upload/';
    $ext = strtolower(substr(strrchr($name, '.'), 1));
     $path = $dir.$name;
//strrchr($name, '.') 
//strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
//比如上传的文件名为$name=1.php.txt,这里strrchr($name, '.') 执行结果为.txt
//substr(strrchr($name, '.'), 1)
//substr字符串截取,从下标为1开始截取,那就是把点略过,截取后为txt
//通过strtolower函数将所有字符转换为小写,赋值给ext变量
//如果我们上传的文件名为1.txt,那么path变量就为upload/1.txt


//检查是否为目录
    function check_dir($dir){
        $handle = opendir($dir);
        while(($f = readdir($handle)) !== false){
            if(!in_array($f, array('.', '..'))){
                if(is_dir($dir.$f)){
                    check_dir($dir.$f.'/');
                 }else{
                    $ext = strtolower(substr(strrchr($f, '.'), 1));
                    if(!in_array($ext, array('jpg', 'gif', 'png'))){
                        unlink($dir.$f);
                    }
                }
            
            }
        }
    }
    
//创建目录    
    if(!is_dir($dir)){
        mkdir($dir);
    }


    $temp_dir = $dir.md5(time(). rand(1000,9999));
    if(!is_dir($temp_dir)){
        mkdir($temp_dir);
    }
//这里应该就是最难的了,大概就是将目录名拼接一个随机数,读到这里,基本上就知道需要路径穿越了
因为我们不知道随机数值,所以就算绕过上传,解析也是一大关(路径不难找,就是解析难)


//首先进行后缀的校验,把刚刚拿到的,最后一个.后面的字符串和这里的zip、jpg、gif、png进行对比校验
    if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){
        if($ext == 'zip'){
//使用PclZip进行解压缩        
            $archive = new PclZip($file['tmp_name']);
//遍历解压缩后的每个目录            
            foreach($archive->listContent() as $value){
                $filename = $value["filename"];
//一段较为简单的正则,就是匹配每个文件结尾的位置,是否是.php                
                if(preg_match('/\.php$/', $filename)){
                     exit("压缩包内不允许含有php文件!");
                 }
            }
            if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
                check_dir($dir);
                   exit("解压失败");
            }

            check_dir($dir);
            exit('上传成功!');
        }else{
            move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);
            check_dir($dir);
            exit('上传成功!');
        }
    }else{
        exit('仅允许上传zip、jpg、gif、png文件!');
    }
}

这样我们上传的文件的路径就是 upload/随机值/上传的文件名

解题过程

我们构造最终文件名为/…/…/hhh.php.xxx 为什么要这样设置文件名呢?
1)/…/…/
因为我们要绕过路经检测,通过路径穿越将文件放到指定目录(通过路径穿越将文件上传到web根目录下) 那么一层是upload,一层是随机值,所以我们要穿越两层,直到根目录 这样我们才能访问得到
2)hhh.php.xxx
在这里插入图片描述
apache版本为2.4.7,当我们上传一个hhh.php是不允许上传的,但是我们上传hhh.php.xxx绕过了后缀检验,上传到了根目录,利用apache解析漏洞,我们再去访问这个文件,这时apache从后面开始解析,遇到xxx,不认识,再往前解析,php,认识,这个时候apache就会将hhh.php.xxx文件解析为hhh.php脚本文件,就可以得到shell了

首先我们先创建一个文件(不是文件夹!!),文件后缀随便,只要文件名长度满足18即可,这就成功将后缀完全覆盖了
在这里插入图片描述
将文件压缩成zip
在这里插入图片描述
在010Edtior中打开该压缩包
在这里插入图片描述
修改文件名为:/…/…/hhh.php.xxx (实操/…/…/1.php.xxx的时候行不通,觉得是长度问题,但是看有些师傅的wp又可以??有点奇怪)
在这里插入图片描述在这里插入图片描述

上传该压缩包绕过对后缀的检查,然后我们在kail中可以看到文件已经上传成功,那么就来访问一下这个文件
在这里插入图片描述
得到flag

在这里插入图片描述
补充:验证一下上传文件的路径哈哈哈
随便上传个符合后白名单的文件(图片),在kail中可以看到确实如此
在这里插入图片描述

文章参考:
https://blog.csdn.net/zy15667076526/article/details/114139749
https://www.cnblogs.com/murkuo/p/14915458.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答:根据引用和引用的内容,buuctf web应该是指buuctf比赛中的一个web题目。其中可能涉及到Tornado作为非阻塞式服务器的使用,以及render函数的使用。而根据引用的内容,buuctf web题目可能存在一些漏洞,比如SSRF(Server Side Request Forgery)漏洞,可以通过对内网web应用实施攻击获取webshell。因此,在buuctf web题目中,可能需要掌握SSRF漏洞的利用和对web应用的渲染函数(render函数)进行利用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【CTF】buuctf web 详解(持续更新)](https://blog.csdn.net/m0_52923241/article/details/119641325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【BUUCTF刷题】Web解题方法总结(一)](https://blog.csdn.net/qq_45834505/article/details/114276572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [BUUCTFWeb真题学习整理(一)](https://blog.csdn.net/qq_41429081/article/details/98042205)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值