Upload-labs Pass-20 数组绕过

Upload-labs Pass-20 数组+/.绕过

在这里插入图片描述
和19关前面长一个样,肯定要代码审计了,直接看源码。

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

explode(a,b)函数以a为分割,把b转为数组。
reset()函数把数组内部指针移动到数组第一个元素,并返回值。
end() 把数组内部指针移动到数组最后一个元素,并返回值。
count()函数数组元素的数量。
通过$file_name = reset($file) . '.' . $file[count($file) - 1];可以知道最终的文件名是由数组的第一个和最后一个元素拼接而成。如果是正常思维来讲,无论如何都是没有办法绕过的,但是有个地方给了一个提示。
在这里插入图片描述
这里有个判断,如果不是数组,就自己拆成数组,也就是说,我们是可以自己传数组进入的。如果第一个元素是x.php/,最后一个元素是end(),讲道理$file[count($file)-1]也就是最后一个,但是为什么不直接使用end()呢,也就是说有特殊的情况下,这两个东西是不等的,其实就是这样的一个数组$array=([0] -> 'x.php/' [2]->'jpg'),看下面这个测试案例就知道是什么意思了。

测试代码
<?php
$file = array();
$file[0] = 'x.php/';
$file[2] = 'jpg';
print_r($file);
echo "数组总元素个数为".count($file);
?>
运行结果
Array
(
    [0] => x.php/
    [2] => jpg
)
数组总元素个数为2

再来分析一下$file_name = reset($file) . '.' . $file[count($file) - 1];,按上面的测试代码来看,reset($file)肯定是x.php/count($file)2,再减少1,后缀就变成了$file[1]。但是上面那个数组里面没有$file[1]啊,这里,来打印着测试一下。

echo "\$file[1] is".$file[1];
Array
(
    [0] => php/
    [2] => jpg
)
$file total is2**********************$file[1] is

很明显看到结果是空,也就是$file[count($file) - 1]相当于没有内容,那最后的文件名为x.php/.了,这个时候就可以用19关的方法进行绕过,当然也可以利用windows的特性.空格和绕过。
在这里插入图片描述
访问,成功解析。
在这里插入图片描述

### 关于 upload-labs Pass-12 的解决方案 #### 背景介绍 upload-labs 是一个用于学习和测试文件上传漏洞的靶场,其中包含了多个级别的挑战。Pass-12 特别关注通过特定条件下的文件上传绕过验证机制来实现攻击[^2]。 #### 漏洞分析 在 Pass-12 中,服务器端设置了较为严格的文件名过滤规则以及 MIME 类型检测。然而,在实际环境中可能存在某些配置不当之处可以被利用: - **MIME Type 绕过**: 即使服务端进行了 MIME 类型校验,但如果仅依赖客户端提供的 Content-Type 头部,则可以通过修改请求头中的内容类型来进行绕过尝试。 - **文件扩展名检查不足**: 如果只简单地基于黑名单模式阻止已知危险类型的文件(如 .php),那么攻击者仍有可能找到未被列入黑名单的安全扩展名并执行恶意脚本。 为了成功完成此关卡的任务,需要理解如何构造特殊格式的数据包以规避上述防护措施[^4]。 #### 实现方法 以下是针对该级别的一种可能解法思路: ```bash curl -X POST \ http://localhost/upload-labs-master/Pass-12/index.php \ -F "file=@test.jpg;type=image/jpeg" \ -H 'Content-Type: multipart/form-data' ``` 这段命令展示了如何使用 `cURL` 工具发送带有自定义 MIME 类型 (`image/jpeg`) 和文件名 (`.jpg` 扩展) 的 HTTP 请求给目标 URL 。这里的关键在于即使上传的是 PHP 文件,也可以伪装成图片或其他无害文件形式提交上去[^3]。 需要注意的是,具体实施时还需考虑更多细节因素,例如服务器的具体版本、中间件特性等都会影响最终效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值