文件上传靶机实验记录

2022-03-18 11:28:20 浏览数 (1)

文件上传脑图

第一关

提示与源码

本pass在客户端使用js对不合法图片进行检查!

代码语言:javascript复制
function checkFile() {
    var file = document.getElementsByName('upload_file')[0].value;
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    if (allow_ext.indexOf(ext_name   "|") == -1) {
        var errMsg = "该文件不允许上传,请上传"   allow_ext   "类型的文件,当前文件类型为:"   ext_name;
        alert(errMsg);
        return false;
    }
}

解题思路

前端JS后缀名校验,通过审查元素发现onsubmit="return checkFile()”校验函数我们将其删除直接上传(浏览器禁用JS脚本也能上传,BURP抓包更改后缀名也能上传)webshell。

解题步骤

  1. 右键审查元素,删除return checkFile()。
  2. 直接上传webshell。

第二关

提示与源码

本pass在服务端对数据包的MIME进行检查!

代码语言:javascript复制
$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.'文件夹不存在,请手工创建!';
    }
}

解题思路

对文件MIME类型验证判断,即请求包中Content-Type为image/jpeg||image/gif||image/png,拦截数据包修改MIME类型进行绕过。通过后得文件后缀仍然是c.php,服务端仍然可以解析脚本。

解题步骤

  1. 抓包修改MIME为图片类型(image/gif)放包上传成功。

第三关

提示与源码

本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!

代码语言:javascript复制
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array('.asp','.aspx','.php','.jsp');
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if(!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;  
            if (move_uploaded_file($temp_file,$img_path)) {
                 $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

解题思路

黑名单判断后缀名,我们可以上传.php3后缀进行绕过。

前提:httpd.conf开启以下配置:

Addtype application/x-httpd-php .php .php3 .phtml

服务端把php3 phtml后缀当成php来解析。

解题步骤

  1. 抓包修改上传文件后缀为.php3进行上传并访问。

第四关

提示与源码

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后缀文件!

代码语言:javascript复制
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //收尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

解题思路

后缀限制很多,但是并没有限制.htaccess可以利用Apache得.htaccess解析漏洞进行上传。

.htaccess是Apache得一个配置文件。

靶机中得httpd.conf配置:

Al lowOverride All

造成文件上传.htaccess解析得突破,从而导致webshell上传并执行。

解题步骤

  1. 准备1.htaccess内容为:

AddType application/x- httpd-php .jpg

整台服务器将.jpg后缀得文件当作php 来解析。

  1. 上传1.htaccess文件抓包修改为.htaccess放包。
  2. 上传c.jpg拦截数据包删除图片内容添加

第五关

提示与源码

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件!

代码语言:javascript复制
$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空

        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

解题思路

黑名单判断加入了.htaccess,不过从代码来看并没有判断大小写这里尝试大小写组合后缀进行绕过。

解题步骤

  1. 上传文件抓包改后缀名为.Php进行绕过限制从而上传webshell。

第六关

提示与源码

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf后缀文件!

代码语言:javascript复制
$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = $_FILES['upload_file']['name'];
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
  
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file,$img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件不允许上传';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

解题思路

通过查看源码发现并没有首尾去空,文件夹后缀增加空格进行绕过从而上传webshell。

解题步骤

  1. burp抓包修改上传得后缀名.php[空格],放包进行上传。

第七关

提示与源码

本pass禁止上传所有可以解析的后缀!

代码语言:javascript复制
$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
  
        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 . '文件夹不存在,请手工创建!';
    }
}

解题思路

根据源码可以看出并没有删除文件末尾得点,那么我们可以根据Windows自动去掉文件末尾得点,从而进行绕过上传。

解题步骤

  1. burp抓包在c.php得末尾加上点(c.php.),放包上传webshell。

根据Windows系统自动去末尾点得特性上传完成得文件名为c.php。

第八关

提示与源码

本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess后缀文件!

代码语言:javascript复制
$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = trim($file_ext); //首尾去空
  
        if (!in_array($file_ext, $deny_ext)) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '此文件类型不允许上传!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

解题思路

