web上存漏洞及道理解析、防备办法(文件类型检测漏洞)

    添加时间:2013-6-4 点击量:

    经由过程上一篇文章,我们知道wed上存漏洞,最常见一种是文件名检测漏洞,接下来,我们看看别的一种漏洞,上存文件类型漏洞,这也是一种较为轻易呈现题目。


    我当时就想,既然我知道我须要容许上存什么样的文件,那么,我就只容许你上存该文件。只要我文件类型断定正确了,你想上存可以或许履行的代码。我都给阻拦掉,不就行了吗? 这确切,是个好的办法,然则我们再做的时辰,往往会呈现下面一些题目。


    这里我们看下常见实现的php代码。 这里,常见两个题目是:




    1.读取文件type,直接做文件类型断定


    2.经由过程对象解析文件格局,以此来确认文件类型






    • 题目一:读取文件type,断定文件类型





     

    if(isset(¥_FILES[img]))
    
    {
    ¥file = save_file(¥_FILES[img]);
    if(¥file===false) exit(上存失败!);

    echo 上存成功!,¥file;
    }



    function check_file(¥img)
    {
    ///读取文件
    if(¥img[error]>0) return false;

    ¥type = ¥img[type];
    ¥filename = ¥img[name];


    ///读取文件扩大名
    ¥len=strrpos(¥filename,.);
    if(¥len===false) return false;

    //获得扩大名
    ¥ext = strtolower(substr(¥filename,¥len+1));

    ///断定文件类型
    if(¥type && preg_match(%^image/.+¥%,¥type)) return ¥ext;

    return false;
    }

    function save_file(¥img)
    {
    ¥ext = check_file(¥img);
    if(!ext) return false;

    //格局检测ok,筹办移动数据
    ¥filename = time().¥ext;
    ¥newfile = upload/ .¥filename;
    if(!move_uploaded_file(¥img[tmp_name],¥newfile)) return false;

    return ¥newfile;

    }


     


    以上加蓝色代码,是关键,这个里面我们直接读取type类型,也就是文件内容。经由过程第一篇常识:web上存漏洞及道理解析、防备办法 我们知道,type来自浏览器端浏览器主动传入变量。 若是是浏览器,这个值一般没有题目。然则,若是是来自用户本身组织的包,他可以给type 设置个:image/jpeg值, 然后,给name 一个 index.php 值。


    估计大师已经看到题目,如许一来,我们生成的文件¥filename变成为:time().’php’了。 就创建一个php文件。




    • 经由过程对象解析文件格局,以此来确认文件类型




     


    我们已经清楚知道了,type值是可以随便机关的,这类搜检用户类型办法。是没有任何感化,恶意用户,可以随便给一个php文件发奉上来,传一个image类型。 那么,必然有伴侣会说,我直接用php法度,去解析用户传入的tmp_name 文件格局,这个总靠谱吧! 我们看看下面代码。



    function check_file(¥img)
    
    {
    ///读取文件
    if(¥img[error]>0) return false;

    ¥typelist = array(array(FFD8FFE1,jpg),
    array(89504E47,png),
    array(47494638,gif),
    array(49492A00,tif),
    array(424D,bmp));

    ¥file = ¥img[tmp_name];
    ¥filename = ¥img[name];


    ///读取文件扩大名
    ¥len=strrpos(¥filename,.);
    if(¥len===false) return false;

    //获得扩大名
    ¥ext = strtolower(substr(¥filename,¥len+1));

    ///断定文件类型
    //读取文件开首15字节,一般经由过程这些字节值,可以断定它的格局
    ¥file = @fopen(¥file,rb);
    ¥bin = fread(¥file, 15);

    foreach (¥typelist as ¥v)
    {
    ¥blen=strlen(pack(H,¥v[0])); //获得文件头标识表记标帜字节数
    ¥tbin=substr(¥bin,0,intval(¥blen)); ///须要斗劲文件头长度

    if(strtolower(¥v[0])==strtolower(array_shift(unpack(H,¥tbin))))
    {
    return ¥ext;
    }
    }

    return false;
    }


    该办法,直接解析用户传入文件格局,然后决意该文件类型,是否容许保存!这套,我们看来很是靠得住办法,应当很正确,应当没有题目,不读取type,本身来解析格局。 其实:若是用户传入一个文件,前面4字节是:89504E47, 然后,后面参加一段<?php代码 。上存的文件名称是image.php 。如许一来,我们发明,这段代码保存为php文件了。 只是这个文件,前面一项目组可能是格局,后面一项目组,只纯粹的php 法度。 经由过程浏览器,去接见下这个,还真的可以运行呢。 好久以前,就有人做过image木马。可以去百度搜刮:”将php木马隐蔽在里” ,如许做出的文件,你用画图软件看是个,你若是用php运行这段代码,里面php可以或许履行了。



    好了,我们总结下,看来经由过程type断定类型,以及经由过程文件格局检测类型。 都不克不及很好解决,正确断定用户上存文件格局了。 其实,我们反过来想想,文件格局,不是经由过程一个简单字节标识码就可以或许正确断定的。 若是真的要去检测文件类型,我们该用什么办法呢?若是真的要检测格局,例如是,可以用php gd库,直接去打开文件,然后再保存一次。 如许,里面不合法的代去掉的。然则,我们想想,如许该会花费多大的机能呢?


    综上所述,其实,去断定文件内容格局,不是明智的办法。 会很是错杂,并且也轻易呈现题目。想正确断定,还会消费多量的办事器资料。除非万不得已,我们不要去测验测验做这种操纵。 接下来,对于安然上存办法,我会说说思路,迎接交换!



    作者:chengmo  QQ:8292669 
    原文网址:http://blog.chacuo.net/141.html 
    订阅对峙存眷:http://blog.chacuo.net/feed 
    本文版权归作者所有,迎接转载,请务必添加原文链接。



    所有随风而逝的都属于昨天的,所有历经风雨留下来的才是面向未来的。—— 玛格丽特·米切尔 《飘》
    分享到: