热搜词
发表于 2021-11-28 07:52:43 | 显示全部楼层 |阅读模式
Veno-File-Manager (VFM3)云盘游客可查看所有文件漏洞解决思路

如果游客开启了“查看文件”权限,游客打开云盘时,不仅能看到主文件夹里的文件,通过在URL地址栏中手工添加“?dir=uploads/子文件夹名称”参数也可以看到子文件夹里文件。

VFM3游客可查看子文件夹内容漏洞.png

解决思路(把未登录用户设置为“guest”用户,并设置可防问的目录权限):

1.修改未登录用户访问目录权限。
打开 主目录/vfm-admin/class/class.gatekeeper.php文件中的 getUserInfo($info) 函数,添加未登录用户可访问的目录名。修改后代码如下:
  1.         /**
  2.          * Get user info ('name', 'role', 'dir', 'email')   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
  3.          *
  4.          * @param int $info index of corresponding user info
  5.          *
  6.          * @return info requested
  7.          */
  8.         public static function getUserInfo($info)
  9.         {
  10.             if (GateKeeper::isUserLoggedIn()
  11.                 && isset($_SESSION['vfm_user_name'])
  12.                 && strlen($_SESSION['vfm_user_name']) > 0
  13.             ) {
  14.                 $username = $_SESSION['vfm_user_name'];
  15.                 $curruser = Utils::getCurrentUser($username);

  16.                 if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
  17.                     return $curruser[$info];
  18.                 }
  19.             } else if(!GateKeeper::isUserLoggedIn() && SetUp::getConfig('viewdirs_enable_guest') ){        
  20.                                 if( !SetUp::getConfig('view_enable_guest')){
  21.                                          return null;}
  22.                $guestpatharray = array ('dir' => '["guest","公共目录"]',);    //游客目录
  23.                            $userpatharray = json_decode($guestpatharray['dir'], true);           
  24.                            return $guestpatharray['dir'];
  25.             }
  26.             return null;
  27.         }
复制代码
2.修改未登录用户,显示用户名为“guest”(非必须)。
查找 主目录/vfm-admin/class/class.utils.php文件中的 getUserName()函数,大约在231行,代码如下:
  1.         /**
  2.          * Return current username  返回当前用户名
  3.          *
  4.          * @return username
  5.          */
  6.         public static function getUserName()
  7.         {
  8.             return isset($_SESSION['vfm_user_name']) ? $_SESSION['vfm_user_name'] : '--';
  9.         }
复制代码
修改为:
  1.         /**
  2.          * Return current username  返回当前用户名
  3.          *
  4.          * @return username
  5.          */
  6.         public static function getUserName()
  7.         {
  8.             return isset($_SESSION['vfm_user_name']) ? $_SESSION['vfm_user_name'] : 'guest';
  9.         }
复制代码

与解决此漏洞相关文件:
主目录/vfm-admin/class/class.gatekeeper.php     //验证当前用户权限的类
主目录/vfm-admin/class/class.location.php     //与路径和目录相关的类
主目录/vfm-admin/include/head.php     //头部,重要的内容
主目录/vfm-admin/include/navbar.php     //顶部标题
主目录/vfm-admin/class/class.dir.php
主目录/vfm-admin/include/breadcrumbs.php     //路径显示
主目录/vfm-admin/include/list-folders.php   //文件夹列表
主目录/vfm-admin/include/list-files.php   //文件列表
主目录//vfm-admin/include/load-js.php


主目录/vfm-admin/admin-panel/view/admin-head.php    //加载 admin-head-settings.php文件

主目录/vfm-admin/class/class.gatekeeper.php    //与用户权限相关的类
isAllowed($action)   //检查是否允许目标操作函数-
变量$role为角色,分别为普通用户(user)、管理员(admin)角色),如果$role内容为空就设置为游客(guest)角色。
  1.         /**
  2.          * Check if target action is allowed  检查是否允许目标操作
  3.          *
  4.          * @param string $action action to check
  5.          *
  6.          * @return true/false
  7.          */
  8.         public static function isAllowed($action)
  9.         {
  10.             if ($action && GateKeeper::isAccessAllowed()) {
  11.                 $role = GateKeeper::getUserInfo('role');
  12.                 $role = $role == null ? 'guest' : $role;

  13.                 if ($role == 'superadmin') {
  14.                     return true;
  15.                 }

  16.                 $base_actions = array(
  17.                     'view_enable',
  18.                     'viewdirs_enable',
  19.                     'download_enable',
  20.                 );

  21.                 // Base actions true for all except Guest and User 基本操作适用于除来宾和用户之外的所有用户
  22.                 if (in_array($action, $base_actions) && $role !== 'guest' && $role !== 'user') {
  23.                     return true;
  24.                 }

  25.                 $role_ext = $role == 'admin' ? '' : '_'.$role;

  26.                 return SetUp::getConfig($action.$role_ext);
  27.             }
  28.             return false;
  29.         }
