文件上传绕过——后端检测_文件头检测漏洞

Posted 剑客 getshell

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传绕过——后端检测_文件头检测漏洞相关的知识,希望对你有一定的参考价值。

一、实验目的:

1、通过本次实验掌握文件头检测的原理。
2、通过fileupload_test靶场,掌握文件头检测绕过技术。

二、工具:

C32Asm(以16进制的方式打开文件)
火狐/谷歌浏览器

三、实验环境:

靶 机: windows10虚拟机:192.168.100.150
      fileupload_test靶场
      phpstudy2018搭建网站

攻击机: 物理机
点击下载fileupload_test靶场 提取码:poz7

–来自百度网盘超级会员V5的分享

四、环境准备:

下载上面的靶场后,解压到网站主目录:

五、什么是文件头:

  我们都知道,文件的扩展名是用来识别文件类型的。通过给他指定扩展名,我们可以告诉自己,也告诉操作系统我们想用什么方式打开这个文件。比如我么会把.jpg的文件默认用图片显示软件打开,.zip 文件会默认用解压软件打开等等。
  然而,扩展名完全是可以随便改改的。我们可以给文件设置一个任意的扩展名,当然也可以不设置扩展名。这样一来我们就不能了解到这个文件究竟是做什么的,究竟是个什么样的文件。我们或许也会疑惑,为什么一个软件,比如视频播放器,就能用正确的方式打开.mp4 .rmvb .wmv 等等的视频?
  事实上,所有的文件都是以二进制的形式进行存储的,本质上没有差别。之所以使用的方法不同,只是因为我们理解他的方式不同。在每一个文件(包括图片,视频或其他的非ASCII文件)的开头(十六进制表示)实际上都有一片区域来显示这个文件的实际用法,这就是文件头标志。
  文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些签名信息。如用uestudio工具以十六进制方式查看zip格式的文件,其文件内容头部有50 4B 03 04这样的十六进制信息。同理jpg文件状况有FF D8 FF E0 xx xx 4A 46这样的十六进制信息,其实这此十六进制都是表示一些特殊字条。
  Linux下我们可以用file命令直接查看文件的实际格式,但是他本质上也是利用文件头标志来进行文件类型判断的。下面就简要介绍下手动判断文件真实类型的方法。

六、常见的文件头:

注意:下面的文件头的格式是16进制的格式:

GIF:47 49 46 38 39 61
png:89 50 4E 47 0D 0A 1A 0A
JPG:FF D8 FF E0 00 10 4A 46 49 46

在进行文件头绕过时,我们可以把上面的文件头添加到我们的一句话木马内容最前面,达到绕过文件头检测的目的。

七、实验过程:

1. 给webshell添加文件头:

下面我们使用1.php文件做实验,文件是一个phpinfo文件,我们把文件头添加到这个1.php中:

注:因为文件头是16进制的文件格式,我们需要使用C32Asm这个工具以16进制的格式打开这个文件。
点击下载C32Asm_16进制文件编辑器 提取码:b6zr

下面我们点击打开C32Asm这个工具,并使用这个工具打开上面的1.php文件:

打开效果如下:

下面我们给1.php文件添加文件头的效果:
GIF:

png:

2. uploadwenjiantou实验靶场

实验源码:

<?php
header("Content-type: text/html; charset=utf-8");

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/".$_FILES['upload_file']['name'];
        echo "$img_path";
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}
?>

1、通过上面方式添加文件头后,我们把1.php上传到靶场里面,发现可以上传成功:



2、复制图片链接后,访问可以解析文件:

3. uploadgetimagesize实验靶场

实验源码:

<?php
header("Content-type: text/html; charset=utf-8");
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/".$_FILES['upload_file']['name'];
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}
?>

1、通过上面方式添加文件头后,我们把1.php上传到靶场里面,发现可以上传成功:

2、复制图片链接后,访问可以解析文件:

以上是关于文件上传绕过——后端检测_文件头检测漏洞的主要内容,如果未能解决你的问题,请参考以下文章

文件上传漏洞及绕过检测的方式

文件上传漏洞代码

上传漏洞

文件上传漏洞绕过手段

目录路径检测解析绕过上传漏洞 啥意思

Web安全之文件上传漏洞