(白帽子学习笔记)前渗透——文件上传upload labs
读者需知
1、本文仅供学习使用,由于传播和利用此文所造成的损失均由使用者本人负责,文章作者不为此承担责任
2、本文参考了一些文章,如有侵权请联系本人删除
第一关——前端验证
1、将浏览器中的JS代码禁用即可绕过
未禁用前:
禁用后:
——————上传成功
第二关——对content-type进行绕过
源码
$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.'文件夹不存在,请手工创建!';}
}
绕过方式:
先用php文件测试
对content-Type进行绕过
放包后即可绕过
第三关——该配置文件绕过黑名单
源码
$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 . '文件夹不存在,请手工创建!';}
}
在httpd.conf改配置文件
AddType application/x-httpd-php .php .phtml .php1 .php2 .php3
第四关——利用.htaccess文件进行绕过
.htaccess文件介绍
.htaccess 文件是 Apache 服务器中的一个配置文件,它负责相关目录下的网页配置,通 过.htaccess 文件可以实现网页 301 重定向、自定义 404 页面、改变文件扩展名、允许/阻 止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
利用条件:
必须启用下面 apache 模块和 httpd.conf 才可以
- rewrite_module 模块开启(默认开启了)
- AllowOverride All(httpd.conf 中默认开启)
- 在 AllowOverride 设置为 None 时, .htaccess 文件将被完全忽略。
- 当此指令设置为 All 时,所有具有 “.htaccess” 作用域的指令都允许出现在 .htaccess 文件中。
绕过方式:
1、上传以下文件,可以解析含有php代码的文件
2、修改上传文件名即可上传
第五关——利用 点空格点 进行绕过(对.htaccess进行了屏蔽)
源码
$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");$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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
抓包修改后缀为1.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 . '文件夹不存在,请手工创建!';}
}
出现漏洞原因:
没有进行大小写转换(strtolower()函数可以把对应字符串转换为小写)
绕过方式:
将php后缀转换为带有大写的,即可绕过
第七关——加空格绕过(windows特性绕过)
源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
此源码含有$file_name = deldot($file_name);//删除文件名末尾的点
不能进行加点绕过
没有$file_ext = trim($file_ext); //首尾去空
使得可以进行空格绕过
第八关——加点绕过(windows特性绕过)
源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
此源码中含有$file_ext = trim($file_ext); //首尾去空
使得无法空格绕过
没有$file_name = deldot($file_name);//删除文件名末尾的点
使得可以进行加点绕过
第九关——用::$data进行绕过
关于
::$data
的定义Windows 下,如果上传的文件名中包含::$DATA 会在服务器生成一个同名且内容也相同的 php 文件,但是 Windows 中文件名不能包含特殊字符。
如:test.php::$DATA 会在服务器上生成 test.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 = 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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
未显示存在$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
的代码
抓包修改文件名后缀为.php::$data
即可绕过
第十关——后缀加点空格点进行绕过
源码
$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 . '文件夹不存在,请手工创建!';}
}
原理
在上传中如果用户文件名不会被重命名时,用户可以自定义文件名并在服务器创建,就可以 绕过黑名单。
如:
用户新建一个文件:
1.php.+空格+.
deldot 函数会处理最后一个点,
trim 函数删除空格,那么文件名会成为
1.php.
最后windows 处理时会自动去掉最后一个点,
这个时候就饶过黑名单及 一些函数的处理。
绕过方式:
第十一关——双写绕过(其他方式也行)
源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
1、根据代码来看,代码中没有进行过滤的方式都可以进行上传。
2、根据代码所看,虽然定义了deny_ext()函数(黑名单),但是没有使用,如果直接上传php文件会变成
3、根据$file_name = str_ireplace($deny_ext,"", $file_name);//替换函数,将后缀替换成空格
可知,本关主打双写等绕过方式。
第十二关——白名单绕过(图片马绕过或%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类型文件!";}
}
###可以看到$img_path则是上传的路径,该路径从save_path中获取,然后再将文件重命名###
绕过方式
1、上传图片马即可绕过
2、也可利用%00截断进行绕过(实战中基本不存在)
(%00被当做结束符,后面的数据其实就已经被截断了,服务器保存的则是1.php这个文件名)
%00截断满足条件
- PHP<5.3.29( 00 截断受限于 addslashes 函数 )
- 修改php.ini配置文件
magic_quotes_gpc = on
为off
第十三关——POST型%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 = $_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类型文件!";}
}
绕过方式
从源码$img_path = $_POST...
可知,截断需要用post型
抓包并对请求内容的hex进行改写
改写后即可绕过
第十四关——图片马绕过
(利用文件内容的前两个字节判断文件类型)
源码
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 = "上传出错!";}}
}
绕过方式:
1、直接在文件内容前加上文件类型字节,即可绕过
2、(利用文件的头两个字节来进行判断,光改后缀名不顶用,文件内容也要相应改变)
直接利用命令行生成图片马即可绕过
第十五关——图片马绕过(getimagesize)
getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度,所以上传的文件不能只是包含文件头那么简单,所以采用图片马技术绕过
但是实践结果是包含文件头也能绕过
源码
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 = "上传出错!";}}
}
绕过方式:
1、上传图片马即可绕过
2、也可以修改文件头绕过
第十六关——exif_imagetype绕过
exif_imagetype() 读取一个图像的第一个字节并检查其签名。
源码
function isImage($filename){//需要开启php_exif模块$image_type = exif_imagetype($filename);switch ($image_type) {case IMAGETYPE_GIF:return "gif";break;case IMAGETYPE_JPEG:return "jpg";break;case IMAGETYPE_PNG:return "png";break; default:return false;break;}
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$res = isImage($temp_file);if(!$res){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}
绕过方式:
利用图片马绕过
第十七关——二次渲染
二次渲染大体意思是说我们传进去的图片马在传进去的同时会被二次渲染,二次渲染会导致图片中的木马会被重置,然后再去加载到对应文件中,而图片马就会因此失去效果,我们所要做的就是绕过他的渲染,从而成功上传。
源码
$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的图片文件!";}
}
move_uploaded_file()
——将上传的文件移动到新位置
imagecreatefromjpeg
——由文件或 URL 创建一个新图象,成功后返回图象资源,失败后返回 FALSE 。
unlink
——删除文件
srand
——播下随机数发生器种子
strval
——获取变量的字符串值
绕过方式:
以下为参考博客网址
https://www.fujieace.com/penetration-test/upload-labs-pass-16.html
第十八关——条件竞争
源码
$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 = '上传出错!';}
}
绕过方式:
1、利用图片马+文件包含可以读取文件内容
2、条件竞争
原理:
- 通过BP的攻Intruder模块来发送大量包,让其和php文件删除进行条件竞争,
- 在利用不稳定的上传的1.php进行文件解析,也就是在1.php文件快要删除时对其进行文件解析,在其中生成另一个脚本shell
- 在浏览器中访问/upload/1.php,当访问的页面不为404等,就可以直接访问/upload/shell.php
其中1.php的文件内容为以下即可
<?php file_put_contents(‘shell.php’,”<?php phpinfo();?>”)>
第十九关——条件竞争
源码
//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{require_once("./myupload.php");$imgFileName =time();$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);$status_code = $u->upload(UPLOAD_PATH);switch ($status_code) {case 1:$is_upload = true;$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;break;case 2:$msg = '文件已经被上传,但没有重命名。';break; case -1:$msg = '这个文件不能上传到服务器的临时文件存储目录。';break; case -2:$msg = '上传失败,上传目录不可写。';break; case -3:$msg = '上传失败,无法上传该类型文件。';break; case -4:$msg = '上传失败,上传的文件过大。';break; case -5:$msg = '上传失败,服务器已经存在相同名称文件。';break; case -6:$msg = '文件无法上传,文件不能复制到目标目录。';break; default:$msg = '未知错误!';break;}
}//myupload.php
class MyUpload{
......
......
...... var $cls_arr_ext_accepted = array(".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",".html", ".xml", ".tiff", ".jpeg", ".png" );......
......
...... /** upload()**** Method to upload the file.** This is the only method to call outside the class.** @para String name of directory we upload to** @returns void**/function upload( $dir ){$ret = $this->isUploadedFile();if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->setDir( $dir );if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->checkExtension();if( $ret != 1 ){return $this->resultUpload( $ret );}$ret = $this->checkSize();if( $ret != 1 ){return $this->resultUpload( $ret ); }// if flag to check if the file exists is set to 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" );}
......
......
......
};
绕过方式:
方法一:
和前一关非常类似,只不过结和前面几关的方法,对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功
方法二:
也可以利用图片马
第二十关——保存文件名可控
源码
$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 . '文件夹不存在,请手工创建!';}
}
绕过方式:
将保存文件名进行修改绕过
例如:加点绕过或者%00及截断
第二十一关——upload in CTF(数组绕过)
本关引用博客链接:https://blog.csdn.net/mi900709/article/details/110919368
源码
$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 = "请选择要上传的文件!";
}
绕过方式:
相比较第二十关,这一关对文件类型进行了限制
empty函数:检查一下变量是否为空;返回值:如果变量是非零非空的值返回False,否则返回True;
三运运算符:(expr1) ? (expr2) : (expr3); 如果条件expr1 成立,执行expr2,否则执行expr3;
end函数:将内部指针指向数组最后一个元素并输出;
reset函数:将内部指针指向数组第一个元素并输出;
关键点在于以下代码:
如果$file 不是数组的话,就会将$file 以" . " 分割,打散成数组;
正常逻辑抓包改包,即使绕过文件类型检测,文件后缀名白名单检测绕不过去;
利用上图的代码可以POST数组绕过,如下:
这样构造的话,$file 本身就是数组了,直接执行end函数,end($file) = jpg, 接下来通过文件后缀名白名单检测,继续执行;
$file_name = reset($file) . '.' . $file[count($file) - 1];
这样count($file) -1 =1,$file[1] 就为空,最终拼接后 $file_name = up.php/.
继续分析
move_uploaded_file
这个函数在执行的时候会忽略掉末尾的/. 最终文件已php的后缀名成功上传。
(白帽子学习笔记)前渗透——文件上传upload labs相关推荐
- 【信安学习笔记三】文件上传
个人学习参考用笔记 目录 前言 一.文件上传 **定义** **危害** **查找及判断** **分类** 二.验证与绕过 前端防护 后端防护 (一)黑名单 (二)白名单 (三)内容及其他 三.漏洞 ...
- Laravel学习笔记4,文件上传,分页,验证码,数据表和迁移
目录 一.文件上传 二.数据分页 三.验证码 Return Image Return URL Return HTML 六.响应处理 一.文件上传 在laravel, 里面实现文件的上传是很简单的,压根 ...
- 第三十二天学习笔记-web漏洞-文件上传的条件竞争、.htaccess文件与.user.ini文件使用前提、二次渲染
目录 二次渲染原理 绕过方法 htaccess配置文件 .user.ini 二次渲染原理 在我们上传文件后,网站会对图片进行二次处理(格式.尺寸,保存,删除 要求等),服务器会把里面的内容进行替换更新 ...
- ssm上传文件进度条_ssm学习笔记-三种文件上传方式
首先需要引入commons-fileupload commons-fileupload commons-fileupload 1.3.3 MultipartFile方式 示例代码: @RequestM ...
- Java Web学习笔记09:文件上传与下载
文章目录 一.SmartUpload组件 1.SmartUpload概述 2.SmartUpload优点 3.SmartUpload缺点 4.环境准备
- python白帽子学习笔记(整合)
python白帽子学习笔记(整合) 学习笔记目录 python白帽子学习笔记(整合) 前言 一.基础篇 1.正则表达式 2.列表 3.元组带上了枷锁的列表 4.奇葩的内置方法 5.格式化字符 6.序列 ...
- 【白帽子学习笔记14】SQL注入常用语句
[白帽子学习笔记14]SQL注入常用语句 目前网站中使用的最多的数据库要算是 ACCESS.SQL Server(MSSQL).MySQL 这三个了,所以这里的手工注入,我就以他们三个数据库来分成三 ...
- 【白帽子学习笔记11】DVWA Brute Force【暴力破解】
[白帽子学习笔记11]DVWA Brute Force Brute Force 就是暴力破解的意思,尝试常用的用户名和必然然后使用工具一个一个的去尝试 LOW级别 通过解析源码我们可以发现代码没有任何 ...
- [网络安全学习篇60]:文件上传
引言:我的系列博客[网络安全学习篇]上线了,小编也是初次创作博客,经验不足:对千峰网络信息安全开源的视频公开课程的学习整理的笔记整理的也比较粗糙,其实看到目录有300多集的时候,讲道理,有点怂了,所以 ...
最新文章
- 汇编语言中带点/小数点的是什么
- ORA-25155: NATURAL 联接中使用的列不能有限定词
- SQL Server R2 地图报表制作(四)
- Redux中的重要概念
- 使用Zookeeper实现leader选举-Leader Latch
- 新型数据中心需要什么样的存储
- caffe boost cuda __float128 undefined
- Java was started but returned exit code=13 问题解决
- junit 生成html报告,gradle – 如何为JUnit 5测试创建HTML报告?
- JAVA高端编程研发培训班 JAVA开发视频教程
- 已知三点求这三点构成三角形的外接圆圆心坐标
- adb安装apk文件时的常见的错误及解决方法
- Navicat15下载安装
- 友善串口工具 电子秤_Serial Port Utility
- 【车间调度】FJSP的属性模型符号约定和约束条件
- 量子前沿英雄谱|既研究陶艺,也研究光量子:Hideo Mabuchi
- 【华为云技术分享】物联网常用开发板
- 万变不离其宗之ZYNQ资源
- quartz的使用(一)
- 深入讨论DECLARE_HANDLE(HINSTANCE)