文件上传Upload-labs学习笔记

前言

Upload-labs是一个帮你总结所有类型的上传漏洞的靶场,包括常见的文件上传漏洞,项目地址:

https://github.com/c0ny1/upload-labs

先看下GitHub上的总结:

1、靶机包含漏洞类型分类

在这里插入图片描述

2、如何判断上传漏洞类型

判断上传漏洞类型

第一关

查看源代码,调用的前端js限制上传文件类型

image-20220210200504206

先将php文件命名为.jpg文件,然后上传,抓包修改文件后缀名为.php文件,forword即可。鼠标右键查看图片源码,找到php文件路径,木马连接

image-20220210200821939

第二关

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

上传phpinfo2.php文件,抓包,修改Content-Type内容为 Content-Type: image/jpg

image-20220211005443531

forward,访问上传文件

image-20220211005655236

另外,这一关也可以通过上传phpinfo.png抓包修改为phpinfo.php,因为上传后缀为png时候,这时候

Content-Type默认会是image/png

第三关

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

直接上传php文件,提示:不允许上传.asp,.aspx,.php,.jsp后缀文件!

可以知道是黑名单限制了后缀名,可以尝试用php3,phtml绕过

image-20220211090123795

image-20220211085600101

前提是apache的httpd.conf中有如下配置代码

AddType application/x-httpd-php .php .phtml .phps .php5 .pht .php7等

image-20220211091339123

第四关

$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,可以上传一个.htaccess文件,内容如下:

SetHandler application/x-httpd-php

image-20220211095923684

然后上传后缀为jpg的图片马,也可以正常解析了

image-20220211100032238

第五关

$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 ,但是没有对大小写,直接上传.pHP文件

image-20220211102554896

第六关

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

这关还是黑名单,但是没有对后缀名进行去空处理,可在后缀名中加空绕过:

windows下xx.jpg[空格] 或xx.jpg.这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点此处会删除末尾的点,但是没有去掉末尾的空格,因此上传一个.php空格文件即可。

image-20220211104516013

image-20220211104527789

第七关

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

对比第六关没有去除文件名末尾的点

image-20220211105239669

image-20220211105211631

第八关

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

NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$ DATA。上传.php::$DATA绕过。(仅限windows)

image-20220211110756630

image-20220211110839590

第九关

对比上面有个明显的一点就是这里用上传的文件名作为上传后的文件名,未重新命名。

image-20220211112159130

可以利用第7行和第11行,去末尾点和空的方法绕过

image-20220211112532864

image-20220211113048532

第十关

image-20220211113129407

覆写绕过

image-20220211144944210

image-20220211144911747

第十一关

image-20220211145448008

第8行,save_path参数可控,使用%00截断

image-20220211150135290

image-20220211150603860

第十二关

image-20220211150815455

不同于第十一关,第7行save_path参数是用POST方式传递的,这里需要对%00进行url解码,因为POST不会像GET对%00进行自动解码

image-20220211151528898

解码后

image-20220211151759445

image-20220211151328655

第十三关

image-20220211160416177

通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,制作方法:

copy hacker.png/b+phpinfo.php/a muma.png

image-20220211160607033

利用文件包含拿到webshell

image-20220211160513519

第十四关

image-20220211161111956

利用getimagesize()函数获取图像类型,同第十三关,制作图片马

image-20220211161215610

第十五关

image-20220211161330583

利用php_exif模块来判断文件类型,同样可以利用图片马就可进行绕过:

image-20220211161432737

第十六关

在这里插入图片描述

本关综合判断了后缀名、content-type,以及利用imagecreatefromjpg判断是否为jpg图片,最后再做了一次二次渲染,绕过方法:

同样用上面的图片马方法可以绕过

image-20220211162729777

另外制作gif图片马好像更为简单

image-20220211163358092
在这里插入图片描述

第十七关

image-20220211172008079

可以看到文件先经过保存,然后判断后缀名是否在白名单中,如果不在则删除,此时可以利用条件竞争在保存文件后删除文件前来执行php文件

在这里插入图片描述

此时回在upload目录下,不断有phpinfo.php文件出现消失,证明利用该漏洞上传成功了。

另外可以不断抓包请求 ./upload/phpinfo.php证明上传成功了,只不过很快被删了

第十八关

image-20220211231002170

image-20220211231228967

本关对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功:

image-20220211231840887

选择空payload,进行爆破

image-20220211232124083

可以在www下面看到有些还未来得及重命名的文件,因此我们可以通过条件竞争来上传图片马。

在这里插入图片描述

第十九关

在这里插入图片描述

发现move_uploaded_file()函数中的img_path是由post参数save_name控制的,因此可以在save_name利用%00截断绕过:

image-20220212000041977

image-20220212000133547

另外move_uploaded_file会忽略掉文件末尾的/. 因此构造save_name参数为 upload-19.phpjpg/. 也是可以的

第二十关

在这里插入图片描述

可以发现$file_name经过reset($file) . '.' . $file[count($file) - 1];处理。

如果上传的是数组的话,会跳过$file = explode('.', strtolower($file));。并且后缀有白名单过滤

$ext = end($file);
$allow_suffix = array('jpg','png','gif');

而最终的文件名后缀取的是$file[count($file) - 1],因此我们可以让$file为数组。$file[0]upload-20.php/,也就是reset($file),然后再令$file[2]为白名单中的jpg。此时end($file)等于jpg,$file[count($file) - 1]为空。而 $file_name = reset($file) . '.' . $file[count($file) - 1];,也就是upload-20.php/.,最终move_uploaded_file会忽略掉/.,最终上传upload-20.php

image-20220211235414622

image-20220211235459550

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值