复制代码
$gateKeeper->isUserLoggedIn()  //检查用户是否已登录
  1. /**
  2.          * Check if user is logged in  检查用户是否已登录
  3.          *
  4.          * @return true/false
  5.          */
  6.         public static function isUserLoggedIn()
  7.         {
  8.             if (isset($_SESSION['vfm_user_name'])
  9.                 && isset($_SESSION['vfm_logged_in'])
  10.                 && $_SESSION['vfm_logged_in'] == 1
  11.             ) {
  12.                 return true;
  13.             }
  14.             return false;
  15.         }
复制代码
$gateKeeper->isSuperAdmin()   //检查用户是否为超级管理员
  1.         /**
  2.          * Check if user is SuperAdmin   检查用户是否为超级管理员
  3.          *
  4.          * @return true/false
  5.          */
  6.         public static function isSuperAdmin()
  7.         {
  8.             if (GateKeeper::getUserInfo('role') === 'superadmin') {
  9.                 return true;
  10.             }
  11.             return false;
  12.         }
复制代码
getUserInfo($info)   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
  1.         /**
  2.          * Get user info ('name', 'role', 'dir', 'email')   获取用户信息(“名称”、“角色”、“目录”、“电子邮件”)
  3.          *
  4.          * @param int $info index of corresponding user info
  5.          *
  6.          * @return info requested
  7.          */
  8.         public static function getUserInfo($info)
  9.         {
  10.             if (GateKeeper::isUserLoggedIn()
  11.                 && isset($_SESSION['vfm_user_name'])
  12.                 && strlen($_SESSION['vfm_user_name']) > 0
  13.             ) {
  14.                 $username = $_SESSION['vfm_user_name'];
  15.                 $curruser = Utils::getCurrentUser($username);

  16.                 if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
  17.                     return $curruser[$info];
  18.                 }
  19.             }
  20.             return null;
  21.         }
复制代码
isAccessAllowed()  检查用户是否可以访问
  1.         /**
  2.          * Check if user can access   检查用户是否可以访问
  3.          *
  4.          * @return true/false
  5.          */
  6.         public static function isAccessAllowed()
  7.         {
  8.             if (!GateKeeper::isLoginRequired() || GateKeeper::isUserLoggedIn()) {
  9.                 return true;
  10.             }
  11.             return false;
  12.         }
复制代码
isLoginRequired()  检查是否开启游客“您需要登录才可以查看”
  1.         /**
  2.          * Check if login is required to view lists  检查查看列表是否需要登录
  3.          *
  4.          * @return true/false
  5.          */
  6.         public static function isLoginRequired()
  7.         {
  8.             if (SetUp::getConfig('require_login') == false) {
  9.                 return false;
  10.             }
  11.             return true;
  12.         }
复制代码

主目录/vfm-admin/class/class.location.php   //用户目录和文件路径
checkUserDir()       //检查目录是否可供用户使用
  1.         /**
  2.          * Check if directory is available for user   检查目录是否可供用户使用
  3.          *
  4.          * @param string $relative relative path to index.php
  5.          *
  6.          * @return true/false
  7.          */
  8.         public function checkUserDir($relative = false)
  9.         {
  10.             $thispath = $this->getDir(true, false, false, 0, $relative);

  11.             if (!is_dir(realpath($thispath))) {
  12.                 return false;
  13.             }

  14.             $getUserInfo = GateKeeper::getUserInfo('dir');
  15.             if ($getUserInfo === null) {
  16.                 return true;
  17.             }

  18.             $startdir = SetUp::getConfig('starting_dir');
  19.             $userpatharray = $getUserInfo !== null ? json_decode($getUserInfo, true) : array();
  20.             $thiscleanpath = ltrim($thispath, './');
  21.             $cleanstartdir = rtrim(ltrim($startdir, './'), '/');
  22.             $thispatharray = explode('/', $thiscleanpath);
  23.             $checkpath = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? $thispatharray[1] : $thispatharray[0];
  24.             $pathcounter = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? (int)2 : (int)1;

  25.             // Check for multiple folders assigned   检查是否分配了多个文件夹
  26.             foreach ($userpatharray as $value) {

  27.                 // Check if a sub/sub folder is assigned
  28.                 $userdirarray = explode('/', $value);
  29.                 $usersubs = count($userdirarray) - 1;
  30.                 if ($usersubs > 0) {
  31.                     $subscounter = $usersubs + $pathcounter;
  32.                     for ($i = $pathcounter; $i < $subscounter; $i++) {
  33.                         $checkpath .= '/'.$thispatharray[$i];
  34.                     }
  35.                 }

  36.                 // Finally check if the location is accessible by the user
  37.                 if ($value === $checkpath) {
  38.                     return true;
  39.                 }
  40.             }
  41.             return false;
  42.         }
