漏洞重温之文件上传(中)

漏洞重温之文件上传


Pass-11

进入第十一关,首先我们先查看源码。

从代码中,我们可以看到。

if (isset($_POST['submit']))

这行代码是在验证我们上传是否为空

$ext_arr = array('jpg','png','gif')

这行代码告诉我们,网页建立了一个数组,从里面的内容可以猜测,这可能是网站设置的白名单数组。

$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1)

这行代码提取了我们上传的文件名中的后缀,并且将其存储到了$file_ext这个变量中。

if (in_array($file_ext,$ext_arr)){
	$temp_file = $_FILES['upload_file']['temp_name'];
	$img_path = $_GET['save_path']."/".rand(10,99).data("YmdHis").".".$file_ext;
	
	if(move_uploaded_file($temp_file,$img_path)){
		$is_upload = true;
	} else{
		$msg = '上传出错!';
	}else {
		$msg = "只允许上传.jpg|.png.gif类型文件!";
	}
}

这行代码则是做了一个判断,如果我们上传文件的后缀在白名单数组里面,那么我们的文件可以被上传,并且会被重命名,如果不是,则返回只允许上传只允许上传.jpg|.png.gif类型文件!这条提示。

但是$img_path 是直接拼接,因此可以利用%00截断绕过。

PS:截断条件:php版本小于5.3.4,php的magic_quotes_gpc为off状态。

因为%00截断绕过,我们所利用的并非正常的上传方式,所以在这里我们并不需要通过返回包知道路径,所以在上传之后,可以直接访问。

第十一关,通关。

Pass-12

进入十二关,直接查看源码,可以发现,源码内容基本和第十一关一致。

但是注意下面这行代码。

$img_path = $_POST['save_path']."/".rand(10,99).data("YmdHis").".".$file_ext;

这条代码是十二关和十一关不同的地方,一个是get请求,一个是post请求。

因为代码一致,所以绕过方式我们依然选择%00截断,只是post请求不像get请求会将%00进行自动解码,所以我们需要在二进制中进行修改。

在修改成功之后,就可以上传,并且直接访问了。

第十二关,通关。

Pass-13

第十三关源码很长,就不截图了,源码如下。

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

这一关需要上传图片马,从开头的注释可以发现,代码只提取了文件名的前两个字节,所以我们根本不需要做任何操作,只需要将我们制作好的图片马上传到服务器即可。

这里,为了验证我们图片马是否成功,还需要写一个文件包含漏洞文件。

漏洞文件代码如下。

<?php
include "上传文件名"
?>

因为网站在我们图片上传完成之后会对我们的文件进行重命名,所以我们需要抓取返回包,记录文件名称,以此来验证我们上传的图片马是否可以使用。

第十三关,通关。

Pass-14

第十四关,源码如下。

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

这个源码我们可以看出,他的判断是利用getimagesize函数来进行的,该函数判断了文件类型,但是因为我们上传的图片马从本质上是图片和代码的结合,并且格式依然是图片格式,所以此处过滤对我们的图片马并无影响,可直接上传,方法跟第十三关一致。

第十四关,通关。

Pass-15

第十五关代码如下。

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

该代码和十四关几乎一致,只是使用了php_exif模块来判断文件类型,所以这关的限制条件依然是文件类型,图片马本质为图片,所以依然可以使用直接使用图片马来绕过。

第十五关,通关。

posted @ 2020-08-11 20:43  小明-o3rr0r  阅读(263)  评论(0编辑  收藏  举报