HEX
Server: LiteSpeed
System: Linux business168.web-hosting.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
User: igniwute (1358)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: /home/igniwute/serendibscenictravels.com/wordpress_cleanup_cron.php
<?php
/**
 * WordPress Full Security & Cleanup Script
 * cPanel Safe
 * Features:
 * - Root cleanup (index.php + .htaccess)
 * - Dangerous plugins removal
 * - Permission hardening
 * - Block PHP in uploads
 * - Malware scan + JSON report
 * - WP core auto-restore (WP-CLI)
 * - Email alert: WP version, plugins list, malware
 */

// ---------------- CONFIG ----------------
$root = __DIR__;
$dryRun = true;
$logFile = $root . '/cleanup.log';
$reportFile = $root . '/security-report.json';
$alertEmail = 'corn@ignitemv.com'; // <-- CHANGE THIS

$dangerPlugins = [
    'wp-file-manager',
    'file-manager-advanced'
];

// ---------------- CLI FLAG ----------------
foreach ($argv ?? [] as $arg) {
    if ($arg === '--run') $dryRun = false;
}

// ---------------- LOG ----------------
function log_msg($msg) {
    global $logFile;
    file_put_contents($logFile, date('[Y-m-d H:i:s] ') . $msg . PHP_EOL, FILE_APPEND);
}

// ---------------- RECURSIVE DELETE ----------------
function rrmdir_or_delete($path) {
    if (!file_exists($path)) return;
    if (is_dir($path)) {
        foreach (scandir($path) as $f) {
            if ($f === '.' || $f === '..') continue;
            rrmdir_or_delete($path . '/' . $f);
        }
        rmdir($path);
    } else {
        unlink($path);
    }
}

// ---------------- WP-CLI CHECK ----------------
function wp_cli_available() {
    return !empty(shell_exec('which wp 2>/dev/null'));
}

// ---------------- STEP 1: FORCE index.php ----------------
$indexContent = <<<PHP
<?php
define( 'WP_USE_THEMES', true );
require __DIR__ . '/wp-blog-header.php';
PHP;

if ($dryRun) {
    log_msg("DRY-RUN Would create/override index.php");
} else {
    file_put_contents($root . '/index.php', $indexContent);
    log_msg("index.php created/overridden");
}

// ---------------- STEP 2: FORCE ROOT .htaccess ----------------
$htaccessContent = <<<HTACCESS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
HTACCESS;

if ($dryRun) {
    log_msg("DRY-RUN Would create/override root .htaccess");
} else {
    file_put_contents($root . '/.htaccess', $htaccessContent);
    log_msg("Root .htaccess created/overridden");
}

// ---------------- STEP 3: BLOCK PHP IN UPLOADS ----------------
$uploadsHtaccess = $root . '/wp-content/uploads/.htaccess';
$uploadsHtaccessContent = <<<HTACCESS
<FilesMatch "\.(php|php5|phtml|phar)$">
    Deny from all
</FilesMatch>
HTACCESS;

if ($dryRun) {
    log_msg("DRY-RUN Would block PHP execution in uploads");
} else {
    if (!is_dir(dirname($uploadsHtaccess))) {
        mkdir(dirname($uploadsHtaccess), 0755, true);
    }
    file_put_contents($uploadsHtaccess, $uploadsHtaccessContent);
    log_msg("PHP execution blocked in uploads");
}

// ---------------- STEP 4: DELETE DANGEROUS PLUGINS ----------------
foreach ($dangerPlugins as $plugin) {
    $path = $root . "/wp-content/plugins/{$plugin}";
    if (file_exists($path)) {
        if ($dryRun) {
            log_msg("DRY-RUN Would delete plugin: {$plugin}");
        } else {
            rrmdir_or_delete($path);
            log_msg("Deleted plugin: {$plugin}");
        }
    }
}

