upload-labs通关秘籍和安装环境

2023-11-07

upload-labs通关

一.什么是upload-labs?

upload-labs是一个使用php语言编写的,专门收集渗透测试过程中遇到的各种上传漏洞的靶场。目前一共19关,每一关都包含着不同上传方式

二.漏洞

在这里插入图片描述

三.安装环境


文件上传漏洞总结:upload-labs

安装环境:

1.phpstudy

2.upload-labs靶场

3.burp suite 安装(自行安装,忘记保存安装链接了)

1.phpstudy安装

windows安装网址(本人使用的安装网址):https://www.xp.cn/download.html

Linux 推荐集成环境Xampp,搭建方法参考上篇:

https://blog.csdn.net/qq_36711453/article/details/83713631

安装成功之后打开phpstudy.exe文件,如图,即安装成功
在这里插入图片描述
2.upload-labs靶场安装

Upload-labs是一个所有类型的上传漏洞的靶场

项目地址:https://github.com/c0ny1/upload-labs

打开网址
在这里插入图片描述
点击download ZIP即可安装

注:upload-labs靶场安装包下载完之后,解压到phpstudy中的www同目录下,并将其名字解压后的文件名中的master去掉:
在这里插入图片描述
在浏览器直接打开:

http://localhost/upload-labs/ 或者:http://127.0.0.1/upload-labs/
在这里插入图片描述

四.小试牛刀

第一关 pass-01 客户端检测绕过(js检测)


第一关:pass-01 客户端检测绕过(js检测)

访问Pass-01 ,打开源码:
在这里插入图片描述查看到允许上传的文件后缀为:jpg/png/gif这三种

若想上传一个php文件,直接将该文件的后缀改为以上三种中之一,就可以成功上传。
在这里插入图片描述上传文件名后缀为jpg的文件,使用burp suite进行抓包(使用火狐代理服务器插件)
在这里插入图片描述
在这里插入图片描述
在浏览器打开http://localhost/upload-labs/upload/1.jpg打开可以看到图片,说明文件上传成功
在这里插入图片描述
尝试上传文件后缀为php的文件,显然直接上传该文件是不成功的。
在这里插入图片描述
方案:首先,先将该文件名的后缀改为jpg ,使用抓包软件burp ruite进行抓包
在这里插入图片描述
将抓到的包的文件名后缀改为php,并进行放包,这样文件就上传成功了
在这里插入图片描述
验证:在浏览器打开http://upload-labs/upload/2.php,可以查看到该文件,说明文件上传成功
在这里插入图片描述

第二关 pass-02 content-type(服务器端检测–MIME 类型)


在HTTP 协议中,使用Content-Type 字段表示文件的MIME 类型。当我们上传文件的时候,抓到HTTP 数据包

常见的媒体格式如下:
在这里插入图片描述
进入正题:

源代码如下:
在这里插入图片描述
分析:由该源代码可以看出该服务器端将会对该content-type类型进行检查,从中可以看出image/jpeg image/png image/gif文件类型content-type为以上,文件即可上传成功

那么解题思路就可以Get到了:

首先先随便下载一个php文件(或者自己写的),打开代理服务器,phpstudy,打开burp suite,将php文件上传,使用burp suite软件进行抓包,因为上传的是Php文件,因此content-type的类型不是服务器认可的类型,那么我们就可以使用burpsuite进行修改该文件类型,并将该文件进行上传。
在这里插入图片描述
鼠标右键->发送给Repeater
在这里插入图片描述
此时文件类型并不是服务器所允许的,那么我们可以尝试更改它的类型,使它可以成功上传
在这里插入图片描述
将文件类型修改为image/jpeg并点击发送就可以看到右边的响应数据
在这里插入图片描述
最后进行放包,在浏览器打开http://localhost/upload-labs/upload/1.php并打开upload所在文件夹,可以看到该文件上传成功。
在这里插入图片描述

第三关 上传可解析的文件后缀名


上传可解析的文件后缀名

黑名单绕过:本题不允许上传文件名后缀为asp|.aspx|.php|.jsp的文件

