From fa101db3b685e776dc51b6b0636e27b7d3b9277e Mon Sep 17 00:00:00 2001 From: Jose Gonzalez Date: Fri, 3 Sep 2021 13:30:15 +0200 Subject: [PATCH] Fix vulnerability --- pandora_console/godmode/servers/plugin.php | 41 ++++--------- .../godmode/setup/file_manager.php | 16 +---- .../include/functions_filemanager.php | 59 ++++++++++++++----- .../snmpconsole/snmp_mib_uploader.php | 15 +---- 4 files changed, 58 insertions(+), 73 deletions(-) diff --git a/pandora_console/godmode/servers/plugin.php b/pandora_console/godmode/servers/plugin.php index e8d12e654c..c247987c42 100644 --- a/pandora_console/godmode/servers/plugin.php +++ b/pandora_console/godmode/servers/plugin.php @@ -219,34 +219,15 @@ if ($filemanager) { $id_plugin = (int) get_parameter('id_plugin', 0); - // Add custom directories here + // Add custom directories here. $fallback_directory = 'attachment/plugin'; - - $directory = (string) get_parameter('directory', $fallback_directory); - $directory = str_replace('\\', '/', $directory); - - // A miminal security check to avoid directory traversal - if (preg_match('/\.\./', $directory)) { - $directory = $fallback_directory; - } - - if (preg_match('/^\//', $directory)) { - $directory = $fallback_directory; - } - - if (preg_match('/^manager/', $directory)) { - $directory = $fallback_directory; - } - - $banned_directories['include'] = true; - $banned_directories['godmode'] = true; - $banned_directories['operation'] = true; - $banned_directories['reporting'] = true; - $banned_directories['general'] = true; - $banned_directories[ENTERPRISE_DIR] = true; - - if (isset($banned_directories[$directory])) { + // Get directory. + $directory = (string) get_parameter('directory'); + if (empty($directory) === true) { $directory = $fallback_directory; + } else { + $directory = str_replace('\\', '/', $directory); + $directory = filemanager_safe_directory($directory, $fallback_directory); } $real_directory = realpath($config['homedir'].'/'.$directory); @@ -263,12 +244,12 @@ if ($filemanager) { $default_real_directory = realpath($config['homedir'].'/'.$fallback_directory); - if ($upload_file_or_zip) { - upload_file($upload_file_or_zip, $default_real_directory); + if ($upload_file_or_zip === true) { + upload_file($upload_file_or_zip, $default_real_directory, $real_directory); } - if ($create_text_file) { - create_text_file($default_real_directory); + if ($create_text_file === true) { + create_text_file($default_real_directory, $real_directory); } filemanager_file_explorer( diff --git a/pandora_console/godmode/setup/file_manager.php b/pandora_console/godmode/setup/file_manager.php index a33bdad26e..af7e9d6e3a 100644 --- a/pandora_console/godmode/setup/file_manager.php +++ b/pandora_console/godmode/setup/file_manager.php @@ -58,18 +58,6 @@ if (empty($directory) === true) { $directory = filemanager_safe_directory($directory, $fallback_directory); } -// Banned directories. -$banned_directories['include'] = true; -$banned_directories['godmode'] = true; -$banned_directories['operation'] = true; -$banned_directories['reporting'] = true; -$banned_directories['general'] = true; -$banned_directories[ENTERPRISE_DIR] = true; - -if (isset($banned_directories[$directory]) === true) { - $directory = $fallback_directory; -} - $real_directory = realpath($config['homedir'].'/'.$directory); echo '

'.__('Index of %s', $directory).'

'; @@ -80,11 +68,11 @@ $create_text_file = (bool) get_parameter('create_text_file'); $default_real_directory = realpath($config['homedir'].'/'); if ($upload_file_or_zip === true) { - upload_file($upload_file_or_zip, $default_real_directory); + upload_file($upload_file_or_zip, $default_real_directory, $real_directory); } if ($create_text_file === true) { - create_text_file($default_real_directory); + create_text_file($default_real_directory, $real_directory); } filemanager_file_explorer( diff --git a/pandora_console/include/functions_filemanager.php b/pandora_console/include/functions_filemanager.php index 4dc595f9fb..9f47cf7b29 100644 --- a/pandora_console/include/functions_filemanager.php +++ b/pandora_console/include/functions_filemanager.php @@ -128,15 +128,16 @@ require_once $config['homedir'].'/vendor/autoload.php'; * * @param boolean $upload_file_or_zip Upload file or zip. * @param string $default_real_directory String with default directory. + * @param string $destination_directory String with destination directory. * * @return void */ -function upload_file($upload_file_or_zip, $default_real_directory) +function upload_file($upload_file_or_zip, $default_real_directory, $destination_directory) { global $config; $config['filemanager'] = []; $config['filemanager']['correct_upload_file'] = 0; - $config['filemanager']['message'] = null; + $config['filemanager']['message'] = ''; check_login(); @@ -164,7 +165,7 @@ function upload_file($upload_file_or_zip, $default_real_directory) if ($upload_file === true) { if (isset($_FILES['file']) === true && empty($_FILES['file']['name']) === false) { $filename = $_FILES['file']['name']; - $real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); + $real_directory = filemanager_safe_directory($destination_directory); $umask = io_safe_output((string) get_parameter('umask')); if (strpos($real_directory, $default_real_directory) !== 0) { @@ -173,23 +174,34 @@ function upload_file($upload_file_or_zip, $default_real_directory) // user is not trying to access an external path (avoid // execution of PHP files in directories that are not explicitly // controlled by corresponding .htaccess). - ui_print_error_message(__('Security error')); + $config['filemanager']['message'] = ui_print_error_message(__('Security error')); } else { // Copy file to directory and change name. - $nombre_archivo = $real_directory.'/'.$filename; + $nombre_archivo = sprintf('%s/%s', $real_directory, $filename); - if (! @copy($_FILES['file']['tmp_name'], $nombre_archivo)) { - $config['filemanager']['message'] = ui_print_error_message(__('Upload error')); - } else { + try { + $result = copy($_FILES['file']['tmp_name'], $nombre_archivo); + } catch (Exception $ex) { + $result = false; + } + + if ($result === true) { + // If umask is provided, set. if (empty($umask) === false) { - chmod($nombre_archivo, $umask); + try { + chmod($nombre_archivo, $umask); + } catch (Exception $ex) { + $config['filemanager']['message'] = ui_print_error_message(__('Issue setting umask: %s', $ex->getMessage())); + } } + // Upload performed properly. + $config['filemanager']['message'] .= ui_print_success_message(__('Upload correct')); $config['filemanager']['correct_upload_file'] = 1; - ui_print_success_message(__('Upload correct')); - // Delete temporal file. unlink($_FILES['file']['tmp_name']); + } else { + $config['filemanager']['message'] = ui_print_error_message(__('Upload error')); } } } @@ -202,7 +214,7 @@ function upload_file($upload_file_or_zip, $default_real_directory) ) { $filename = $_FILES['file']['name']; $filepath = $_FILES['file']['tmp_name']; - $real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); + $real_directory = filemanager_safe_directory($destination_directory); if (strpos($real_directory, $default_real_directory) !== 0) { // Perform security check to determine whether received upload @@ -213,10 +225,10 @@ function upload_file($upload_file_or_zip, $default_real_directory) ui_print_error_message(__('Security error')); } else { if (PandoraFMS\Tools\Files::unzip($filepath, $real_directory) === false) { - ui_print_error_message(__('It was impossible to uncompress your file')); + $config['filemanager']['message'] = ui_print_error_message(__('It was impossible to uncompress your file')); } else { unlink($_FILES['file']['tmp_name']); - ui_print_success_message(__('Upload correct')); + $config['filemanager']['message'] = ui_print_success_message(__('Upload correct')); $config['filemanager']['correct_upload_file'] = 1; } } @@ -234,7 +246,7 @@ if (isset($_SERVER['CONTENT_LENGTH']) === true) { } -function create_text_file($default_real_directory) +function create_text_file($default_real_directory, $destination_directory) { global $config; @@ -253,7 +265,7 @@ function create_text_file($default_real_directory) $filename = filemanager_safe_directory((string) get_parameter('name_file')); if (empty($filename) === false) { - $real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); + $real_directory = filemanager_safe_directory($destination_directory); $umask = (string) get_parameter('umask'); if (strpos($real_directory, $default_real_directory) !== 0) { @@ -980,6 +992,15 @@ function filemanager_safe_directory( // Safe output. $directory = io_safe_output($directory); $forbiddenAttempting = false; + // Banned directories. + $bannedDirectory = [ + 'include', + 'godmode', + 'operation', + 'reporting', + 'general', + ENTERPRISE_DIR, + ]; if ((bool) preg_match('/(\.){2}/', $directory) !== false) { $directory = preg_replace('/(\.){2}/', '', (empty($safedDirectory) === true) ? $directory : $safedDirectory); @@ -991,6 +1012,12 @@ function filemanager_safe_directory( $forbiddenAttempting = true; } + if (in_array($directory, $bannedDirectory) === true) { + // Setted images for default (usually in file manager). + $directory = (empty($safedDirectory) === false) ? $safedDirectory : 'images'; + $forbiddenAttempting = true; + } + if ($forbiddenAttempting === true) { db_pandora_audit('File manager', 'Attempting to use a forbidden file or directory name'); } diff --git a/pandora_console/operation/snmpconsole/snmp_mib_uploader.php b/pandora_console/operation/snmpconsole/snmp_mib_uploader.php index a0d6d0ebb1..fdaff50428 100644 --- a/pandora_console/operation/snmpconsole/snmp_mib_uploader.php +++ b/pandora_console/operation/snmpconsole/snmp_mib_uploader.php @@ -78,17 +78,6 @@ if (empty($directory) === true) { $directory = filemanager_safe_directory($directory, $fallback_directory); } -$banned_directories['include'] = true; -$banned_directories['godmode'] = true; -$banned_directories['operation'] = true; -$banned_directories['reporting'] = true; -$banned_directories['general'] = true; -$banned_directories[ENTERPRISE_DIR] = true; - -if (isset($banned_directories[$directory]) === true) { - $directory = $fallback_directory; -} - $real_directory = realpath($config['homedir'].'/'.$directory); ui_print_info_message(__('MIB files will be installed on the system. Please note that a MIB may depend on other MIB. To customize trap definitions use the SNMP trap editor.')); @@ -99,11 +88,11 @@ $create_text_file = (bool) get_parameter('create_text_file'); $default_real_directory = realpath($config['homedir'].'/'.$fallback_directory); if ($upload_file_or_zip === true) { - upload_file($upload_file_or_zip, $default_real_directory); + upload_file($upload_file_or_zip, $default_real_directory, $real_directory); } if ($create_text_file === true) { - create_text_file($default_real_directory); + create_text_file($default_real_directory, $real_directory); } filemanager_file_explorer(