upload-labs
知识点
实战思路:
- 判断中间件的类型,看是否存在解析漏洞
- CMS(公共漏洞和暴露,意思是用了别人的组件,而别人的组件有漏洞)
- 编辑器漏洞
- CVE
1.文件上传漏洞的过滤方式
对文件上传进行分类
不同的类型文件上传的方式有所不同,对上传漏洞的分类,对不同的漏洞实行不同的方法可以实现高效率准确的上传。
解析类漏洞
对文件上传进行分类
在解析类漏洞中,长传的是php就只能解析php,解析图片就对图片进行解析。拿对图片的解析来解析PHP是不对的。
cms和cve
对文件上传进行分类
在cms和cve漏洞中有太多的细节,需要参考别人已经实现了的,自己实现起来可能会有大麻烦,因为很多细节不能注意到。
2.解析漏洞+文件上传
中间件解析漏洞
文件解析漏洞,是指Web容器(Apache、Nginx、IIS等在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求。)在解析文件时将文件解析成脚本文件格式并得以执行而产生的漏洞。从而,黑客可以利用该漏洞实现非法文件的解析。
中间件使用特定的方式,使得非脚本文件变成脚本文件执行的情况。
Nginx解析漏洞
中间件解析漏洞
在Nginx中在url最后添加"/x.php"一个任意的php文件,会导致把前面的文件当成脚本执行
3.编辑器漏洞+文件上传
编辑器漏洞
使用在线的编辑器使得可以上传脚本文件到后台并执行
OA系统下的Fckeditor编辑器漏洞
4.文件上传+WAF绕过
绕过的方法
确定数据包中可以修改的项,不可修改的项。通过更改可修改的项的内容对数据进行修改来绕过waf的过程。
#上传参数名解析:明确哪些东西能修改?
Content-Disposition:一般可更改
name:表单参数值,不能更改
filename:文件名,可以更改 Content-Type:
文件 MIME,视情况更改
文件上传的WAF
WAF工作在web服务器之前,对基于HTTP协议的通信进行检测和识别。在用户请求到达Web服务器前对用户请求进行扫描和过滤,分析并校验每个用户请求的网络包,确保每个用户请求有效且安全,对无效或有攻击行为的请求进行阻断或隔离
对用户发来的请求包进行验证,判断请求包当中有无恶意的代码包。如果有就进行截断,如果没有就放包
绕过安全狗对上传文件的拦截
文件上传的WAF
在本地进行waf的绕过练习,尝试思考waf的验证方式,寻找waf的绕过方式。
绕过方法
-
数据溢出-防匹配(xxx…)
通过添加许多无用的数据使得waf验证的数据包被填满
-
符号变异-防匹配(’ " ;)
引用编程思想,验证数据的匹配方式
-
数据截断-防匹配(%00 ; 换行)
换行方式使得waf得到的数据中有\n标准,从而使得验证失败
-
重复数据-防匹配(参数多次
相同的数据重复多次使得绕过
Pass-01(前端)
验证方式
**前端:**通过前端的js代码进行验证(防护)。
思路
- 方法一:在浏览器禁用js代码,缺点会导致其他正常js代码无法正常使用
- 方法二:bp抓包,更改文(filename属性)件后缀名
- 方法三:下载html文件,删除相应的js代码
过程
方法一:
- 在浏览器中禁用js,此时想上传什么类型文件就可以上传什么类型文件了(也就是脚本文件)
- 上床成功后右击图片获取图片链接,访问链接就可以查看上传的脚本。
方法二:
- 把编辑好的脚本改成jpg格式,抓取上传的包,修改filename的文件格式为php,即可上传脚本成功。
方法三:
-
–右击–查看网页源代码
-
复制网页源代码到一个txt文档中,删除检查的文件类型的js代码
-
通过长传一次正常的图片,右击–检查–网络,可以查看上传到的服务器的地址
-
在
标签添加服务器地址到action,(指向何处发送表单数据,即需要发送的服务器的地址) -
把txt文档改成html文档,用浏览器访问进行上传(会出现乱码,但是不影响)


Pass-02(MIME)
验证方式
**后端(MIME验证):**验证文件的MIME信息
$is_upload = false;
$msg = null;
/*
isset -- 检测变量是否设置
判断post过来的数据是否被提交过来
*/
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {//判断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)) {//把临时文件移到UPLOAD_PATH目录
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '文件类型不正确,请重新上传!';
}
} else {
$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
}
}
/*
$_FILES数组内容如下:
$_FILES['myFile']['name'] 客户端文件的原名称。
$_FILES['myFile']['type'] 文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"。
$_FILES['myFile']['size'] 已上传文件的大小,单位为字节。
$_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定,但 用 putenv() 函数设置是不起作用的。
$_FILES['myFile']['error'] 和该文件上传相关的错误代码。['error'] 是在 PHP 4.2.0 版本中增加的
*/
思路
- 抓包更改content_type为验证的类型
过程
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服务器中,在配置文件httpd.conf中有如下配置代码:AddType application/x-httpd-php .php .phtml .phps .php5 .pht,如果不配置他是无法解析php5代码的,访问的时候就是一个空白页。可以随便写一个后缀名,入.hhh,那么上传.hhh的文件都会被当成php来执行。
所以,就是在httpd.com的配置文件中,没有被黑名单限制的后缀。
在上传的时候抓包,修改filename的文件后缀绕过黑名单限制
过程
- 配置phpstudy环境
- 上传php脚本,抓包修改后缀名
- 访问图片链接
Pass-04(.htaccess)
验证方式
后端:黑名单(黑名单齐全),.htacces解析:
$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 . '文件夹不存在,请手工创建!';
}
}
思路
针对Apache,有一个.htaccess的配置文件,
.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
前提是在配置文件httpd.conf中有如下配置代码 不是AllowOverride None ,而是 AllowOverride All
可以先上传.htaccess文件,在文件指定某个文件以php格式运行,在上传木马图片,点击上传好的链接进行运行。
过程
- 配置.htaccess文件,并上传
<FilesMatch "test4.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
匹配到test4.jpg的文件,就以php格式运行