虽然用黑名单不允许上传.asp,.aspx,.php,.jsp后缀的文件
但可以上传.phtml .phps .php5 .pht

主要代码如下:
在这里插入图片描述首先查看apache配置文件中的配置是否允许该文件名后缀
在这里插入图片描述
解决方案:直接将php文件的文件名后缀改为phtml,直接将该文件进行上传,如果出现不能解析php代码,可以采用下面这个靶场:
BUUCTF在线评测
BUUCTF 是一个 CTF 竞赛和训练平台,为各位 CTF 选手提供真实赛题在线复现等服务。
https://buuoj.cn
上传文件之后,很可能文件名会被更改,因此要确定是否上传文件成功,只需要在上传的文件图片那里右键,在新标签页中打开图像,就可以了。

第四关 黑名绕过 .htaccess

主要代码如下:

$deny_ext中的文件后缀都是不允许的,本题不允许上传文件后缀为phtml,htm,php3…

黑名单中没有禁止.htaccess

了解一下.htaccess
文件上传之 .htaccess文件getshell_buffedon的博客-CSDN博客_htaccess文件
https://blog.csdn.net/weixin_46684578/article/details/119141109

在这里插入代码片​
$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); //收尾去空

​

那么解决方案就来了:可以先上传一个文件名为.htaccess的文件,该文件内容为:

<FilesMatch “phpinfo.jpg”>
SetHandler application/x-httpd-php

FilesMatch中的文件为允许上传的文件,因此我们只要将php代码写在记事本中,再将其文件名改为phpinfo.jpg,然后再将其上传就可以解决问题啦。

第五关 黑名单 大小写绕过

黑名单中.htaccess已被列出,不允许上传该文件

可以看出,该代码中禁用后缀名为.php|.php5…|pHp…,该代码没有将文件名转化为小写。

但没有禁用.PHP|.Php|.phP

主要代码如下:

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

​

那么解决方案就出来了:直接将php文件的文件后缀名改为.PHP|.Php|.phP,然后将文件上传就可以了,问题解决。nice!!!

第六关 黑名单 空格绕过

主要代码如下:该黑名单中不仅包含有.htaccess文件,并且还将其文件名转化为小写

因此不能通过更改大小写实现绕过,但是该题目中没有对空格进行首尾进行去空格

​
$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

​

那么解决思路就来啦:我们可以直接写一个php文件,然后在php文件后缀名.php在加一个空格,然后将该文件上传,然后就发现了报错,很有可能是我们在上传文件的时候,Windows系统会将空格删除掉,那么这时我们可以尝试一下使用burp ruite进行文件上传,首先先上传一个后缀名为.php的文件,用burp ruite进行抓包,在抓到的文件的后缀名后面加空格,文件就上传成功啦!!!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题解决,那么我们进入下一关啦啦啦啦啦!!!!

第七关 黑名单 点绕过

主要代码如下:黑名单中包含了.htaccess文件,因此不能使用.htacess,并且该代码将文件的大小写全部改为小写,并且进行了首尾去空格,因此大小写绕过,空格绕过也不能考虑,但还是抓到了一个Bug,该代码并没有进行删除文件名末尾的点

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

​

还是一样,不能直接上传文件名.php.文件,因为windows系统会将文件名后缀的点删除
在这里插入图片描述
那么解决方案就来啦:我们直接上传文件后缀名为.php的文件,使用burp ruite进行抓包,并将抓到的文件的后缀名在加点,这样就成功啦啦啦。

上传成功的结果如下:
在这里插入图片描述

第八关 黑名单 ::$DATA

源代码如下:文件大小写,空格,点绕过都已经不可行了,但该黑名单没有::$DATA

在后缀名加入::$DATA,实现将当前文件不会进行黑、白名单检测
在这里插入图片描述
(此种方法仅仅针对windows平台+php语言的站点才有效)

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

​

那么解决方法来啦:该PHP代码中没有对:: D A T A 进 行 过 滤 , 在 w i n d o w s 中 会 将 文 件 名 : : DATA进行过滤,在windows中会将文件名:: DATAwindows::DATA之后的数据当成文件流处理,保持:: D A T A 之 前 的 文 件 名 。 那 么 我 们 可 以 使 用 B u r p 上 传 文 件 名 为 x x . p h p : : DATA之前的文件名。那么我们可以使用Burp上传文件名为 xx.php:: DATA使Burpxx.php::DATA的文件,实际上传的是xx.php