查看源码发现并没有对::DATA进行限制,文件后缀加::DATA直接绕过上传webshell。

  • Windows下NTFS文件系统的一个特性,即NTFS文件系统的存储数据流的一个属性DATA时,就是请求a.asp本身的数据,如果a.asp还包含了其他的数据流,则a.asp:lake2.asp, 请求a. asp:lake2. asp::$DATA,则是请求a. asp中的流数据lake2. asp的流数据内容。
  • NTFS文件系统包括对备用数据流的支持。这还是永久的功能,主要包括提供与Macintosh文件系统 中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。 在Windows中,此之后数据流称为: $DATA。

NTFS文件流实际应用:https://www.freebuf.com/column/143101.html

解题步骤

  1. 上传c.php时burp抓包在后缀之后添加::DATA 放包,访问webshell得时候去掉::DATA 即可。

第九关

提示与源码

本pass只允许上传.jpg|.png|.gif后缀的文件!

代码语言:javascript复制
$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = deldot($file_name);//删除文件名末尾的点
        $file_ext = strrchr($file_name, '.');
        $file_ext = strtolower($file_ext); //转换为小写
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
        $file_ext = trim($file_ext); //首尾去空
  
        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 . '文件夹不存在,请手工创建!';
    }
}

解题思路

白名单限制,只允许上传特定得后缀名文件。查看代码发现

代码语言:javascript复制
 $img_path = UPLOAD_PATH.'/'.$file_name;

路径拼接是处理后得文件名,于是构造c.php点 空格 点

经过处理后,文件名为c.php.,Windows特性去掉末尾得点。最终保存下来得文件名为c.php。

解题步骤

  1. 上传得时候抓包后缀末尾添加点 空格 点 (. .)放包上传webshell。

最后保存下来得文件:

第十关

提示与源码

本pass会从文件名中去除.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess字符!

代码语言:javascript复制
$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 = 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 . '文件夹不存在,请手工创建!';
    }
}

解题思路

代码语言:javascript复制
  $file_name = str_ireplace($deny_ext,"", $file_name);

查看源码发现只对后缀进行一次过滤,双写文件名进行绕过。

解题步骤

  1. burp抓包将上传得文件名改为c.pphphp放包上传即可。

第十一关

提示与源码

本pass上传路径可控!

代码语言:javascript复制
$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类型文件!";
    }
}

解题思路

服务器端_上传文件名的后缀制定限制

可知上传路径 命名规则使用用户get请求的save_ path值拼接而成。 考虑使用上传路径名截断中断绕过,不过这需要对文件有足够的权限,比如说创建文件夹,上传的文件名写成c.jpg, save_ path改成. ./upload/c.php,最后保存下来的文件就是c.php。文件保存的方式是上传路径 随机时间 截取的文件后缀。

前提条件:

截断条件:

  1. php版本小于5.3.4
  2. php.ini的magic_quotes_gpc为OFF状态

解题步骤

  1. 文件上传得时候进行抓包路径save_path=../upload/ 改为save_path=../upload/c.php 进行00截断。

第十二关

提示与源码

本pass上传路径可控!

代码语言:javascript复制
$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 = $_POST['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 = $_ POST['save_ path']."/".rand(10, 99) .date("YmdHis").".".$file_ ext;和pass-11分级将GET换为了POST,思路相同

这次的save_ path是通过post传进来的,在进行00截断时需要在hex中修改。

解题步骤

  1. 修改post参数的值, 这里在php的后面添加了一个空格和字母a(a得20进制为12),实际上写什么都可以,如果写个任意字符,再去查他的16二进制表示也可以:
  2. 修改完返回放包即可绕过上传成功。

第十三关

提示与源码

本pass检查图标内容开头2个字节!

代码语言:javascript复制
function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);  
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);  
    $fileType = '';  
    switch($typeCode){  
        case 255216:  
            $fileType = 'jpg';
            break;
        case 13780:  
            $fileType = 'png';
            break;  
        case 7173:  
            $fileType = 'gif';
            break;
        default:  
            $fileType = 'unknown';
        }  
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

解题思路

  • 服务端检测文件头,合并. 上传文件的后缀重命名为检测到的文件类型
  • 关于服务端检测文件头,我们可以在文件起始加入jpg lpnglgif文件的文件头来绕过。
  • 关于文件上传后被重命名为图片文件,不能当做php解析,我们可以利用文件包含漏洞进行包含解析。
  • 使用./表示当前根目录

