• Resolved ImageJVM Design

    (@jvmd)


    This came up on a scan today: /plugins/modern-events-calendar-lite/app/libraries/filessystem.php Below is the full code of that file. Thank you

    <?php
    /** no direct access **/
    defined('MECEXEC') or die();

    /**
    * Webnus MEC File class.
    * @author Webnus <info@webnus.net>
    */
    class MEC_file extends MEC_base
    {
    /**
    * Constructor method
    * @author Webnus <info@webnus.net>
    */
    public function __construct()
    {
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return string
    */
    public static function getExt($file)
    {
    $ex = explode('.', $file);
    return end($ex);
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return string
    */
    public static function stripExt($file)
    {
    return preg_replace('#\.[^.]*$#', '', $file);
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return string
    */
    public static function makeSafe($file)
    {
    $regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');
    return preg_replace($regex, '', $file);
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $src
    * @param string $dest
    * @param string $path
    * @return boolean
    */
    public static function copy($src, $dest, $path = null)
    {
    // Prepend a base path if it exists
    if ($path)
    {
    $src = MEC_path::clean($path . '/' . $src);
    $dest = MEC_path::clean($path . '/' . $dest);
    }

    // Check src path
    if (!is_readable($src))
    {
    return false;
    }

    if (!@ copy($src, $dest))
    {
    return false;
    }

    return true;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return boolean
    */
    public static function delete($file)
    {
    if(is_array($file))
    {
    $files = $file;
    }
    else
    {
    $files[] = $file;
    }

    foreach($files as $file)
    {
    $file = MEC_path::clean($file);

    @chmod($file, 0777);
    @unlink($file);
    }

    return true;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $src
    * @param string $dest
    * @param string $path
    * @return boolean
    */
    public static function move($src, $dest, $path = '')
    {
    if($path)
    {
    $src = MEC_path::clean($path . '/' . $src);
    $dest = MEC_path::clean($path . '/' . $dest);
    }

    // Check src path
    if(!is_readable($src)) return false;
    if(!@rename($src, $dest)) return false;

    return true;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $filename
    * @return boolean
    */
    public static function read($filename)
    {
    // Initialise variables.
    $fh = fopen($filename, 'rb');

    if(false === $fh) return false;

    clearstatcache();

    if($fsize = @filesize($filename))
    {
    $data = fread($fh, $fsize);

    fclose($fh);
    return $data;
    }
    else
    {
    fclose($fh);
    return false;
    }
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @param string $buffer
    * @return string
    */
    public static function write($file, &$buffer)
    {
    @set_time_limit(ini_get('max_execution_time'));

    // If the destination directory doesn't exist we need to create it
    if (!file_exists(dirname($file)))
    {
    MEC_folder::create(dirname($file));
    }

    $file = MEC_path::clean($file);
    $ret = is_int(file_put_contents($file, $buffer)) ? true : false;

    return $ret;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $src
    * @param string $dest
    * @return boolean
    */
    public static function upload($src, $dest)
    {
    // Ensure that the path is valid and clean
    $dest = MEC_path::clean($dest);
    $baseDir = dirname($dest);

    if (!file_exists($baseDir))
    {
    MEC_folder::create($baseDir);
    }

    if (is_writable($baseDir) && move_uploaded_file($src, $dest))
    {
    // Short circuit to prevent file permission errors
    if (MEC_path::setPermissions($dest)) $ret = true;
    else $ret = false;
    }
    else $ret = false;

    return $ret;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return string
    */
    public static function exists($file)
    {
    return is_file(MEC_path::clean($file));
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $file
    * @return string
    */
    public static function getName($file)
    {
    // Convert backslashes to forward slashes
    $file = str_replace('\\', '/', $file);
    $slash = strrpos($file, '/');

    if ($slash !== false)
    {
    return substr($file, $slash + 1);
    }
    else
    {
    return $file;
    }
    }
    }

    /**
    * Webnus MEC Folder class.
    * @author Webnus <info@webnus.net>
    */
    class MEC_folder extends MEC_base
    {
    /**
    * Constructor method
    * @author Webnus <info@webnus.net>
    */
    public function __construct()
    {
    parent::__construct();
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $src
    * @param string $dest
    * @param string $path
    * @param boolean $force
    * @return boolean
    */
    public static function copy($src, $dest, $path = '', $force = false)
    {
    @set_time_limit(ini_get('max_execution_time'));

    if ($path)
    {
    $src = MEC_path::clean($path . '/' . $src);
    $dest = MEC_path::clean($path . '/' . $dest);
    }

    // Eliminate trailing directory separators, if any
    $src = rtrim($src, DIRECTORY_SEPARATOR);
    $dest = rtrim($dest, DIRECTORY_SEPARATOR);

    if (!self::exists($src)) return false;
    if (self::exists($dest) && !$force) return false;

    // Make sure the destination exists
    if (!self::create($dest)) return false;
    if (!($dh = @opendir($src))) return false;

    // Walk through the directory copying files and recursing into folders.
    while (($file = readdir($dh)) !== false)
    {
    $sfid = $src . '/' . $file;
    $dfid = $dest . '/' . $file;

    switch (filetype($sfid))
    {
    case 'dir':

    if ($file != '.' && $file != '..')
    {
    $ret = self::copy($sfid, $dfid, null, $force);
    if ($ret !== true)
    {
    return $ret;
    }
    }
    break;

    case 'file':

    if (!@copy($sfid, $dfid))
    {
    return false;
    }
    break;
    }
    }

    return true;
    }

    /**
    * Create a folder -- and all necessary parent folders.
    * @author Webnus <info@webnus.net>
    * @staticvar int $nested
    * @param string $path
    * @param int $mode
    * @return boolean
    */
    public static function create($path = '', $mode = 0755)
    {
    // Initialise variables.
    static $nested = 0;

    // Check to make sure the path valid and clean
    $path = MEC_path::clean($path);

    // Check if parent dir exists
    $parent = dirname($path);

    if (!self::exists($parent))
    {
    // Prevent infinite loops!
    $nested++;
    if (($nested > 20) || ($parent == $path))
    {
    $nested--;
    return false;
    }

    // Create the parent directory
    if (self::create($parent, $mode) !== true)
    {
    // MEC_folder::create throws an error
    $nested--;
    return false;
    }

    // OK, parent directory has been created
    $nested--;
    }

    // Check if dir already exists
    if (self::exists($path))
    {
    return true;
    }

    // We need to get and explode the open_basedir paths
    $obd = ini_get('open_basedir');

    // If open_basedir is set we need to get the open_basedir that the path is in
    if ($obd != null)
    {
    $obdSeparator = ":";

    // Create the array of open_basedir paths
    $obdArray = explode($obdSeparator, $obd);
    $inBaseDir = false;
    // Iterate through open_basedir paths looking for a match
    foreach ($obdArray as $test)
    {
    $test = MEC_path::clean($test);
    if (strpos($path, $test) === 0)
    {
    $inBaseDir = true;
    break;
    }
    }
    if ($inBaseDir == false)
    {
    return false;
    }
    }

    // First set umask
    $origmask = @umask(0);

    // Create the path
    if (!$ret = @mkdir($path, $mode))
    {
    @umask($origmask);
    return false;
    }

    // Reset umask
    @umask($origmask);

    return $ret;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @return boolean
    */
    public static function delete($path)
    {
    @set_time_limit(ini_get('max_execution_time'));

    // Sanity check
    if (!$path)
    {
    return false;
    }

    // Check to make sure the path valid and clean
    $path = MEC_path::clean($path);

    // Is this really a folder?
    if (!is_dir($path))
    {
    return false;
    }

    // Remove all the files in folder if they exist; disable all filtering
    $files = self::files($path, '.', false, true, array(), array());
    if (!empty($files))
    {
    if (MEC_file::delete($files) !== true)
    {
    return false;
    }
    }

    // Remove sub-folders of folder; disable all filtering
    $folders = self::folders($path, '.', false, true, array(), array());
    foreach ($folders as $folder)
    {
    if (is_link($folder))
    {
    if (MEC_file::delete($folder) !== true)
    {
    return false;
    }
    }
    elseif (self::delete($folder) !== true)
    {
    return false;
    }
    }

    // In case of restricted permissions we zap it one way or the other
    // as long as the owner is either the webserver or the ftp.
    if (@rmdir($path))
    {
    $ret = true;
    }
    else
    {
    $ret = false;
    }

    return $ret;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $src
    * @param string $dest
    * @param string $path
    * @return boolean
    */
    public static function move($src, $dest, $path = '')
    {
    if ($path)
    {
    $src = MEC_path::clean($path . '/' . $src);
    $dest = MEC_path::clean($path . '/' . $dest);
    }

    if (!self::exists($src)) return false;
    if (self::exists($dest)) return false;

    if (!@rename($src, $dest))
    {
    return false;
    }

    return true;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @return string
    */
    public static function exists($path)
    {
    return is_dir(MEC_path::clean($path));
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $filter
    * @param boolean $recurse
    * @param boolean $full
    * @param array $exclude
    * @param array $excludefilter
    * @return boolean|array
    */
    public static function files($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\..*', '.*~'))
    {
    // Check to make sure the path valid and clean
    $path = MEC_path::clean($path);

    // Is the path a folder?
    if (!is_dir($path))
    {
    return false;
    }

    // Compute the excludefilter string
    if (count($excludefilter))
    {
    $excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
    }
    else
    {
    $excludefilter_string = '';
    }

    // Get the files
    $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true);

    // Sort the files
    asort($arr);
    return array_values($arr);
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $filter
    * @param boolean $recurse
    * @param boolean $full
    * @param array $exclude
    * @param array $excludefilter
    * @return boolean|array
    */
    public static function folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\..*'))
    {
    // Check to make sure the path valid and clean
    $path = MEC_path::clean($path);

    // Is the path a folder?
    if (!is_dir($path))
    {
    return false;
    }

    // Compute the excludefilter string
    if (count($excludefilter))
    {
    $excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
    }
    else
    {
    $excludefilter_string = '';
    }

    // Get the folders
    $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false);

    // Sort the folders
    asort($arr);
    return array_values($arr);
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $filter
    * @param boolean $recurse
    * @param boolean $full
    * @param array $exclude
    * @param array|string $excludefilter_string
    * @param boolean $findfiles
    * @return array
    */
    protected static function _items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles)
    {
    @set_time_limit(ini_get('max_execution_time'));

    // Initialise variables.
    $arr = [];

    // Read the source directory
    if (!($handle = @opendir($path)))
    {
    return $arr;
    }

    while (($file = readdir($handle)) !== false)
    {
    if ($file != '.' && $file != '..' && !in_array($file, $exclude)
    && (empty($excludefilter_string) || !preg_match($excludefilter_string, $file)))
    {
    // Compute the fullpath
    $fullpath = $path . '/' . $file;

    // Compute the isDir flag
    $isDir = is_dir($fullpath);

    if (($isDir xor $findfiles) && preg_match("/$filter/", $file))
    {
    // (fullpath is dir and folders are searched or fullpath is not dir and files are searched) and file matches the filter
    if ($full)
    {
    // Full path is requested
    $arr[] = $fullpath;
    }
    else
    {
    // Filename is requested
    $arr[] = $file;
    }
    }

    if ($isDir && $recurse)
    {
    // Search recursively
    if (is_integer($recurse))
    {
    // Until depth 0 is reached
    $arr = array_merge($arr, self::_items($fullpath, $filter, $recurse - 1, $full, $exclude, $excludefilter_string, $findfiles));
    }
    else
    {
    $arr = array_merge($arr, self::_items($fullpath, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles));
    }
    }
    }
    }

    closedir($handle);
    return $arr;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @return string
    */
    public static function makeSafe($path)
    {
    $regex = array('#[^A-Za-z0-9:_\\\/-]#');
    return preg_replace($regex, '', $path);
    }
    }

    /**
    * Webnus MEC Path class.
    * @author Webnus <info@webnus.net>
    */
    class MEC_path extends MEC_base
    {
    /**
    * Constructor method
    * @author Webnus <info@webnus.net>
    */
    public function __construct()
    {
    parent::__construct();
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @return boolean
    */
    public static function canChmod($path)
    {
    $perms = fileperms($path);
    if ($perms !== false)
    {
    if (@chmod($path, $perms ^ 0001))
    {
    @chmod($path, $perms);
    return true;
    }
    }

    return false;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $filemode
    * @param string $foldermode
    * @return boolean
    */
    public static function setPermissions($path, $filemode = '0644', $foldermode = '0755')
    {
    // Initialise return value
    $ret = true;

    if (is_dir($path))
    {
    $dh = opendir($path);

    while ($file = readdir($dh))
    {
    if ($file != '.' && $file != '..')
    {
    $fullpath = $path . '/' . $file;
    if (is_dir($fullpath))
    {
    if (!MEC_path::setPermissions($fullpath, $filemode, $foldermode))
    {
    $ret = false;
    }
    }
    else
    {
    if (isset($filemode))
    {
    if (!@ chmod($fullpath, octdec($filemode)))
    {
    $ret = false;
    }
    }
    }
    }
    }

    closedir($dh);
    if (isset($foldermode))
    {
    if (!@ chmod($path, octdec($foldermode)))
    {
    $ret = false;
    }
    }
    }
    else
    {
    if (isset($filemode))
    {
    $ret = @ chmod($path, octdec($filemode));
    }
    }

    return $ret;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @return string
    */
    public static function getPermissions($path)
    {
    $path = MEC_path::clean($path);
    $mode = @ decoct(@ fileperms($path) & 0777);

    if(strlen($mode) < 3)
    {
    return '---------';
    }

    $parsed_mode = '';
    for($i = 0; $i < 3; $i++)
    {
    // read
    $parsed_mode .= ($mode[$i] & 04) ? "r" : "-";
    // write
    $parsed_mode .= ($mode[$i] & 02) ? "w" : "-";
    // execute
    $parsed_mode .= ($mode[$i] & 01) ? "x" : "-";
    }

    return $parsed_mode;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $ds
    * @return string
    */
    public static function check($path, $ds = DIRECTORY_SEPARATOR)
    {
    $path = MEC_path::clean($path, $ds);
    return $path;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param string $path
    * @param string $ds
    * @return string
    */
    public static function clean($path, $ds = DIRECTORY_SEPARATOR)
    {
    $path = trim($path);
    if(empty($path))
    {
    $path = BASE_PATH;
    }
    else
    {
    // Remove double slashes and backslashes and convert all slashes and backslashes to DIRECTORY_SEPARATOR
    $path = preg_replace('#[/\\\\]+#', $ds, $path);
    }

    return $path;
    }

    /**
    * @author Webnus <info@webnus.net>
    * @param array $paths
    * @param string $file
    * @return boolean
    */
    public static function find($paths, $file)
    {
    settype($paths, 'array'); //force to array

    // Start looping through the path set
    foreach ($paths as $path)
    {
    // Get the path to the file
    $fullname = $path . '/' . $file;

    // Is the path based on a stream?
    if (strpos($path, '://') === false)
    {
    // Not a stream, so do a realpath() to avoid directory
    // traversal attempts on the local file system.
    $path = realpath($path); // needed for substr() later
    $fullname = realpath($fullname);
    }

    // The substr() check added to make sure that the realpath()
    // results in a directory registered so that
    // non-registered directories are not accessible via directory
    // traversal attempts.
    if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path)
    {
    return $fullname;
    }
    }

    return false;
    }
    }
Viewing 2 replies - 1 through 2 (of 2 total)
  • Plugin Author ImageEli

    (@scheeeli)

    Thanks for reporting this. I have removed this matching pattern from the definitions of Known Threat. Please download the latest definition updates and run the Complete Scan again to confirm that this file is no longer identified as a Known Threat.

    Thread Starter ImageJVM Design

    (@jvmd)

    Thank you!

Viewing 2 replies - 1 through 2 (of 2 total)

The topic ‘Possible False-Positive with Modern Events Calendar Lite Plugin’ is closed to new replies.