实操如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
记得把.php后面的::$data去掉,这样文件就上传成功啦啦啦啦!!!

第九关 点 空格绕过黑名单

php代码中在后端使用了黑名单,过滤了大小写,点,空格,但未对文件重命名,并且只过滤了一边点和空格

主要代码如下:

​
$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;

​

那么解决方案来啦:我们使用burp 进行抓包,在抓到的文件名后再加.空格.(xx.php. .),这样过滤完之后该文件命名为:xx.php.,黑名单匹配不到,从而放行,文件上传至保存目录时,windows会自动清除后缀名中的点,使得文件可以正常使用。

实操结果如下:

文件上传成功啦啦啦啦!!!进入下一关啦啦啦!!!!
在这里插入图片描述

第十关 双写绕过黑名单

代码如下:

$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;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

代码中str_ireplace函数对该数组中的文件后缀名进行替换,用空格替换掉该数组中的文件后缀名。
关于php 中str_ireplace函数,可以了解以下链接:
https://www.w3school.com.cn/php/func_string_str_ireplace.asp
那么解决思路来啦:
直接上传文件名后缀为.php的文件,使用Burp进行抓包,将抓到的文件名后缀更改为.pphphp,上传即可成功!!!

第十一关 白名单 %00截断

首先了解一下00截断的原理https://blog.csdn.net/weixin_44840696/article/details/90581104
代码如下:
该php代码中只设置了允许通过的(白名单)文件后缀名为: jpg|png|gif, 并且$img_path = $_GET[‘save_path’]将获取到的文件路径进行拼接。

$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截断的方式,因为00截断的原理,在后缀中插入一个空字符(不是空格),会导致之后的部分被丢弃,而导致绕过的发生
这种情况常出现在ASP程序中,PHP 版本<5.3.4时也会有这个情况,JSP中也会出现。大概了解了,那么我们来进行实操。
实操:
1.需要将php的版本切换到<5.3.4
2.需要将php.ini文件中magic_quotes_gpc=Off
3.加入我们要上传一个php文件,那么我们在上传文件的窗口进行上传该文件,使用burp进行抓包,将抓到的文件的后缀名改为jpg|png|gif,将文件上传路径改为upload/xx.php%00,然后进行放包。
在这里插入图片描述
在这里插入图片描述
然后我们只需要将4.php后面的东西删掉就可以啦啦啦
在这里插入图片描述

第十二关 白名单 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 = $_POST['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只不过是对ascii码中的0对应的字符编码后的结果。0x开头表示16进制,0在十六进制中是00, 0x00则是%00解码成的16进制
注意:当url中的参数是通过GET方式获取时,%00会被自动解码。而当参数是通过POST方式获取时,是不会自动解码的,也就是说%00只会原样被当成字符串来输出。所以通过POST方式请求此类参数的时候,我们需要手动将它的十六进制改写为0x00
实操:
1.PHP的版本要小于5.3.4和在php.ini文件中 magic_quotes_gpc=Off。
2.上传php文件,使用抓包软件进行抓包
在这里插入图片描述
在这里插入图片描述
将图中的25改为00就可以了,接下来的步骤和第11关一致,就不给截图了

第十三关 图片马

代码如下:
该代码中对文件读取头两个字节,并以此判断文件类型
我们可以制作图片马
图片马实际上就是用一张图片和一个php文件(即我们需要的木马病毒)进行合成,最后合成一张带有php代码的图片。

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:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;

制作图片马
1.首先保证图片和php文件在同一个目录中(直接在相关的文件夹打开cmd)
2.copy 1.jpg/b+ 4.php 2.jpg 合成之后的2.jpg即我们需要的图片马
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
若出现这种情况,可以尝试提高php版本,我们对图片马进行上传,那么我们要如何进行解析该图片马中的php语句呢?
文件有包含漏洞的php文件include.php文件,简单来说就是在这个include.php文件中需要引用其他的应用程序,php中的应用程序是.php,也就是说它本来是想引用一个php文件,但漏洞就是,它不会识别什么是php文件,所以会将引用的文件当做php进行解析,我们就可以利用这个漏洞,将图片马最为它引用的文件,那么就可以解析图片马中的php代码喽!!!
采用include.php?file=upload/xxxx.jpg进行解析图片马,图片的名字可能重命名,可以直接在burp中查看文件名。
在这里插入图片描述
成功啦啦啦!!!!

第十四关 getimagesize()-图片马

代码如下:

function isImage($filename){
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
        $info = getimagesize($filename);
    //getimagesize获取宽度,高度,图片类型(文件类型)
        $ext = image_type_to_extension($info[2]);
     //$info[2]刚好是图片类型(文件类型)
     //找出字符串$ext在$types中的位置,若该位置大于0,说明为该字符串中的某一种文件名后缀
        if(stripos($types,$ext)>=0){ 
            return $ext;   //返回该文件后缀名
        }else{
            return false;
        }
    }else{
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){ //isset函数用于检测变量是否已设置并且非null
    $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 = "上传出错!";
        }
    }
}

