安全-Pass02之MIME绕过(upload-labs)

Posted 小狐狸FM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安全-Pass02之MIME绕过(upload-labs)相关的知识,希望对你有一定的参考价值。

前言

  • phpHypertext Preprocessor超文本预处理器,多用于web后端
  • 在进行代码审计的时候可以使用Seay进行全局搜索
    目前正在学习代码审计的内容,所以会介绍得更细一些,以便学习了解。

upload-labs靶场下载

蚁剑AntSword

菜刀Cknife

Seay

PHP: PHP 手册 - Manual

一、题目

在这里插入图片描述
在这里插入图片描述

php后端代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

二、WriteUp

随便上传一个文件,并抓包了解一下其中都含有那些上传的变量参数

在这里插入图片描述

[1]. 源码审计

  • php代码进行审计,if语句比较多最好从外往内分析
  • 第一条if语句只是判断了一下提交的post请求中submit参数是否被设置且非空
    PHP:isset - Manual

在这里插入图片描述

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {//第一条if
	//代码
}
  • 第二条语句判断了一下文件上传的路径存不存在,存在的话就执行里面的代码,不存在就给$msg设置回显信息
  • 通过Seay审计的全局搜索功能可以找到UPLOAD_PATH是在config.php中被定义的
    Pass-02\\index.php的代码中包含了上一级目录下的config.php
    然后这个变量就可以在Pass-02\\index.php中直接使用
  • ../表示访问上一级的目录,所以upload-labs-master\\Pass-02\\index.php包含的是upload-labs-master\\config.php
  • UPLOAD_PATH变量在upload-labs-master\\Pass-02\\index.php中被调用时,就会设置上传的父文件夹为upload-labs-master\\upload

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

$is_upload = false;
$msg = null;
if (xxx) {//第一条if为真时
    if (file_exists(UPLOAD_PATH)) {//第二条if为真时
    	//代码
    }else {//第二条if为假时
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}
  • 第三条if语句判断的条件稍微多了点,主要是判断了文件的Content-Type参数是否为image/jpegimage/pngimage/gif三者中的一个
  • 如果符合就通过此if语句,否则就设置$msg的值用于回显错误提示信息

在这里插入图片描述

$is_upload = false;
$msg = null;
if (xxx) {//第一条if为真时
    if (xxx) {//第二条if为真时
        if (($_FILES['upload_file']['type'] == 'image/jpeg') 
        || ($_FILES['upload_file']['type'] == 'image/png') 
        || ($_FILES['upload_file']['type'] == 'image/gif')) {//第三条if为真时
        	//代码
        } else {//第三条if为假时
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {//第二条if为假时
        //代码
    }
}
  • 在上传文件的时候,文件都会被存储在一个临时的文件夹下
    我们不需要知道具体路径,只需要通过tmp_name参数获取路径即可
  • 下方两条语句是先将获取的临时路径存储到$temp_file变量内,然后设置上传的路径
  • 假设上传的文件名为test2.txt,则$img_path值为../upload/test2.txt
$is_upload = false;
$msg = null;
if (xxx) {//第一条if为真时
    if (xxx) {//第二条if为真时
        if (xxx) {//第三条if为真时
        	$temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
            //代码 
        } else {//第三条if为假时
            //代码
        }
    } else {//第二条if为假时
        //代码
    }
}
  • 第四条if语句会执行move_uploaded_file函数,将存在临时文件夹内的文件移动到指定的upload文件夹下,并以原先的文件名存储。
  • 如果移动失败就设置回显语句,成功就设置$is_upload为真
$is_upload = false;
$msg = null;
if (xxx) {//第一条if为真时
    if (xxx) {//第二条if为真时
        if (xxx) {//第三条if为真时
        	//代码
            if (move_uploaded_file($temp_file, $img_path)) {//第四条if为真时
                $is_upload = true;
            } else {//第四条if为假时
                $msg = '上传出错!';
            }
        } else {//第三条if为假时
            //代码
        }
    } else {//第二条if为假时
        //代码
    }
}

[2]. MIME绕过

  • 知道了源码的上传思路后,就比较好绕过了
    其中比较重要的是第三条if语句,其他的语句没有对文件进行过滤
  • 所以只要Content-Type的值为image/jpegimage/pngimage/gif其中一个,就可以绕过
    存在于服务器的文件后缀必须为php,不然没有办法解析里面的代码

在这里插入图片描述

上传成功后,右键查看图片的url并访问
没有报错,就说明成功解析了这个php文件

在这里插入图片描述
在这里插入图片描述

使用蚁剑进行连接

在这里插入图片描述
在这里插入图片描述

以上是关于安全-Pass02之MIME绕过(upload-labs)的主要内容,如果未能解决你的问题,请参考以下文章

安全-Pass08之黑名单点绕过(upload-labs)

安全-Pass01之js绕过(upload-labs)

安全-Pass03之黑名单绕过(upload-labs)

安全-Pass07之黑名单空格绕过(upload-labs)

安全-Pass14之文件头绕过(upload-labs)

安全-Pass15之图片马绕过(upload-labs)