• php之文件类型解析漏洞防御与攻击


    php在处理文件上传时,经常可以用到下面几种方式来判断文件的类型

    1.通过文件名后缀,不安全,非常容易欺骗
    2.通过mime判断,部分类型的文件通过修改文件后缀名,也可以欺骗服务器
    3.通过头字节判断文件类型,但是判断范围有限,比如docx/xlsx等新的文档,通过头信息判断时,其实是一个zip包

    PHP通过读取文件头部两个字节判断文件真实类型及其应用示例

    function checkFileType($fileName){

            $file     = fopen($fileName, "rb");
            $bin      = fread($file, 2); //只读2字节
            fclose($file);
            $strInfo = @unpack("C2chars", $bin);// C为无符号整数,网上搜到的都是c,为有符号整数,这样会产生负数判断不正常
            $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
            $fileType = '';

            if($typeCode == 255216 /*jpg*/ || $typeCode == 7173 /*gif*/ || $typeCode == 13780 /*png*/) {
                return true;
            }else{
                return false;
            }

    }

       function file_type($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 7790:
                 $fileType = 'exe';
                 break;
             case 7784:
                 $fileType = 'midi';
                 break;
             case 8297:
                 $fileType = 'rar';
                 break;
             case 255216:
                 $fileType = 'jpg';
                 break;
             case 7173:
                 $fileType = 'gif';
                 break;
             case 6677:
                 $fileType = 'bmp';
                 break;
             case 13780:
                 $fileType = 'png';
                 break;
             default:
                 $fileType = 'unknown';
         }
         return $fileType;
    }

    示例,判断真实类型的php上传类:

    /**
    * 读取文件头部判断文件准确类型
    */
    class UpLoader{

        private $path;
        private $files;
        private $checkFunction;

        /**
         * @param $allow_type 接受参数为过滤类型,目前有"images"和"zip"两种,可以扩展
         */
         function UpLoader($allow_type){

                $this->path = getenv('SINASRV_CACHE_DIR').'zhuanqu_files/';

                switch($allow_type){
                    case 'image':
                        $this->checkFunction = 'checkIfImage';
                    break;
                    case 'zip':
                        $this->checkFunction = 'checkIfZip';
                    break;
                }

         }

        /**
         * 执行上传
         * @param $files 参数为$_FILES数组
         */
         public function doUpload($files){

                $this->files = $files;
                $func = $this->checkFunction;

                 if($this->files['files']['name'] != '' && $this->files['files']['error'] == UPLOAD_ERR_OK) {

                    $tmp_name = $this->files["files"]["tmp_name"];

                    //检查文件类型
                    if( $this->$func($tmp_name) ){
                        $name = md5_file($tmp_name);
                        $name = $name.'___'.$this->files["files"]["name"];
                        if(move_uploaded_file($tmp_name, $this->path.$name)){
                            //echo ' "上传成功!" ';
                        }
                    }
                 }
         }

         private function checkIfImage($fileName){

            $file     = fopen($fileName, "rb");
            $bin      = fread($file, 2); //只读2字节
            fclose($file);
            $strInfo = @unpack("C2chars", $bin);
            $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
            $fileType = '';

            if($typeCode == 255216 /*jpg*/ || $typeCode == 7173 /*gif*/ || $typeCode == 13780 /*png*/) {
                return true;
            }else{
               // echo '"仅允许上传jpg/gif/png格式的图片!';
                return false;
            }
         }

         private function checkIfZip($fileName){

            $file     = fopen($fileName, "rb");
            $bin      = fread($file, 2); //只读2字节
            fclose($file);
            $strInfo = @unpack("C2chars", $bin);
            $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
            $fileType = '';

            if($typeCode == 8075) {
                return true;
            }else{
                //echo '"仅允许上传zip格式的文件!"';
                return false;
            }
        }

    }

    图片木马欺骗服务器案例

    利用解析漏洞

    一、IIS 5.x/6.0解析漏洞
    IIS 6.0解析利用方法有两种
    1.目录解析
    /xx.asp/xx.jpg

    2.文件解析
    wooyun.asp;.jpg

    第一种,在网站下建立文件夹的名字为 .asp、.asa 的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。
     
    例如创建目录 wooyun.asp,那么
    /wooyun.asp/1.jpg

    将被当作asp文件来执行。假设黑阔可以控制上传文件夹路径,就可以不管你上传后你的图片改不改名都能拿shell了。
    第二种,在IIS6.0下,分号后面的不被解析,也就是说
    wooyun.asp;.jpg

    会被服务器看成是wooyun.asp还有IIS6.0 默认的可执行文件除了asp还包含这三种
    /wooyun.asa
    /wooyun.cer
    /wooyun.cdx

    二、IIS 7.0/IIS 7.5/ Nginx <8.03畸形解析漏洞
    Nginx解析漏洞这个伟大的漏洞是我国安全组织80sec发现的…
    在默认Fast-CGI开启状况下,黑阔上传一个名字为wooyun.jpg,内容为
    <?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>

    的文件,然后访问wooyun.jpg/.php,在这个目录下就会生成一句话木马 shell.php
     
    三、Nginx <8.03 空字节代码执行漏洞
    影响版:0.5.,0.6., 0.7 <= 0.7.65, 0.8 <= 0.8.37
    Nginx在图片中嵌入PHP代码然后通过访问
    xxx.jpg%00.php

    来执行其中的代码
     
    四、Apache解析漏洞
    Apache 是从右到左开始判断解析,如果为不可识别解析,就再往左判断.
    比如 wooyun.php.owf.rar “.owf”和”.rar” 这两种后缀是apache不可识别解析,apache就会把wooyun.php.owf.rar解析成php.
    如何判断是不是合法的后缀就是这个漏洞的利用关键,测试时可以尝试上传一个wooyun.php.rara.jpg.png…(把你知道的常见后缀都写上…)去测试是否是合法后缀
     
    五、其他
    在windows环境下,xx.jpg[空格] 或xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点,黑客可以通过抓包,在文件名后加一个空格或者点绕过黑名单.若上传成功,空格和点都会被windows自动消除,这样也可以getshell。
    如果在Apache中.htaccess可被执行.且可被上传.那可以尝试在.htaccess中写入:
    <FilesMatch "wooyun.jpg"> SetHandler application/x-httpd-php </FilesMatch>

    然后再上传shell.jpg的木马, 这样shell.jpg就可解析为php文件

  • 相关阅读:
    zookeeper 简介
    缓存雪崩 缓存穿透
    SpringCloud实战2-Ribbon客户端负载均衡
    SpringCloud实战1-Eureka
    JVM笔记9-Class类文件结构
    JVM笔记8-虚拟机性能监控与故障处理工具
    JVM笔记7-内存分配与回收策略
    SpringAOP-JDK 动态代理和 CGLIB 代理
    MySQL多数据源笔记5-ShardingJDBC实战
    MySQL多数据源笔记4-Mycat中间件实战
  • 原文地址:https://www.cnblogs.com/milantgh/p/4085158.html
Copyright © 2020-2023  润新知