分析代码:本题中的PHP代码只对图片的前几个字节进行处理,并且只允许上传图片,那么我们任然可以采用和第13关一样的方式进行上传图片马,再用include.php进行解析图片马中的php代码。具体过程就不再演示了。

第十五关 图片马 exif_imagetype()

代码如下:

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

分析:exif_imagetype()函数是php内置函数中用来获取图片类型,因此我们可以通过上传图片马来达到上传php木马的目的。当在上传图片马之前,需要打开php_exif,打开之后,步骤和第13关一样!!!记得还是要使用include.php进行解析!!!
在这里插入图片描述

第十六关 二次渲染绕过

代码如下:

$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的图片文件!";
    }
}

分析:
该php代码中允许上传图片,但会对图片进行二次渲染,因此我们需要绕过二次渲染的部分,也就是在在二次渲染不会改变的部分加入我们需要的php木马的代码
满足move_uploaded_file就可以上传成功!!!
实操如下:
我们需要安装winhex软件,在winhex中打开图片,首先我们需要准备一个木马图(操作步骤和第13关一致),文件名后缀为gif的图片,下面两张图是进行二次渲染(左边)之后的和未进行二次渲染(右边)的图片的内容,因为制作图片马时,PHP代码放在了最后,在进行二次渲染时,该代码部分被改变了。
在这里插入图片描述
对比两张图片的内容,很容易在靠近头部的位置有很多位置是是二次渲染之后没有改变的部分,那么我们就可以尝试将我们的Php木马写入这段区间中喽!(注意:不要在头部插入Php代码,会破坏gif文件头,验证图片会失败,就上传不了图片喽)
在这里插入图片描述
将php代码隐藏在二次渲染不会改变的部分
在这里插入图片描述
再次将隐藏好Php代码的图片进行上传,发现该区间没有被改变,因此,图片马上传成功。
在这里插入图片描述
接下来就是使用Include.php包含漏洞的原理进行解析该图片马,成功啦啦啦!!!
在这里插入图片描述

第十七关 条件竞争

代码如下:

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

科普:
条件竞争漏洞是一种服务器端的漏洞,是由于开发者设计应用程序并发处理时操作逻辑不合理而造成。当应用面临高并发的请求时未能同步好所有请求,导致请求与请求之间产生等待时出现逻辑缺陷。该漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。
分析:
从源码看,服务器是将上传的文件保存下来,在对该文件的后缀名与白名单中的进行比较,若果为白名单中的后缀名,就会将文件进行重命名,否则,就会通过unlink()函数进行删除该文件。首先,代码执行过程是需要消耗时间的,因此我们要在上传的php文件被删除之前,成功的解析访问它,因此我们需要使用burp进行发送无限多的数据包,并使用python脚本去连接该文件,以此来判断该文件是否上传成功,并且在浏览器不停访问该文件的默认上传路径,一直不停刷新,直至访问成功,实验就成功啦啦啦!!!!
在这里插入图片描述
在这里插入图片描述
点击attack进行攻击,无限次发包
在这里插入图片描述
使用以下的python进行判断,当文件上传成功时,会出现ok