// ---------------- STEP 5: PERMISSION HARDENING ----------------
function fix_permissions($path) {
    if (is_dir($path)) {
        chmod($path, 0755);
        foreach (scandir($path) as $f) {
            if ($f === '.' || $f === '..') continue;
            fix_permissions($path . '/' . $f);
        }
    } else {
        chmod($path, 0644);
    }
}

if ($dryRun) {
    log_msg("DRY-RUN Would apply permissions 755/644");
} else {
    fix_permissions($root);
    if (file_exists($root . '/wp-config.php')) chmod($root . '/wp-config.php', 0600);
    log_msg("Permissions hardened");
}

// ---------------- STEP 6: MALWARE SIGNATURE SCAN ----------------
$badPatterns = ['base64_decode','eval(','gzinflate','shell_exec','passthru','str_rot13'];
$suspicious = [];

$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root));
foreach ($rii as $file) {
    if ($file->isDir()) continue;
    if (pathinfo($file, PATHINFO_EXTENSION) !== 'php') continue;
    $content = @file_get_contents($file);
    foreach ($badPatterns as $p) {
        if (stripos($content, $p) !== false) {
            $suspicious[] = (string)$file;
            log_msg("SUSPICIOUS FILE: {$file}");
            break;
        }
    }
}

// ---------------- STEP 7: WP CORE AUTO-RESTORE (WP-CLI) ----------------
$wpCli = wp_cli_available();
$wpVersion = 'Unknown';
$pluginList = [];

if ($wpCli) {
    $wpVersion = trim(shell_exec("wp core version 2>/dev/null"));
    $pluginsOutput = shell_exec("wp plugin list --format=json 2>/dev/null");
    if ($pluginsOutput) $pluginList = json_decode($pluginsOutput, true);

    if (!$dryRun) {
        shell_exec("wp core verify-checksums --quiet");
        shell_exec("wp core download --force --skip-content");
        log_msg("WordPress core verified & restored via WP-CLI");
    } else {
        log_msg("DRY-RUN Would verify & restore WP core via WP-CLI");
    }
}

// ---------------- STEP 8: JSON SECURITY REPORT ----------------
$report = [
    'timestamp' => date('c'),
    'dry_run' => $dryRun,
    'wp_cli_available' => $wpCli,
    'wordpress_version' => $wpVersion,
    'plugins_removed' => $dangerPlugins,
    'installed_plugins' => $pluginList,
    'suspicious_files_count' => count($suspicious),
    'suspicious_files' => $suspicious
];

if (!$dryRun) file_put_contents($reportFile, json_encode($report, JSON_PRETTY_PRINT));
log_msg("JSON security report generated");

// ---------------- STEP 9: EMAIL ALERT ----------------
if (!$dryRun) {
    $msg = "WordPress Security Cleanup Report\n\n";
    $msg .= "WordPress Version: {$wpVersion}\n\n";

    $msg .= "Installed Plugins:\n";
    if (!empty($pluginList)) {
        foreach ($pluginList as $plugin) {
            $msg .= " - {$plugin['name']} ({$plugin['status']}, update: {$plugin['update']})\n";
        }
    } else {
        $msg .= "No plugins found or WP-CLI not available.\n";
    }

    $msg .= "\nSuspicious files count: " . count($suspicious) . "\n";
    if (!empty($suspicious)) {
        $msg .= "Suspicious files list:\n";
        foreach ($suspicious as $file) {
            $msg .= " - " . $file . "\n";
        }
    }

    $msg .= "\nFull JSON report: security-report.json\n";

    mail($alertEmail, "WP Security Cleanup Report - Serendib Scenic Travels", $msg);
    log_msg("Email alert sent with WP version, plugin list, and suspicious files");
}

log_msg("Security cleanup completed");
echo "Security cleanup completed. Check cleanup.log and security-report.json\n";

if ($dryRun) echo "Dry-run mode. Use --run to apply changes.\n";