复制代码
makeLink()      创建注销、删除和打开目录的链接(用户登录?logout)
  1. /**
  2.    * Create links to logout, delete and open directory  创建注销、删除和打开目录的链接
  3.    *
  4.    * @param boolean $logout set logout
  5.    * @param string  $delete path to delete
  6.    * @param string  $dir    path to link
  7.    *
  8.    * @return link
  9.    */
  10.   public function makeLink($logout, $delete, $dir)
  11.   {
  12. $link = '?';

  13. if ($logout == true) {
  14.     $link .= 'logout';
  15.     return $link;
  16. }
  17. $link .= 'dir='.$dir;
  18. if ($delete != null) {
  19.     $link .= '&del='.base64_encode($delete);
  20. }
  21. return $link;
  22.   }
复制代码

主目录/vfm-admin/class/class.utils.php  //常用工具类
Utils::getCurrentUser($username)  按用户名获取用户数据
  1.         /**
  2.          * Get user data by username  按用户名获取用户数据
  3.          *
  4.          * @param int $search username to search
  5.          *
  6.          * @return user array requested
  7.          */
  8.         public static function getCurrentUser($search)
  9.         {
  10.             $currentuser = array();
  11.             $users = SetUp::getUsers();
  12.             if ($users) {
  13.                 foreach ($users as $user) {
  14.                     if (strtolower($user['name']) == strtolower($search)) {
  15.                         $currentuser = $user;
  16.                         return $currentuser;
  17.                     }
  18.                 }
  19.             }
  20.             return false;
  21.         }
复制代码
主目录/vfm-admin/class/class.setup.php  //设置类
SetUp::getUsers()  获取所有用户数据
  1.         /**
  2.          * Get all users from users.php   从users.php   获取所有用户
  3.          *
  4.          * @return users array
  5.          */
  6.         public static function getUsers()
  7.         {
  8.             global $_USERS;
  9.             if (isset($_USERS)) {
  10.                 return $_USERS;
  11.             }
  12.             return false;
  13.         }
复制代码
主目录/vfm-admin/class/class.location.php文件中的 checkUserDir()  函数
$userpatharray = $getUserInfo !== null ? json_decode($getUserInfo, true) :  array();


后台管理面板与游客设置相关的文件config.php配置文件中与游客相关函数:
'starting_dir' => './uploads/',            主目录(上传文件存放文件夹)
'require_login' => false,                      您需要登录才可以查看    => 关闭
'view_enable_guest' => true,               查看文件_开启_游客  => 开启
'download_enable_guest' => true,      打包下载_开启_游客  => 开启
'viewdirs_enable_guest' => false,        查看文件夹_开启_游客   => 关闭
'sendfiles_enable_guest' => true,       分享文件_开启_游客   => 开启

主目录/vfm-admin/admin-panel/view/admin-head-settings.php   //保存与游客用户权限相关的设置参数
    // Users permissions
    // Guest
    $_CONFIG['view_enable_guest'] = (isset($_POST['view_enable_guest']) ? true : false);
    $_CONFIG['download_enable_guest'] = (isset($_POST['download_enable_guest']) ? true : false);
    $_CONFIG['sendfiles_enable_guest'] = (isset($_POST['sendfiles_enable_guest']) ? true : false);
    $_CONFIG['viewdirs_enable_guest'] = (isset($_POST['viewdirs_enable_guest']) ? true : false);

主目录/vfm-admin/admin-panel/view/dashboard/permissions.php   //管理后台用户权限设置
定义与游客相关的变量:

$rolename = $setUp->getString("role_guest");
$rolekey = '_guest';


全部评论1
灰儿 发表于 2021-12-3 16:38:09 | 显示全部楼层
主目录/vfm-admin/admin-panel/view/dashboard/permissions.php   //管理后台用户权限设置
定义与游客相关的变量:

$rolename = $setUp->getString("role_guest");
$rolekey = '_guest';

游客权限设置源代码:
<h4><?php echo $rolename; ?></h4>
<div class="row toggle-reverse-next">
    <div class="col-sm-6">
        <div class="form-group bg-warning py-2">
            <div class="checkbox checkbox-bigger clear">
<label>
    <input type="checkbox" name="require_login"
    <?php
    if ($setUp->getConfig('require_login')) {
        echo "checked";
    } ?>>
    <i class="fa fa-lock fa-fw"></i>
    <?php print $setUp->getString("require_login"); ?>