import requests  # 第三方库
import os  # 为了让屏幕停留导入的库

url = "http://localhost/upload-labs/upload/4.php"

while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break

os.system('pause')  # 停留

在这里插入图片描述
疯狂点击刷新,直至访问到该php文件
在这里插入图片描述
成功啦啦啦!!!!

第十八关 上传重命名竞争

代码如下:

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

分析:
在这里插入图片描述
审计后发现文件的白名单只有以上这些
在这里插入图片描述
打开了完整的代码,发现文件上传保存的地址为空,也就是会将上传的文件保存和upload同级目录下,而不是子目录
在这里插入图片描述
最后上传的文件名会被改名!!!
查看了源码:发现该php代码会先对文件类型进行匹配,先检查文件类型,如果文件类型匹配成功之后,就会将该文件进行移动,并且移动到和upload的同级目录下面,然后再对该文件进行重命名。
重点:因此我们需要上传一个文件名后缀为白名单中存在的,否则,下面的过程都无法进行啦!!!浏览器遇到不能解析的后缀时,会向前解析,发现只有7z结尾的后缀不会被解析。所以我们可以考虑一下上传4.php.7z的文件,这时我们要利用上传重命名的竞争性,我们已经知道文件上传之后是先保存后再重命名,改名是需要时间的,那么我们就使用Burp无限上传4.php.7z的文件,这样我们就可以直接在浏览器进行访问http://localhost/upload-labs/upload4.php.7z直到访问成功(要一直疯狂刷新哦),那么文件就上传成功啦啦啦啦!!!
我们在重命名成功之前执行木马程序(其实就是在浏览器解析):
4.php.7z

<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php phpinfo(); ?>');

?>

成功上传解析之后可以在upload同级目录下查看到shell.php文件,然后我们可以对该文件进行访问。

我们还可以采用以下python代码验证是否有上传成功:

# 注意:使用时记得删去注释,否则cmd窗口会一闪而过
import requests  # 第三方库
import os  # 为了让屏幕停留导入的库

url = "http://localhost/upload-labs/upload4.php.7z"

while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break

os.system('pause')  # 停留

在这里插入图片描述
文件上传成功并解析成功之后文件目录时这样的(发现了shell.php文件):
在这里插入图片描述
对shell.php进行解析
在这里插入图片描述
成功!!!

第十九关 黑名单绕过 00截断

代码如下:

$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 = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

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

分析:
从源码看,服务器定义了一系列黑名单,并且都是小写的文件名后缀,save_name参数为我们保存的名称的参数。并且该代码并没有对文件类型进行处理,仅仅只是对保存的文件名做了黑名单处理,那么我们可以直接上传4.PHP文件,完全可以直接绕过(记得保存名称的后缀名要改为PHP)!!!!
在这里插入图片描述
上传成功!!!,可以直接在浏览器解析该文件!!
在这里插入图片描述
在这里插入图片描述
这是第一种解决方案,接下来是第二种,采用的00截断的方式:
分析:
mov_upload_file()函数中的Img_path是由post参数save_name控制地,因此我们可以利用这一漏洞,使用00截断(记得环境要符合)绕过:
上传图片马

在这里插入图片描述
将+号对应的2b改成00
在这里插入图片描述
将包上传,在浏览器解析,成功啦啦啦!!!!
在这里插入图片描述

第二十关 数组绕过

代码如下:

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

分析:
该代码中先进行MIME进检查,该代码允许的content-type类型:‘image/jpeg’,‘image/png’,‘image/gif’,end会判断该数组的最后一个元素是否合理,也就是图片格式的后缀名,我们可以直接设置数组中参数的值,只要保证最后一个参数能满足条件(jpg/png/gif)就可以成功绕过检验。
实操:
1.先准备好一个php文件
2.使用burp进行抓包,需要将该包中的content-type改成允许的类型,如:image/jpeg
其次,将索引[0]为xx.php/,索引[2]为jpg/png/gif如图:

