3 && time() - $log[$_SERVER['REMOTE_ADDR']]['time'] < 86400) { die('This IP address is blocked due to unsuccessful login attempts.'); } foreach ($log as $key => $value) { if (time() - $value['time'] > 86400) { unset($log[$key]); $log_updated = true; } } if (isset($log_updated)) { file_put_contents(LOG_FILE, serialize($log)); } } session_set_cookie_params(86400, dirname($_SERVER['REQUEST_URI'])); session_name('pheditor'); session_start(); if (empty(PASSWORD) === false && (isset($_SESSION['pheditor_admin']) === false || $_SESSION['pheditor_admin'] !== true)) { if (isset($_POST['pheditor_password']) && empty($_POST['pheditor_password']) === false) { if (hash('sha512', $_POST['pheditor_password']) === PASSWORD) { $_SESSION['pheditor_admin'] = true; redirect(); } else { $error = 'The entry password is not correct.'; $log = file_exists(LOG_FILE) ? unserialize(file_get_contents(LOG_FILE)) : array(); if (isset($log[$_SERVER['REMOTE_ADDR']]) === false) { $log[$_SERVER['REMOTE_ADDR']] = array('num' => 0, 'time' => 0); } $log[$_SERVER['REMOTE_ADDR']]['num'] += 1; $log[$_SERVER['REMOTE_ADDR']]['time'] = time(); file_put_contents(LOG_FILE, serialize($log)); } } else if (isset($_POST['action'])) { header('HTTP/1.0 403 Forbidden'); die('Your session has expired.'); } die('Pheditor

Pheditor

' . (isset($error) ? '

' . $error . '

' : null) . '

'); } if (isset($_GET['logout'])) { unset($_SESSION['pheditor_admin']); redirect(); } $permissions = explode(',', PERMISSIONS); $permissions = array_map('trim', $permissions); $permissions = array_filter($permissions); if (count($permissions) < 1) { $permissions = explode(',', 'newfile,newdir,editfile,deletefile,deletedir,renamefile,renamedir,changepassword,uploadfile'); } if (isset($_POST['action'])) { header('Content-Type: application/json'); if (isset($_POST['file']) && empty($_POST['file']) === false) { $_POST['file'] = urldecode($_POST['file']); if (empty(PATTERN_FILES) === false && !preg_match(PATTERN_FILES, basename($_POST['file']))) { die(json_error('Invalid file pattern')); } if (strpos($_POST['file'], '../') !== false || strpos($_POST['file'], '..\'') !== false) { die(json_error('Invalid file pattern')); } } switch ($_POST['action']) { case 'open': $_POST['file'] = urldecode($_POST['file']); if (isset($_POST['file']) && file_exists(MAIN_DIR . $_POST['file'])) { die(json_success('OK', [ 'data' => file_get_contents(MAIN_DIR . $_POST['file']), ])); } break; case 'save': $file = MAIN_DIR . $_POST['file']; if (isset($_POST['file']) && isset($_POST['data']) && (file_exists($file) === false || is_writable($file))) { if (file_exists($file) === false) { if (in_array('newfile', $permissions) !== true) { die(json_error('Permission denied', true)); } file_put_contents($file, $_POST['data']); echo json_success('File saved successfully'); } else if (is_writable($file) === false) { echo json_error('File is not writable'); } else { if (in_array('editfile', $permissions) !== true) { die(json_error('Permission denied')); } if (file_exists($file)) { file_to_history($file); } file_put_contents($file, $_POST['data']); echo json_success('File saved successfully'); } } break; case 'make-dir': if (in_array('newdir', $permissions) !== true) { die(json_error('Permission denied')); } $dir = MAIN_DIR . $_POST['dir']; if (file_exists($dir) === false) { mkdir($dir); echo json_success('Directory created successfully'); } else { echo json_error('Directory already exists'); } break; case 'reload': echo json_success('OK', [ 'data' => files(MAIN_DIR), ]); break; case 'password': if (in_array('changepassword', $permissions) !== true) { die(json_error('Permission denied')); } if (isset($_POST['password']) && empty($_POST['password']) === false) { $contents = file(__FILE__); foreach ($contents as $key => $line) { if (strpos($line, 'define(\'PASSWORD\'') !== false) { $contents[$key] = "define('PASSWORD', '" . hash('sha512', $_POST['password']) . "');\n"; break; } } file_put_contents(__FILE__, implode($contents)); echo json_success('Password changed successfully'); } break; case 'delete': if (isset($_POST['path']) && file_exists(MAIN_DIR . $_POST['path'])) { $path = MAIN_DIR . $_POST['path']; if ($_POST['path'] == '/') { echo json_error('Unable to delete main directory'); } else if (is_dir($path)) { if (count(scandir($path)) !== 2) { echo json_error('Directory is not empty'); } else if (is_writable($path) === false) { echo json_error('Unable to delete directory'); } else { if (in_array('deletedir', $permissions) !== true) { die(json_error('Permission denied')); } rmdir($path); echo json_success('Directory deleted successfully'); } } else { file_to_history($path); if (is_writable($path)) { if (in_array('deletefile', $permissions) !== true) { die(json_error('Permission denied')); } unlink($path); echo json_success('File deleted successfully'); } else { echo json_error('Unable to delete file'); } } } break; case 'rename': if (isset($_POST['path']) && file_exists(MAIN_DIR . $_POST['path']) && isset($_POST['name']) && empty($_POST['name']) === false) { $path = MAIN_DIR . $_POST['path']; $new_path = str_replace(basename($path), '', dirname($path)) . DS . $_POST['name']; if ($_POST['path'] == '/') { echo json_error('Unable to rename main directory'); } else if (is_dir($path)) { if (in_array('renamedir', $permissions) !== true) { die(json_error('Permission denied')); } if (is_writable($path) === false) { echo json_error('Unable to rename directory'); } else { rename($path, $new_path); echo json_success('Directory renamed successfully'); } } else { if (in_array('renamefile', $permissions) !== true) { die(json_error('Permission denied')); } else if (empty(PATTERN_FILES) === false && !preg_match(PATTERN_FILES, $_POST['name'])) { die(json_error('Invalid file pattern: ' . htmlspecialchars($_POST['name']))); } file_to_history($path); if (is_writable($path)) { rename($path, $new_path); echo json_success('File renamed successfully'); } else { echo json_error('Unable to rename file'); } } } break; case 'upload-file': $files = isset($_FILES['uploadfile']) ? $_FILES['uploadfile'] : []; $destination = isset($_POST['destination']) ? rtrim($_POST['destination']) : null; if (empty($destination) === false && (strpos($destination, '/..') !== false || strpos($destination, '\\..') !== false)) { die(json_error('Invalid file destination')); } $destination = MAIN_DIR . $destination; if (file_exists($destination) === false || is_dir($destination) === false) { die(json_error('File destination does not exists')); } if (is_writable($destination) !== true) { die(json_error('File destination is not writable')); } if (is_array($files) && count($files) > 0) { for ($i = 0; $i < count($files['name']); $i += 1) { if (empty(PATTERN_FILES) === false && !preg_match(PATTERN_FILES, $files['name'][$i])) { die(json_error('Invalid file pattern: ' . htmlspecialchars($files['name'][$i]))); } move_uploaded_file($files['tmp_name'][$i], $destination . '/' . $files['name'][$i]); } echo json_success('File' . (count($files['name']) > 1 ? 's' : null) . ' uploaded successfully'); } break; case 'terminal': if (in_array('terminal', $permissions) !== false && isset($_POST['command'], $_POST['dir'])) { if (function_exists('shell_exec') === false) { echo json_error("shell_exec function is disabled\n"); exit; } set_time_limit(15); $command = $_POST['command']; $dir = $_POST['dir']; $command_found = false; foreach (explode(',', TERMINAL_COMMANDS) as $value) { $value = trim($value); if (strlen($command) >= strlen($value) && substr($command, 0, strlen($value)) == $value) { $command_found = true; break; } } if ($command_found === false) { echo json_error("Command not allowed\n"); exit; } $output = shell_exec((empty($dir) ? null : 'cd ' . $dir . ' && ') . $command . ' && echo \ ; pwd'); $output = trim($output); if (empty($output)) { $output = null; $dir = null; } else { $output = explode("\n", $output); $dir = end($output); unset($output[count($output) - 1]); $output = implode("\n", $output); $output = trim($output) . "\n"; $output = htmlspecialchars($output); } echo json_success('OK', ['result' => $output, 'dir' => $dir]); } break; } exit; } function files($dir, $first = true) { $data = ''; if ($first === true) { $data .= ''; } return $data; } function redirect($address = null) { if (empty($address)) { $address = $_SERVER['PHP_SELF']; } header('Location: ' . $address); exit; } function file_to_history($file) { if (is_numeric(MAX_HISTORY_FILES) && MAX_HISTORY_FILES > 0) { $file_dir = dirname($file); $file_name = basename($file); $file_history_dir = HISTORY_PATH . str_replace(MAIN_DIR, '', $file_dir); foreach ([HISTORY_PATH, $file_history_dir] as $dir) { if (file_exists($dir) === false || is_dir($dir) === false) { mkdir($dir, 0777, true); } } $history_files = scandir($file_history_dir); foreach ($history_files as $key => $history_file) { if (in_array($history_file, ['.', '..', '.DS_Store'])) { unset($history_files[$key]); } } $history_files = array_values($history_files); if (count($history_files) >= MAX_HISTORY_FILES) { foreach ($history_files as $key => $history_file) { if ($key < 1) { unlink($file_history_dir . DS . $history_file); unset($history_files[$key]); } else { rename($file_history_dir . DS . $history_file, $file_history_dir . DS . $file_name . '.' . ($key - 1)); } } } copy($file, $file_history_dir . DS . $file_name . '.' . count($history_files)); } } function json_error($message, $params = []) { return json_encode(array_merge([ 'error' => true, 'message' => $message, ], $params), JSON_UNESCAPED_UNICODE); } function json_success($message, $params = []) { return json_encode(array_merge([ 'error' => false, 'message' => $message, ], $params), JSON_UNESCAPED_UNICODE); } ?> Pheditor
Terminal