setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (Exception $e) { echo json_encode(['error' => 'DB: ' . $e->getMessage()]); exit; } $PATHS = [ 'adx' => '/opt/wevads/public', 'arsenal' => '/opt/wevads-arsenal/public', 'arsenal_api' => '/opt/wevads-arsenal/public/api' ]; $PORTS = ['adx' => 5821, 'arsenal' => 5890, 'fmg' => 5822, 'bcg' => 5823, 'dkim' => 5824]; function runFullScan($pdo, $paths, $autoFix = true) { global $start, $PORTS; $scanId = startScan($pdo, 'full'); $issues = []; $fixed = 0; $totalFiles = 0; foreach ($paths as $name => $path) { if (!is_dir($path)) continue; // 1. PHP Syntax Check $phpFiles = glob("$path/*.php"); foreach ($phpFiles as $f) { $totalFiles++; $out = shell_exec("php -l " . escapeshellarg($f) . " 2>&1"); if (strpos($out, 'Parse error') !== false || strpos($out, 'Fatal') !== false) { $issues[] = ['file' => basename($f), 'path' => $f, 'type' => 'php-syntax-error', 'detail' => substr($out, 0, 200)]; logFix($pdo, $scanId, $f, 'php-syntax-error', 'Logged for review'); } } // 2. HTML Script Tag Balance $htmlFiles = glob("$path/*.html"); foreach ($htmlFiles as $f) { $totalFiles++; $content = @file_get_contents($f); if (!$content) continue; $opens = substr_count($content, ''); if ($opens > $closes) { $diff = $opens - $closes; $issues[] = ['file' => basename($f), 'path' => $f, 'type' => 'unclosed-script', 'detail' => "open=$opens close=$closes"]; if ($autoFix && is_writable($f)) { file_put_contents($f, $content . str_repeat("\n", $diff)); $fixed++; logFix($pdo, $scanId, $f, 'unclosed-script', "Appended $diff "); } } } // 3. Injection Detection $allFiles = array_merge($phpFiles, $htmlFiles); foreach ($allFiles as $f) { $content = @file_get_contents($f); if (!$content) continue; // WEVADS_NUKE if (strpos($content, "WEVADS_" . "NUKE") !== false && strpos($f, "sentinel") === false) { $issues[] = ['file' => basename($f), 'path' => $f, 'type' => 'WEVADS_NUKE', 'detail' => 'Malicious injection']; if ($autoFix && is_writable($f)) { $content = preg_replace('/