然后进行放包,会发现生成了一个索引[0]的文件。将该文件进行解析,成功啦啦啦!!!!
在这里插入图片描述
靶场闯关就先告一段落喽!欢迎大家批评指正!!!一起学习啦啦啦!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

upload-labs通关秘籍和安装环境 的相关文章

  • 在 PHP 数组定义中显示重复键警告

    下面的代码是否可以得到警告 error reporting E ALL s array a gt 1 a gt 1 var export s 你唯一的希望 除了count 你自己 是你的编辑足够聪明 可以突出显示拼写错误 此屏幕截图来自 P
  • 在多维数组 PHP 的所有键中搜索

    我想在多维数组中的所有键中搜索特定字符串 我只需要弄清楚它是否存在 仅此而已 我想知道访问者的 IP 是否存在于任何数组中 有没有我可以用来执行此操作的 php 函数或方法 我尝试过的每个函数或方法总是返回 false 数组中 数组搜索 数
  • 是否可以在 UML 中可视化一堆函数

    我正在改进一个使用类和函数文件 只是包含各种函数的 php 文件 的内容管理系统 例如 我有一堂课叫Admin以及一个功能文件 其功能包括显示管理员概述 创建新管理员 编辑现有管理员 删除管理员 函数文件使用类并执行 mvc 概念的可视化部
  • Codeigniter PHP - 在锚点加载视图

    我在一个长页面的底部有一个表单 如果用户填写了表单但它不验证页面是否以典型的 codeigniter 方式重新加载 this gt load gt view template data 然而 由于表单位于页面底部 我需要将页面加载到那里 就
  • Facebook“赞”按钮回调帮助

    我正在使用此代码进行类似 facebook 的回调 问题是 如果我调用 php 脚本 例如 有人可以看到我的 javascript 并运行此页面 甚至可以向其发送垃圾邮件或在没有先点赞的情况下使用它 我的想法是 我想为每个喜欢该页面的用户提
  • 随机错误 symfony:ContextErrorException: 警告: simplexml_load_file(): I/O 警告: 无法加载外部实体

    在我的 Symfony 项目中 当我进入应用程序中的随机页面时 会出现以下随机错误 ContextErrorException Warning simplexml load file I O warning failed to load e
  • DataTables 第 2 页的分页未调用放大弹出窗口

    所以我有这个启用分页的数据表 我编码了一种方式 以便用户可以编辑表的行 当用户调用它在放大弹出窗口中打开的编辑页面时 它在第 1 页 从第 2 页起都运行良好 DataTable 及其前面停止调用 Magnific Popup 我只是不明白
  • Symfony 生成器形式、原则和 M:N 关系

    我有一个基本的 M N 设置 包含三个表 candidate position 和 Candidate position 这是 MySQL Workbench 的 ERD 屏幕截图 现在 我们继续讨论表单 在 symfony 生成器的默认世
  • 查明具有特定 ID 的会话是否已过期

    我正在创建一个上传功能 将用户上传的文件存储在服务器上 并以用户的会话 ID 作为名称 现在 我只想将此文件保留在服务器上 直到该会话处于活动状态 所以 我的问题是 如何根据会话 ID 确定会话是活动的还是过期的 以便在后一种情况下我可以安
  • PHP Github Pull 脚本错误“权限被拒绝(公钥)”

    我已经设置了一个 PHP 脚本来执行 GitHub 拉取 这包含在我的 Github 文件夹中 home mysite public html github github pull php 我的服务器已经有 SSH 公钥 就像我执行git
  • PHP 电子邮件验证[重复]

    这个问题在这里已经有答案了 For PHP最好的电子邮件验证方法是什么preg NOT ereg因为它是已弃用 删除 I don t需要检查该网站是否存在 这不像最高安全性 我找到了很多方法ereg但它们 显然 不是好的做法 我建议你使用F
  • 彩色 var_dump() 和错误

    我怎样才能将样式设置为var dump 功能和PHP错误样式 如下图所示 目前我有下一个观点var dump with pre var dump pre 没有它将全部在一行中 并且只是纯文本的错误 我搜索了一些 PHP 颜色错误 var d
  • Yii 未检测到骆驼案例操作

    伊伊正在给我404 Error如果我声明这样的操作 站点控制器 php public function actionRegisterUser 这就是我在main php label gt Register User url gt site
  • 将 echo 和 print 合并到一个语句中

    echo 1 print 2 3 返回 214 脚本如何以 14 结尾 当你这样做时 echo 1 print 2 3 PHP 会做 demo http codepad viper 7 com OfrNrs line op fetch ex
  • PHP-如何根据条件配对数组中的项目

    如何将数组中的项目配对 假设我有一个数组Fighters 我想根据他们的情况将他们配对Weights 体重最接近的拳手应作为配对最佳匹配 但如果他们是在同一个团队中 他们不应该配对 团队 1 战斗机A体重为60 战斗机B体重为65 2队 战
  • 控制数据是否存在于数组中

    我在mysql中有两个不同的表 我正在使用curl从json文件中获取数据 我的第一个表名称是 tblclients 该表存储客户端数据 我的第二个表名称是 tblcustomfieldsvalues 该表使用 tblclients 表的
  • WordPress - 类别和子类别的嵌套列表

    我正在尝试显示带有嵌套子类别的 WordPress 类别列表 到目前为止 我只能获取父类别列表或不包括父类别的子类别列表 但我无法将两者连接在一起 这是我想要创建的结果 Parent Category 子类别 子类别 Parent Cate
  • Mysql加密/存储敏感数据,

    我的 PHP 网站有以下内容 启用 SSL 饼干 session set cookie params cookieParams lifetime cookieParams path cookieParams domain secure ht
  • 管理产品页面自定义字段显示在购物车和结账中

    我在产品页面的常规设置选项卡上的 WooCommerce 管理中创建了一个自定义字段 以插入几天的制造时间 我想在购物车和结帐页面上每个产品名称上方显示此自定义字段值 这是我的代码 Insert a Custom Admin Field f
  • 如何统计订单总价?

    我有这些表 Orders id status user id address id 1 await 1 1 products id name price quantity 1 test1 100 5 2 test2 50 5 order p