</label>
            </div>
        </div>
    </div>
</div>
<div class="reverse-toggle-target">
    <div class="row">
        <div class="col-sm-6">
            <div class="toggle">
<div class="checkbox checkbox-big toggle">
    <label>
        <input type="checkbox" name="view_enable<?php echo $rolekey; ?>"
        <?php
        if ($setUp->getConfig('view_enable'.$rolekey)) {
            echo "checked";
        } ?>>
            <span class="fa-stack">
              <i class="fa fa-file-o fa-stack-2x"></i>
              <i class="fa fa-eye fa-stack-1x"></i>
            </span>
        <?php print $setUp->getString("view_files"); ?>
    </label>
</div>
            </div>
            <div class="toggleme">
<div class="checkbox checkbox-big toggle">
    <label>
        <input type="checkbox" name="download_enable<?php echo $rolekey; ?>"
        <?php
        if ($setUp->getConfig('download_enable'.$rolekey)) {
            echo "checked";
        } ?>>
            <span class="fa-stack">
              <i class="fa fa-file-o fa-stack-2x"></i>
              <i class="fa fa-download fa-stack-1x"></i>
            </span>
        <?php print $setUp->getString("download_files"); ?>
    </label>
</div>

<div class="checkbox checkbox-big">
    <label>
        <input type="checkbox" name="sendfiles_enable<?php echo $rolekey; ?>"
        <?php
        if ($setUp->getConfig('sendfiles_enable'.$rolekey)) {
            echo "checked";
        } ?>>
            <span class="fa-stack">
              <i class="fa fa-file-o fa-stack-2x"></i>
              <i class="fa fa-paper-plane-o fa-stack-1x"></i>
            </span>
        <?php print $setUp->getString("share_files"); ?>
    </label>
</div>
            </div>
        </div>

        <div class="col-sm-6">
            <div class="checkbox">
<label>
    <input type="checkbox" name="viewdirs_enable<?php echo $rolekey; ?>"
    <?php
    if ($setUp->getConfig('viewdirs_enable'.$rolekey)) {
        echo "checked";
    } ?>>
        <span class="fa-stack">
          <i class="fa fa-folder fa-stack-2x"></i>
          <i class="fa fa-eye fa-stack-1x fa-inverse"></i>
        </span>
    <?php print $setUp->getString("view_folders"); ?>
</label>
            </div>
        </div>
    </div>
</div>

游客权限设置转换为html内容如下:
//标题
<h4>游客</h4>
//  您需要登录才可以查看
<div class="row toggle-reverse-next">
                    <div class="col-sm-6">
                        <div class="form-group bg-warning py-2">
                            <div class="checkbox checkbox-bigger clear">
                                <label>
                                    <input type="checkbox" name="require_login">
                                    <i class="fa fa-lock fa-fw"></i>
                                    您需要登录才可以查看                                </label>
                            </div>
                        </div>
                    </div>
                </div>


//具体权限选项
<div class="reverse-toggle-target">
                    <div class="row">
                        <div class="col-sm-6">
                            <div class="toggle">
                                <div class="checkbox checkbox-big toggle">
                                    <label>
                                        <input type="checkbox" name="view_enable_guest" checked="">
                                            <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-eye fa-stack-1x"></i>
                                            </span>
                                        查看文件                                    </label>
                                </div>
                            </div>
                            <div class="toggleme">
                                <div class="checkbox checkbox-big toggle">
                                    <label>
                                        <input type="checkbox" name="download_enable_guest" checked="">
                                            <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-download fa-stack-1x"></i>
                                            </span>
                                        打包下载                                    </label>
                                </div>

                                <div class="checkbox checkbox-big">
                                    <label>
                                        <input type="checkbox" name="sendfiles_enable_guest" checked="">
                                            <span class="fa-stack">
                                              <i class="fa fa-file-o fa-stack-2x"></i>
                                              <i class="fa fa-paper-plane-o fa-stack-1x"></i>
                                            </span>
                                        分享                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="col-sm-6">
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox" name="viewdirs_enable_guest" checked="">
                                        <span class="fa-stack">
                                          <i class="fa fa-folder fa-stack-2x"></i>
                                          <i class="fa fa-eye fa-stack-1x fa-inverse"></i>
                                        </span>
                                    查看文件夹                                </label>
                            </div>
                        </div>
                    </div>
                </div>
回复

使用道具 举报

回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|管理员之家 ( 苏ICP备2023053177号-2 )

GMT+8, 2024-12-27 20:01 , Processed in 0.166176 second(s), 25 queries .

Powered by Discuz! X3.5

Cpoyright © 2001-2024 Discuz! Team