
CVE-2026-5076 के लिए साक्ष्य-अवधारणा शोषण जो ARMember Premium में SQL injection और plaintext पासवर्ड रीसेट कुंजी भंडारण के माध्यम से अप्रमाणित व्यवस्थापक खाता अधिग्रहण प्रदर्शित करता है।
प्लेनटेक्स्ट पासवर्ड रीसेट कुंजियाँ डेटाबेस में संग्रहीत + SQL इंजेक्शन = पूर्ण व्यवस्थापक अधिग्रहण
| आइटम | विवरण |
|---|---|
| CVE ID | CVE-2026-5076 |
| प्लगइन | ARMember – सदस्यता प्लगइन और सामग्री प्रतिबंध |
| प्रभावित संस्करण | Premium <= 7.3.1 |
| पैच किया गया संस्करण | 7.3.2 |
| CVSS स्कोर | 9.8 गंभीर |
| CWE | CWE-640: कमजोर पासवर्ड पुनर्प्राप्ति |
| प्रकार | असुरक्षित पासवर्ड रीसेट तंत्र → प्लेनटेक्स्ट कुंजी भंडारण |
| आक्रमण वेक्टर | नेटवर्क / रिमोट / बिना प्रमाणीकरण (SQLi श्रृंखला के माध्यम से) |
| सक्रिय स्थापनाएँ | 30,000+ (प्रीमियम) |
| खोजकर्ता | Wordfence Threat Intelligence |
| प्रकाशन तिथि | 3 जून 2026 |
| CVE | प्रकार | गंभीरता |
|---|---|---|
| CVE-2026-5076 | असुरक्षित पासवर्ड रीसेट — प्लेनटेक्स्ट कुंजी भंडारण | 9.8 गंभीर |
| CVE-2026-5073 | बिना प्रमाणीकरण SQL इंजेक्शन (ORDER BY) | 9.8 गंभीर |
| CVE-2026-5074 | बिना प्रमाणीकरण SQL इंजेक्शन (WHERE) | 9.8 गंभीर |
वर्डप्रेस प्लगइन ARMember Premium <= 7.3.1 में तीन गंभीर कमजोरियाँ, जिन्हें एक साथ जोड़ने पर बिना प्रमाणीकरण के पूर्ण व्यवस्थापक खाता अधिग्रहण संभव होता है:
wp_usermeta (arm_reset_password_key) में प्लेनटेक्स्ट में संग्रहीत होती है, वर्डप्रेस मानक के अनुसार हैश नहीं की जातीarm_directory_paging_action() में order पैरामीटर पर SQL इंजेक्शनarm_directory_paging_action() में filter पैरामीटर पर SQL इंजेक्शनCVE-2026-5076 का प्रत्यक्ष परिणाम: डेटाबेस तक पढ़ने की पहुँच रखने वाला कोई भी व्यक्ति (SQLi, बैकअप एक्सपोज़र आदि के माध्यम से) पासवर्ड रीसेट कुंजी को प्लेनटेक्स्ट में पढ़ सकता है और सीधे किसी भी खाते का पासवर्ड रीसेट कर सकता है — बिना क्रैकिंग की आवश्यकता।
वर्डप्रेस मानक पासवर्ड रीसेट कुंजी को user_activation_key कॉलम में hashed रूप में wp_hash() का उपयोग करके संग्रहीत करता है। ARMember उसी कुंजी की एक प्रति wp_usermeta में meta_key arm_reset_password_key के साथ संग्रहीत करता है — लेकिन PLAINTEXT रूप में:```php
// FILE: armember-membership/core/class.arm_member_forms.php
// Fungsi: arm_lost_password_action()
// WordPress menyimpan HASHED key (aman) $key = wp_generate_password(20, false); $wp_key = $wpdb->get_var( $wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login=%s", $user_login) );
// ARMember menyimpan PLAINTEXT key (VULNERABLE!) update_user_meta($user_id, 'arm_reset_password_key', $wp_key); // ^^^^^^ // Ini adalah key ASLI yang bisa langsung dipakai
**गंभीर समस्या**: `$wp_key` यहाँ `wp_generate_password(20, false)` द्वारा उत्पन्न की गई key है — 20 अल्फ़ान्यूमेरिक वर्ण। WordPress इस key को `user_activation_key` में संग्रहीत करने से पहले हैश करता है, लेकिन ARMember इसे **हैश करने से पहले** संग्रहीत करता है या एक अलग प्रतिलिपि संग्रहीत करता है जो **हैश नहीं की गई** है।
### मूल कारण #2: कुंजी स्थिरता बग
जब `get_password_reset_key()` कहा जाता है (WordPress कोर), तो एक नई key उत्पन्न और हैश की जाती है। लेकिन यह फ़ंक्शन `arm_reset_password_key` को **अपडेट नहीं करता**:```php
// WordPress core: get_password_reset_key($user)
// - Generate key baru
// - Hash key → simpan di user_activation_key
// - Return key plaintext
// - TAPI: arm_reset_password_key TIDAK diupdate!
परिणामस्वरूप, पुरानी प्लेनटेक्स्ट कुंजी हमेशा के लिए संग्रहीत रहती है arm_reset_password_key में, भले ही उपयोगकर्ता पासवर्ड रीसेट कर ले। इस कुंजी का बार-बार उपयोग किया जा सकता है जब तक कि मेटा कुंजी को स्पष्ट रूप से हटा नहीं दिया जाता।
AJAX हैंडलर arm_directory_paging_action() में arm_check_user_cap() के माध्यम से nonce जांच होती है, लेकिन पैरामीटर order और filter सीधे SQL क्वेरी में बिना सैनिटाइजेशन के पहुंच जाते हैं:```php
// FILE: armember-membership/core/class.arm_member_forms.php
// Fungsi: arm_directory_paging_action()
// Nonce check (dibutuhkan nonce valid) $nonce_check = $this->arm_check_user_cap();
// ORDER BY injection — langsung ke SQL tanpa sanitasi! $orderby = "u.{$arm_member} {$order_dir}"; // $order_dir dari $_POST['order'] → LANGSUNG ke ORDER BY
// WHERE injection via filter if (!empty($filter)) { $where .= " AND " . $filter; // ← LANGSUNG concatenation! }
**ORDER BY का शोषण**: पैरामीटर `order` को SQL के `ORDER BY` क्लॉज में डाला जाता है। चूंकि कोई सैनिटाइज़ेशन नहीं है, हमलावर subquery inject कर सकता है:```sql
-- Payload SQLi via parameter order
ORDER BY u.ID ASC, IF(COND, 1, EXP(710))
-- COND = TRUE → IF returns 1 → ORDER BY 1 → response normal (besar)
-- COND = FALSE → IF returns EXP(710) → MySQL overflow ERROR → response 90B
Oracle यह network latency के प्रति प्रतिरक्षित है क्योंकि यह TRUE/FALSE को error बनाम success के आधार पर अलग करता है, न कि प्रतिक्रिया समय के आधार पर।
╔══════════════════════════════════════════════════════════════════════════════════╗ ║ CVE-2026-5076 FULL CHAIN ATTACK ROADMAP ║ ║ ARMember Premium <= 7.3.1 → Unauthenticated Admin Takeover ║ ╚══════════════════════════════════════════════════════════════════════════════════╝