| 
 pass2分析代码: 
 $_FILES['upload_file']['type'] == 'image/jpeg'用来获取文件的 MIME 类型,需要浏览器提供该信息的支持,例如"image/gif"。因此此题属于MIME绕过。
 解决: 更改mime 
 上传成功 
 
 
 pass3分析代码 
 $deny_ext = array('.asp','.aspx','.php','.jsp');定义了部分后缀黑名单。
 trim用来删除左右空格
 
 strrchr("xxax","a")搜索a的位置,并从a位置开始显示
 一系列函数是为了规避一些常见绕过黑名单的的方式,在此涉及到特殊解析后缀来绕过实现后门文件上传 例如phtml、php3、php4… 解决 上传后缀为phtml文件 
 成功 
 这里可能会碰到上传成功,但访问后门文件时无法解析的情况。这里需要找到对应的apache的httpd.conf,修改其中代码。记得修改后重启apache。 将原本的注释去掉,并添加新的解析格式。(题目在这里是提供一种思路,而非实战上这种做法的可行性) 
 
 
 pass4$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);//去除字符串::$DATA
        $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 在此参考了资料:https://blog.csdn.net/wn314/article/details/77074477 仅需在上传的.htaccess中写上AddType application/x-httpd-php xxx 或   <FilesMatch "xxx.xxx">
    SetHandler application/x-httpd-php
  </FilesMatch>
  #将某文件以php来解析
 解决: 
 上传.htaccess文件后,上传相应名字的文件。注意后缀需要是可绕过黑名单的格式。  
 
 
 pass5代码分析 $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 . '文件夹不存在,请手工创建!';
    }
}
 与前一题对比,在黑名单下多了.htaccess,在验证上却少了如下代码 $file_ext = strtolower($file_ext); 
 所以,就可通过大小写来绕过。黑名单上仍有pHp这一后缀,因此可用其他大小写组合后缀,如phP。 解决更改后缀为phP
 
  成功
 
  
 
 less6$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 . '文件夹不存在,请手工创建!';
    }
}
 代码分析少了最后一处的
 $file_ext = trim($file_ext); //首尾去空
 
 解决:
 直接数据包.php后加上一个空格。后面几关基本都是围绕这类过滤格式这个来展开的。
 
  
  
 
 
 
 less7缺少删除.语句。而在window下,无论文件最后加不加点,都默认删除。
 
 
 
 less8代码分析缺少
 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA在window的时候如果文件名+"::
    
     
      
       
        D
       
       
        A
       
       
        T
       
       
        A
       
       
        "
       
       
        会
       
       
        把
       
       
        :
       
       
        :
       
      
      
       DATA"会把::
      
     
    DATA"会把::DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,其目的就是不检查后缀名
 解决
  这里需要把后缀::$DATA删除后才能访问。
 
  
 
 less9先放答案:点+空格+点绕过。代码分析
 $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); 
 光看代码,其实最初是觉得.php..也是可以的。但结果意外的不行。思索了后觉得可能对deldot这个函数有些疑惑。后来查阅资料并经高人指点,知道了deldot这个函数并非官方定义,而是环境里自己编写的代码。 <?php
function deldot($s){
	for($i = strlen($s)-1;$i>0;$i--){
		$c = substr($s,$i,1);
		if($i == strlen($s)-1 and $c != '.'){
			return $s;
		}
		if($c != '.'){
			return substr($s,0,$i+1);
		}
	}
}
?>
 函数是直接会将最后的…一并删除的。因此需要用空格来绕过它。所以只需要改成
 .php. .即可。
 
 
 
 less10代码解析 $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);
 关键函数:
  需要注意的是这个函数是会进行循环替换的,假如后缀为.phpphp,最后上传成功后图片地址会是xxx.,并不会以php为后缀并解析。因此需要在这里用
 .pphphp来绕过。我用笨脑袋瓜想了下应该是没有其他写法了。 
 解决
  
 
 
 
 less11代碼分析 $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类型文件!";
    }
}
 首先是個白名單绕过。根据题目提示,本pass上传路径可控。代码中img_path是通过get来发送,因此可以考虑%00截断。%00在ascll中表示的是0作为特殊字符,意为字符结束,因此url会在此处被截断。
 解决:save_path中添加xx.php后加上%00。
 
  访问时要将截断后的内容删除再访问。
 
  
  
 
 
 
 less12代码分析 $temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
 其余应该是跟上题一致。但在path路径上是通过post来传递。这里需要知道,GET方式是会对URL进行解码,%00解码后会得到一个空。而POST不会对URL解码,因此需要对%00进行一次解码。 解决:hex中将.php后面那个+更改为00
 
  或者在数据包中将路径后添%00,之后再进行编码。
 
  截断成功
  
 
 
 
 less13代码分析fread()函数读取文件,本题通过读取文件头来判断文件类型。
 解决就可以在命令行里执行语句来制作图片马
 copy 1.jpg /b + 2.php /a webshell.jpg
 或者直接用记事本或notepad在最后加php语句也可以实现。光上传的话就已经完成了,但要想让实现木马的启用就还需要配合其他漏洞来实现。 
 
 less14代码分析
 getimagesize()函数:用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。解决方式跟上一关一样。
 
 
 
 less15代码分析
 exif_imagetype()函数: 读取一个图像的第一个字节并检查其签名,如果发现了恰当的签名则返回一个对应的常量,否则返回 false。返回值和getimagesize()返回的数组中的索引 2 的值是一样的,但本函数快得多。 
 
 less16updating… |