随机推荐

  • 索引构造与信息检索:让 ChatGPT 成为 Selenium 问答助手

    这是chatgpt为我生成的3个标题 我选了第3个 利用 Langchain 和 GPT 实现 Selenium 机器人自动问答 向量化存储和检索 如何用相似度搜索匹配 Selenium 知识 索引构造与信息检索 让 ChatGPT 成为
  • open3d python版本安装及安装过程中遇到的问题

    本文介绍一下我在安装open3d包过程中遇到的问题 pip安装 pip install open3d pip install open3d i https pypi tuna tsinghua edu cn simple or pip in
  • npm镜像设置

    查看镜像列表 npm isntall g nrm nrm ls 根据镜像列表地址来设置镜像 例如 npm config set registry https registry npmjs org 查看镜像 npm config get re
  • 高通QCM6125的LK部分(uefi/xbl)编译

    高通在QCM6125安卓10 0加入了UEFI 以前的lk相关代码移到了boot images QcomPkg路径下 编译方式和之前也不同了 编译环境 编译时错误提示 需要工具在这个路径 pkg qct software llvm rele
  • KNX协议入门

    KNX协议入门 转自 https wenku baidu com view 65b0a25a55270722182ef706 html 如有侵权 请联系qq 2453419889 我将立即删除 一 KNX技术简介 KNX通过一条总线将各个分
  • Dapper功能讲解

    简述 适用特性 使用Dapper流程 代码示例 简述 Dapper是一个轻量级的ORM工具 ORM框架的核心思想是对象关系映射 ORM是将表与表之间的操作 映射成对象和对象之间的操作 就是通过操作实体类来达到操作表的目的 从数据库提取的数据
  • [637]文件或目录损坏且无法读取CHKDSK修复方法

    文件或目录损坏且无法读取 不要太担心是出现了磁盘坏道 也许只是小小的存储问题 解决方法很简单 用chsdsk命令即可 方法如下 开始 运行 输入cmd 输入chkdsk 盘符 f 例如 chkdsk c f 等命令运行完即可 注意 冒号后面
  • matlab中size()的用法

    size A 设有一矩阵为A 则size A 返回的是一行向量 该行向量的第一个元素时矩阵的行数 第二个元素是矩阵的列数 size A 1 获取矩阵A的行数 size A 2 获取矩阵A的列数
  • 数学的1000+篇文章总结

    数学的1000 篇文章总结 本文收集和总结了有关数学的1000 篇文章 由于篇幅有限只能总结近期的内容 想了解更多内容可以访问 http www ai2news com 其分享了有关AI的论文 文章 图书 query 第13章 爱因斯坦 量
  • C#实现程序的版本升级更新

    我们做了程序 不免会有版本升级 这就需要程序有自动版本升级的功能 那么看看我是如何实现程序自动更新的 直接上代码 using System using System Collections Generic using System Text
  • 数学建模学习2论文排版

    如何写论文 一 四点注意事项 一 标题与正文层次分明 二 正文排版紧凑 三 表格与图片格式 四 公式编辑 二 如何写标题 一 要求 二 格式及示例 三 如何写摘要 一 要求 二 格式及示例 1 总体格式图 2 开头段模板 3 中间段模板 4
  • 机器学习笔记-感知机对偶形式

    文章目录 前言 一 感知机对偶形式 二 感知机对偶形式的实现 总结 前言 感知机模型是有两种形式的 上一篇文章中详细学习了感知机的原始形式数学模型 我们知道 感知机应该还有对偶形式 这篇文章就来记录一下感知机对偶形式的的数学模型 一 感知机
  • Object.entries()

    Object entries 方法返回一个给定对象自身可枚举属性的键值对数组 其排列与使用 for in 循环遍历该对象时返回的顺序一致 区别在于 for in 循环还会枚举原型链中的属性 语法 Object entries obj 参数
  • 构造函数与析构函数的保护权限

    通常我们如果希望对象只在堆上创建 我们会将析构函数定义为protect或private类型 这种情况下我们还要添加一个函数来析构对象 因为此时在类外部无法使用delete释放对象 因为析构函数被保护 那么究竟为什么限制析构函数的访问权限可以
  • 下载网页视频简单的办法之一

    下载网页视频简单的办法之一 下载小网站网页视频的简单办法之一 添加插件 使用方法 局限性 下载小网站网页视频的简单办法之一 经常在小网站 比如91xxx youxxxx 上看到喜欢的小视频 想要收藏 你懂的 无赖很多都要VIP才给下载 以前
  • kali_linux (install版)移动硬盘(物理机)安装记录

    作者 瓴 时间 2023 04 23 kali linux install版 移动硬盘 物理机 安装问题记录 1 安装介绍 1 1 相关参数 2 kali 安装 2 1 制作系统启动U盘 2 2 移动硬盘分区 2 2 系统安装 2 3 引导
  • UE4_异步_数据处理(Json)

    如果一个数字城市demo 需要将第三方海量的数据进行处理展示 将数据的处理放在GameThread 上显然是不合理 这个时候需要用多线程解析数据 防止游戏线程的阻塞 关于异步和多线程 前两天面试被别人问到一个问题 异步和多线程的区别 面试的
  • 代码静态测试工具

    Ounec5 0 扫描语言VB C C C Java 属于付费工具 Coverity Prevent 扫描语言有C C C Java 属于付费工具 Stake SmartRiskAnalyzer 扫描语言C C Java 属于付费工具 Ra
  • 【缓存】一种新的缓存 Caffeine Cach 介绍

    1 概述 转载 真正的缓存之王 Google Guava 只是弟弟 Guava Cache 他的优点是封装了get put操作 提供线程安全的缓存操作 提供过期策略 提供回收策略 缓存监控 当缓存的数据超过最大值时 使用LRU算法替换 这一
  • upload-labs通关秘籍和安装环境

    upload labs通关 一 什么是upload labs 二 漏洞 三 安装环境 四 小试牛刀 第一关 pass 01 客户端检测绕过 js检测 第二关 pass 02 content type 服务器端检测 MIME 类型 第三关 上