- 制作图片密码(Linux)
其中test3.php为木马代码

- 上传图片test4.jpg,并访问

Pass-05(点绕过)
验证方式
**后端:黑名单,点绕过:**其实于04关代码相同
$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 . '文件夹不存在,请手工创建!';
}
}
思路
**点绕过:**由于后端去除后缀名的点只有一次,所以构造“. .”,点空格点的形式,由于Windows的特性,在文件后缀名过后追加一个点,或者一个空格,还是原文件本身。
比如绕过黑名单验证过后得到的文件后缀为.php. ,由于Windows的特性最后在服务器的文件为.php
过程
- 上传php,抓包更改文件后缀

- 访问上传成功的链接

Pass-06(大小写转换)
验证方式
**后端:黑名单(大小写转换):**后端给出了黑名单,但是代码中没有强制转换成小写
思路
把上传的php文件用大小写混写上传。
过程
- 抓包更改后缀

- 访问上传的链接

Pass-07(空格绕过)
验证方式
**后端,黑名单(空格绕过):**在这里,验证代码中没有最后一步的去掉后面的空格,
思路
在黑名单中没有对".php ",进行过滤。我们可以构造”.php .“来使得最后代码验证过后得到的文件后缀为,“.php ”(含空格)
由于Windows的特性,在文件后缀加上空格,最终得到的文件还是源文件,最终在服务器上的为.php执行文件。
过程
- 抓包构造

- 访问上传好的链接

Pass-08(点绕过)
验证方式
**后端,黑名单(点绕过):**缺少去除后缀后的点
思路
与第五关原理相同
过程
- 抓包更改

- 访问链接

Pass-09(::$DATA)
验证方式
**后端:黑名单,::$DATA:**此次的验证代码中缺失
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
思路
在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名
在文件中添加后缀就行了
过程
- 抓包添加::$DATA

- 访问图片链接
注意url里面要删去图片链接的::$DATA
Pass-10(点绕过)==Pass-05
验证方式
**后端,黑名单:**验证代码只验证一次
思路
因为后端的代码只验证了一次,所以是用双点,来进行绕过
过程
见Pass-05
Pass-11(双后缀名绕过)
验证方式
**后端,黑名单:**一次性的验证,把上传的文件与黑名单相同的替换为空
思路
因为是一次性的验证,且把上传文件中与黑名单相同的文件替换为空,那么可以构造后缀使得替换空过后得到的后缀就是php脚本的。
过程
- 抓包更改数据包

- 访问上传的链接

Pass-12(%00,0x00,/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类型文件!";
}
}
思路
00截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾。
操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号。
因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的。00截断通常用来绕过web软waf的白名单限制
截断的分类
- %00:在url中%00表示ascll码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束,所以当url中出现%00时就会认为读取已结束
- 0x00:0x开头表示16进制,0在十六进制中是00, 0x00就是%00解码成的16进制。需要注意的是,0x00截断是16进制的截断,需要修改16进制的数据头,如果使用burp,就要在Hex中对数据进行改写。
00截断条件
- PHP版本小于5.3.4
- php.ini中的magic_quotes_gpc设置为Off
- 上传路劲可控:据包中须含有上传后文件的目录情况才可以用,比如数据包中存在
path: uploads/,那么攻击者可以通过修改path的值来构造paylod:uploads/aa.php%00
过程
本次实验需要的PHP版本小于5.3.4,而本次实验的php版本高于5.3.4
- 代码是用GET的方式提交的,所以在进行%00截断的时候,%00是写在路径当中的。