解题步骤

  1. 上传webshell时c.php修改内容:上传
代码语言:javascript复制
GIF89a
  1. 利用文件包含漏洞包含上传得webshell使得webshell可以被解析。

include代码如下:

代码语言:javascript复制
 <?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}else{
    show_source(__file__);
}
?> 

http://192.168.0.108/upload/include.php?file=./upload/3120200817134332.gif

第十四关

提示与源码

本pass使用getimagesize()检查是否为图片文件!

代码语言:javascript复制
function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
        $ext = image_type_to_extension($info[2]);
        if(stripos($types,$ext)>=0){
            return $ext;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

解题思路

  • 这里使用getimagesize()函数判断是否为图片文件。

getimagesize 2()函数用于获取图像大小及相关信息,成功返回-一个数组,失败则返回FALSE 并产生一条E_ _WARNING级的错误信息。 示例:

代码语言:javascript复制
<?php
 $array = getimagesize("images/ flower_1.jpg");
 print_r($array);
 ?>

返回结果:

代码语言:javascript复制
Array
(
[0] => 350
[1] => 318
[2]
=> 2
[3] => width= "350" height="318"
[bits] => 8
[channels] => 3
[mime] => image/jpeg
 )

我们用到了索引[2],表示的是图像的类型,返回的是数字,

其中:

1 = GIF, 2 = JPG, 3 =PNG, 4= SWF, 5= PSD, 6= BMP, 7 = TIFF (英特尔字节顺序), 8= TIFF (摩托罗拉字 节顺序), 9=JPC, 10=JP2, 11=JPX, 12=JB2, 13=SWC, 14=IFF, 15=WBMP, 16= XBM

  • 与上题目解题思路大致相同,上传一张正常得图片,本题验证得内容比较多所以在图片内容末尾加入

解题步骤

  1. 上传正常得jpeg图片,抓包修改包内容,文件内容末尾加入进行上传。(有时候需要删除一部分尾部得内容,防止干扰PHP解析出错)
  2. 使用http://192.168.0.108/upload/include.php?file=./upload/3520200817135922.jpeg 进行文件包含。

第十五关

提示与源码

本pass使用exif_imagetype()检查是否为图片文件!

代码语言:javascript复制
function isImage($filename){
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;  
        default:
            return false;
            break;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}

解题思路

思路同上题

exif_imagetype() — 判断一个图像的类型

返回值: 图像类型常量 值 常量 1 IMAGETYPE_GIF 2 IMAGETYPE_JPEG 3 IMAGETYPE_PNG 4 IMAGETYPE_SWF 5 IMAGETYPE_PSD 6 IMAGETYPE_BMP 7 IMAGETYPE_TIFF_II(Intel 字节顺序) 8 IMAGETYPE_TIFF_MM(Motorola 字节顺序) 9 IMAGETYPE_JPC 10 IMAGETYPE_JP2 11 IMAGETYPE_JPX 12 IMAGETYPE_JB2 13 IMAGETYPE_SWC 14 IMAGETYPE_IFF 15 IMAGETYPE_WBMP 16 IMAGETYPE_XBM

解题步骤

第十六关

提示与源码

本pass重新渲染了图片!

代码语言:javascript复制
$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的图片文件!";
    }
}

解题思路

  • 程序通过imagecreatefromjpeg( )函数调用了PHP GD库(GD库,是php处理图形的扩展库),对图片进行了转换。
  • 将一个正常显示的图片,. 上传到服务器。下载被渲染后与原始图片对比,在仍然相同的数据块部分内部插入Webshell代码,然后上传。
  • 特殊的上传技巧,绕过PHP图片转换实现远程代码执行
  • 巨老解题

解题步骤

  1. 直接上传链接中得POC图片。

POC

第十七关

提示与源码

需要代码审计!

代码语言:javascript复制
$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 = '上传出错!';
    }
}

解题思路

抓取一个post上传得数据,发送到爆破模块选择null payload,设置数据包10000

再抓取一个get访问shell得数据包,同样得null payload ,设置10000

解题步骤

待学习

0 人点赞