Current Path : /proc/self/root/proc/5213/cwd/wp-content/plugins/backup-backup/includes/cli/ |
Current File : //proc/self/root/proc/5213/cwd/wp-content/plugins/backup-backup/includes/cli/php_cli_finder.php |
<?php // Namespace namespace BMI\Plugin\PHPCLI; // Use use BMI\Plugin\Backup_Migration_Plugin as BMP; // Exit on direct access if (!defined('ABSPATH')) exit; /** * Scans for PHP CLI executable and makes sure exec is working */ class Checker { /** * Points if the exec is disabled or not */ public $ini_disabled = true; /** * __construct - Unused construct function * * @return {self} */ function __construct() {} /** * findPHP - Scans the system to find executable PHP * * @return {bool/array} false on fail, array on success * $final_executable = [ * 'version' => $php_cli_version, * 'brand' => $php_brand, * 'memory' => $php_cli_memory . '/' . $php_cli_memory_modified, * 'max_exec' => $php_cli_max_exec . '/' . $php_cli_max_exec_modified, * 'executable' => $executable_path_to_file * ]; */ public function findPHP() { // Return false if exec is disabled if ($this->isExecEnabled() === false) return false; // Check if user defined own PHP CLI $user_defined = false; if (defined('BMI_CLI_EXECUTABLE')) { if (file_exists(BMI_CLI_EXECUTABLE)) { $user_defined = true; } } if ($user_defined === false) { // Makes variable for system paths list $system_paths = null; // Exec command which displays all paths per line @exec('(sed "s/:/\n/g" <<< $PATH) 2>&1', $system_paths); // Concat output $system_paths = implode("\n", $system_paths); // Check if the output is not empty, if empty abort // if (empty($system_paths) || !$system_paths) return false; // Make variable for executables that contains php keyword $executables = ['php', '/usr/bin/php', '/usr/bin/php8.0', '/usr/bin/php7.4']; // Make variable for "for" loop $system_paths = explode("\n", $system_paths); if (in_array('/usr/bin', $system_paths)) $system_paths[] = '/usr/bin'; if (in_array('/bin', $system_paths)) $system_paths[] = '/bin'; if (in_array('/etc/alternatives', $system_paths)) $system_paths[] = '/etc/alternatives'; if (in_array('/usr/local/bin', $system_paths)) $system_paths[] = '/usr/local/bin'; // Loop all paths and check for PHP executables for ($i = 0; $i < sizeof($system_paths); ++$i) { // Variable for scan output $executables_scan = null; // Trim the path just in case $path = trim($system_paths[$i]); // If path is empty ignore and continue if (empty($path)) continue; // Exec command which will display PHP (in name) executables @exec('(for i in $(ls ' . $path . ' | grep "php"); do [ -x ' . $path . '/$i ] && echo ' . $path . '/$i || echo ""; done;) 2>&1', $executables_scan); // Implode the output $executables_scan = implode("\n", $executables_scan); // Merge the array with other results $executables = array_merge($executables, explode("\n", $executables_scan)); } } // Make variable for real PHP executables $php_executables = []; // If used defined own PHP CLI use it if ($user_defined === true) $executables = [BMI_CLI_EXECUTABLE]; // Filter the array to exclude empty values and remove duplicates $executables = array_filter(array_unique($executables)); // Make variable for final executable $final_executable = false; // Loop and test the executables foreach ($executables as $exe) { // If path+name does not contain php ignore and continue if (strpos($exe, 'php') === false) continue; // Make variable for CLI version in shell $shell_version = null; // Make variable for regex check $output = null; // Exec the command to check shell displayed version @exec($exe . ' --version 2>&1', $shell_version); // Implode the output $shell_version = implode("\n", $shell_version); // Test the output with regex to find PHP version and brand preg_match('/PHP\ (.*)\ (.*)\ \(built: (.*)\)/i', $shell_version, $output); // Check if the output is not empty and contains at least 4 results if ($output && !empty($output) && !empty($output[1]) && sizeof($output) >= 4) { // Remove additional characters from the version leave only numbers with dots $php = preg_replace("/[^0-9.]/", "", $output[1]); // Save the brand in the $brand variable $brand = $output[2]; // Make variable for file version test $file_version = null; // Make variable for shell inline PHP version test $inline_version = null; // Exec the shell inline test for version @exec($exe . ' -r "echo phpversion();" 2>&1', $inline_version); // Implode the version $inline_version = implode("\n", $inline_version); // Check if the version match required minimum if (version_compare($inline_version, '7.0', '>=')) { // Path to CLI check file $path_to_cli = BMI_INCLUDES . '/cli/version_check.php'; // Exec the file check if it can run files @exec($exe . ' -f ' . $path_to_cli . ' 2>&1', $file_version); // Check if the output is correct if ($file_version && is_array($file_version) && !empty($file_version) && sizeof($file_version) >= 5) { // The results from file saved to named variables $php_cli_version = $file_version[0]; $php_cli_memory = $file_version[1]; $php_cli_max_exec = $file_version[2]; $php_cli_memory_modified = $file_version[3]; $php_cli_max_exec_modified = $file_version[4]; // Check if the version match the inline one (it's the same php.ini) if (trim($php_cli_version) == trim($inline_version)) { // If it match use this PHP CLI module $final_executable = [ 'brand' => $brand, 'version' => $php_cli_version, 'memory' => $php_cli_memory . '/' . $php_cli_memory_modified, 'max_exec' => $php_cli_max_exec . '/' . $php_cli_max_exec_modified, 'executable' => $exe ]; break; } } } } } // Return the final result return $final_executable; } /** * isExecAvailable - Check if exec is not blocked by php.ini * * @return {bool} true on success / false on fail */ public function isExecAvailable() { // Get disabled functions $disabled_functions = @ini_get('disable_functions'); // Turn disabled functions to array $disabled_functions = explode(',', $disabled_functions); // Check if everything is allowed if (empty($disabled_functions)) { // Check if function is callable and not disabled (PHP 8 check) if (function_exists('shell_exec') && is_callable('shell_exec')) return true; else return false; } // Few checks if (!is_array($disabled_functions)) return false; elseif (in_array('shell_exec', $disabled_functions)) return false; elseif (in_array('exec', $disabled_functions)) return false; elseif (in_array('system', $disabled_functions)) return false; else { // Check if function is callable and not disabled (PHP 8 check) if (function_exists('shell_exec') && is_callable('shell_exec')) return true; else return false; } } /** * isExecEnabled - Checks if exec function is not disabled or blocked * * @return {bool} true on success / false on fail */ public function isExecEnabled() { // Check if the function is not disabled in php.ini if ($this->isExecAvailable()) { // Mark as enabled in php_ini $this->ini_disabled = false; // Try to run simple shell try { // Output variable $output = null; // Execute the command @exec('echo "It works!" 2>&1', $output); // Implode the output just in case if ($output) { $output = implode("\n", $output); } else return false; // Check if the output is as expected if ($output === 'It works!') return true; else return false; // Catch errors in older PHP } catch (\Error $e) { return false; // Catch exceptions if any } catch (\Exception $e) { return false; // Catch throwable exception if any } catch (\Throwable $e) { return false; } // If the function is blocked do not even try and return false } else { // Mark as disabled in php_ini $this->ini_disabled = true; return false; } } }