Pass-13(同12)
验证方式
**后端,白名单:**只有允许上传指定的文件
思路
13 关与12关有一些差别,12关是的上路劲是GET的方式,是在URL中的,浏览器会自动对其进行解码。
此关卡是用的POST提交的方式,浏览器不会对器进行解码,需要自动编码一下
过程
- 抓包对参数进行修改

- 最终的修改方式

Pass-14(文件包含)
验证方式
**后端,白名单:**但是可以利用文件包含
思路
文件包含
开发人员将需要重复调用的函数写入一个文件,对该文件进行包含时产生的操作。文件包含函数加载的参数没有经过过滤或严格定义,可以被用户控制,包含其他恶意文件,导致了执行非预期代码。
如果设置了fiel变量,则把file的文件包含进去,这个关卡的文件包含

通过设置图片马,把如片上传到网站,然后利用文件包含执行木马
过程
- 制作图片码
Linux
cat init.jpg test14.php >>webshell.jpg
windows
copy init.jpg /b + test14.php /a webshell.jpg
-
上传并获得文件路径
-
设置文件包含
这里要特别注意文件包含的目录,是在include.php中的file进行设置。如果到别的地方去进行包含的话是不能执行脚本的。

Pass-15(文件包含)
验证方式
function isImage($filename){
$types = '.jpeg|.png|.gif';
if(file_exists($filename)){
$info = getimagesize($filename);//获取图像的信息
/* getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。函数成功返回的就是一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
返回的值是一个七位的数组
索引 0 给出的是图像宽度的像素值
索引 1 给出的是图像高度的像素值
索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
索引 3 给出的是一个宽度和高度的字符串,可以直接用于 HTML 的 <image> 标签
索引 bits 给出的是图像的每种颜色的位数,二进制格式
索引 channels 给出的是图像的通道值,RGB 图像默认是 3
索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如: header("Content-type: image/jpeg");
*/
$ext = image_type_to_extension($info[2]);//获取文件的类型
if(stripos($types,$ext)>=0){//查找 $ext在字符串$types中第一次出现的位置
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 = "上传出错!";
}
}
}
思路
同14关一模一样的方式
过程
参见14关
Pass-16
验证方式
后端:exif_imagetype()
知识补充: exif_imagetype()读取一个图像的第一个字节并检查其后缀名。
返回值与getimage()函数返回的索引2相同,但是速度比getimage快得多。需要开启php_exif模块。
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 = "上传出错!";
}
}
}
思路
参见14,15关,主要是需要在php中开启相应的模块
过程
参见14,15关
Pass-17(二次渲染)
验证方式
**后端,白名单:**同时验证文件后缀,MIME文件类型。如果前两步验证成功,则使用imagecreatefromjpeg($target_path);函数对其进行二次渲染。根据图片的大小尺寸进行渲染,这样就会使得我们写的木马代码被渲染无效,不能执行。
$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);//basename返回路劲文的文件名部分
// 获得上传文件的扩展名
$fileext= substr(strrchr($filename,"."),1);
//判断文件后缀与类型,合法才进行上传操作
if(($fileext == "jpg") && ($filetype=="image/jpeg")){
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefromjpeg($target_path);
//由文件或 URL 创建一个新图象
if($im == false){
$msg = "该文件不是jpg格式的图片!";
@unlink($target_path);//删除文件
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".jpg";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagejpeg($im,$img_path);
//用于向浏览器或文件显示图像。此函数的主要用途是在浏览器中查看图像,将任何其他图像类型转换为JPEG并更改图像质量
@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的图片文件!";
}
}
思路
找到渲染前后没有改变的地方,然后把木马写在不变的位置。而且不同格式的修改方式是不一样的。在自己的多次尝试下,都未成功。先留着。
参考链接:upload-labs之pass 16详细分析 - 先知社区 (aliyun.com)
Pass-18
验证方式
**后端,白名单:**先获上传文件的后缀,全名,类型。先把文件暂时上传,然后检验文件的后缀是否合理,如果合理就重新更改名字,否则就删除。
$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 = '上传出错!';
}
}
思路
知识点:当一个文件被修改的时候,是不能对这个文件进行修改的,所以当我们把文件上传上去,在后端还没开始验证的时候去访问这个文件,就不能删除了。