Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
wp2shell — PoC de RCE sin autenticación para el núcleo de WordPress — encadena CVE-2026-63030 (route-confusion desync en REST /batch/v1) con CVE-2026-60137 (SQLi en author__not_in) para obtener un shell sin autenticación. Solo pruebas autorizadas. | Kitploit
Herramientas/GitHubGitHub/mcipekci/wp2shell
Escalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPost-ExplotaciónSeguridad WebPruebas de PenetraciónComando y ControlRed TeamingDesarrollo de Payloads
GitHubmcipekci/wp2shell
158hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

wp2shell

PoC de RCE sin autenticación para el núcleo de WordPress — encadena CVE-2026-63030 (route-confusion desync en REST /batch/v1) con CVE-2026-60137 (SQLi en author__not_in) para obtener un shell sin autenticación. Solo pruebas autorizadas.

Ver Repositorio

wp2shell — RCE pre-autenticación en el núcleo de WordPress

PoC de RCE no autenticado en el núcleo de WordPress que encadena CVE-2026-63030 + CVE-2026-60137. Solo pruebas autorizadas.

wp2shell.py es una prueba de concepto de un solo archivo que usa únicamente la biblioteca estándar y encadena dos vulnerabilidades del núcleo de WordPress para lograr ejecución remota de código no autenticada:

CVEComponenteFallo
CVE-2026-63030Manejador REST /batch/v1desync por confusión de rutas: el manejador de lotes pierde la sincronía entre su tabla de manejadores y su tabla de validación cuando una ruta de sub-solicitud no se puede analizar, de modo que una sub-solicitud se despacha a través de un manejador para el que nunca fue validada.
CVE-2026-60137WP_Queryinyección SQL escalar: el valor de author__not_in se inserta directamente en el SQL, por lo que una cadena que llegue hasta él es inyectable.

Ninguna de las dos es RCE por sí sola. El desync es el medio de entrega (introduce una cadena del atacante en una consulta a la que nunca debería llegar); la inyección es la primitiva. Juntas le dan a un atacante sin autenticación un oráculo completo de lectura/escritura SQL y, a partir de ahí, una shell funcional.

⚠️ Solo pruebas autorizadas. Esto explota instalaciones de WordPress en producción. Úsalo solo contra sistemas que poseas o para los que tengas permiso explícito por escrito.


Versiones afectadas

Vulnerables: 6.8.0–6.8.5, 6.9.0–6.9.4, 7.0.0–7.0.1 Corregidas: 6.8.6, 6.9.5, 7.0.2 (y posteriores) Reportadas por Adam Kues (Assetnote / Searchlight Cyber); la SQLi también acreditada a TF1T, dtro, haongo.

Solo 6.9.0–7.0.1 son capaces de RCE. En la línea 6.8.x el desync aún se dispara, pero la rama que desalinearía el manejador choca con un fatal WP_Error::get_method() en su lugar — así que 6.8.x es una denegación de servicio / caída, no una shell. La herramienta lo detecta y te indica qué primitiva está disponible.


Cómo funciona la cadena

El exploit se construye en capas; cada una es un puente hacia la siguiente.

  1. Desync (CVE-2026-63030). Una solicitud por lotes anida un segundo lote. Una sub-solicitud lleva una ruta deliberadamente malformada (http://:, que wp_parse_url() rechaza). En 6.9.0+ el fallo de análisis hace que las tablas de manejadores y de validación se desvíen una entrada, de modo que la siguiente sub-solicitud se ejecuta bajo un manejador contra el que nunca fue validada: la colección pública de posts.

  2. Inyección (CVE-2026-60137). Esa llamada mal despachada llega a WP_Query con un author__not_in controlado por el atacante. Un UNION ALL SELECT ahí no lee filas — las fabrica, lo que nos permite forjar posts arbitrarios en el resultado de la consulta.

  3. Puente SQL → escritura. Los posts fabricados llevan marcado [embed]. WordPress los resuelve fielmente y los almacena en caché como filas reales de oembed_cache post-meta — convirtiendo una inyección de solo lectura en una primitiva de escritura arbitraria.

  4. Escalada de privilegios. Usando ese puente de escritura forjamos (a) un changeset del personalizador con autoría del administrador real y (b) un post request autorreferencial. Juntos fuerzan a WordPress a re-ejecutar su propio pipeline de solicitudes como ese administrador — una ventana lo bastante larga para que una llamada encolada a cree un nuevo administrador.

Oráculos de extracción

Para el lado de lectura (--dump, resolución de prefijo, IDs en caché) la herramienta selecciona automáticamente el oráculo más rápido que funcione y se detiene en el primer acierto:

  1. union — UNION en banda: el post_title de la fila forjada lleva |||HEX(value)|||, que se refleja textualmente en el cuerpo de la respuesta de /wp/v2/posts. Lee un valor completo (de cualquier longitud) en una sola solicitud. Si UNION se refleja, los oráculos booleanos nunca se prueban.

  2. bool — oráculo booleano X-WP-Total: el encabezado X-WP-Total de la sub-respuesta confundida es count>0 para verdadero / 0 para falso. Un bit por solicitud (bisección).

  3. time — SLEEP() basado en tiempo: el recurso de respaldo cuando el cuerpo se elimina y la respuesta es un 500 (p. ej. un fatal posterior al despacho de un mu-plugin de caché). Funciona incluso en objetivos que fallan en cada llamada REST.

--dump usa GROUP_CONCAT para extraer todo el conjunto de credenciales de una sola vez cuando UNION está disponible.


Instalación

Ninguna. Solo biblioteca estándar de Python 3.7+ — sin pip install.

root@kitploit:~
chmod +x wp2shell.py

Uso

root@kitploit:~
# 1. Is it vulnerable? (no injection, no writes, no account created)
./wp2shell.py http://target --check

# 2. Read-only credential dump — FIRST administrator + option secrets
./wp2shell.py http://target --dump

#    …every administrator
./wp2shell.py http://target --dump all

# 3. Full RCE — create a temp admin, run a command, clean up
./wp2shell.py http://target --exec "id; uname -a"

Reconocimiento de solo lectura (sin crear administrador, evita 2FA)

root@kitploit:~
./wp2shell.py http://target --user-list          # full user table (logins/emails/roles)
./wp2shell.py http://target --content            # every post type at status=any (private/draft)
./wp2shell.py http://target --content full        #   …including each item's raw body

Escaneo de muchos hosts

root@kitploit:~
./wp2shell.py -f targets.txt --check --target-threads 8

Opciones

Evasión de WAF / endurecimiento


Notas sobre la salida

  • Hashes de contraseña ($wp$2y$… / $P$… / $2y$…) van directamente a hashcat (-m 3200 para phpass, o el modo bcrypt de WP). WordPress 6.8+ usa bcrypt $wp$….
  • --dump por defecto solo al primer administrador. Usa --dump all para la lista completa de admins.
  • Objetivos con error 500 / caídas: si un fatal posterior al despacho (p. ej. un mu-plugin de caché estilo Pantheon) convierte cada respuesta REST en un 500, la creación de admin no funcionará, pero las lecturas sí — cambia a --oracle time --dump para recuperar hashes.

Por qué importa la limpieza

La ruta --exec está diseñada para no dejar nada atrás: el administrador temporal, su usermeta, las filas oembed_cache fabricadas y la webshell subida se eliminan antes de que la herramienta termine. No hay flag --keep — un operador nunca debe dejar una cuenta de administrador activa creada por un atacante en el sistema de un cliente.


Archivos

  • wp2shell.py — el exploit (un solo archivo, solo stdlib).

Créditos

El descubrimiento de las vulnerabilidades, su divulgación y el informe original de "wp2shell" pertenecen al equipo de investigación Searchlight Cyber / Assetnote:

  • CVE-2026-63030 — desync por confusión de rutas en REST /batch/v1
  • CVE-2026-60137 — inyección SQL en WP_Query author__not_in

Este repositorio es una implementación independiente de prueba de concepto de la cadena de explotación que ellos divulgaron; no reivindica el descubrimiento de las vulnerabilidades subyacentes. Si alguna atribución es incompleta o incorrecta, abre un issue y se corregirá.

Referencias

  • Searchlight Cyber / Assetnote — wp2shell: Pre-Authentication RCE in WordPress core https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core/
  • Lanzamiento de WordPress 7.0.2 (parche) — https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
  • Avisos — GHSA-ff9f-jf42-662q, GHSA-fpp7-x2x2-2mjf

Descargo de responsabilidad

Esta es una prueba de concepto de investigación de seguridad para pruebas de penetración autorizadas y validación defensiva. Ejecutarla contra sistemas que no posees o para los que no tienes permiso por escrito es ilegal. El autor no acepta ninguna responsabilidad por el mal uso.

Descargar herramienta
POST /wp/v2/users
  • Shell. Inicia sesión como el nuevo administrador, sube un plugin, ejecuta el comando. La cuenta, su meta, las filas oembed y la webshell se limpian después — no queda ninguna huella persistente.

  • FlagPropósito
    url / -f FILEobjetivo único, o un archivo de objetivos (una URL por línea)
    --checksolo verificación de vulnerabilidad — sin inyección, escrituras o cuentas
    --dump [all]volcar el hash + secretos del primer admin; all = todos los admins
    --exec CMDcrear admin temporal → ejecutar CMD → limpiar
    --user-listlectura en banda elevada de la tabla de usuarios completa (sin login, evita 2FA)
    --content [full]lectura elevada de todos los tipos de post en status=any; full añade los cuerpos
    --oracle {auto,union,bool,time}forzar un oráculo de extracción (por defecto auto)
    --prefix PFXforzar el prefijo de tabla en lugar de resolverlo automáticamente
    --impersonate UIDsuplantar este id de usuario en lugar del primer admin
    --threads Nsondas de extracción concurrentes dentro de un objetivo (por defecto 5)
    --target-threads Nescanear N objetivos de -f concurrentemente (por defecto 1)
    --proxy URLenrutar a través de un proxy (p. ej. Burp http://127.0.0.1:8080)
    --timeout SECtiempo de espera por solicitud (por defecto 30)
    --verbose / -vvolcar sub-respuestas de lote crudas (depuración)
    FlagPropósito
    --formenviar el lote como multipart/form-data (URL limpia, sin ?rest_route=)
    --permalink [PREFIX]enrutar vía /<PREFIX>/batch/v1 (por defecto wp-json); mantiene el payload fuera de la URL y fuera de $_POST. Consejo: --permalink index.php/wp-json llega a REST vía PATH_INFO, evadiendo reglas ancladas en /wp-json
    --dummy Nanteponer N bytes de basura en el cuerpo para desbordar el búfer de inspección de un WAF
    --donor {widgets,categories,tags}cambiar la ruta donante de la confusión si una da 500 (por defecto widgets)
    --per-page Nforjar per_page (-1 o un positivo grande devuelven todas las filas; usa un positivo grande si el objetivo da 500 con -1)
    --users-route PATHvariante de mayúsculas/consulta para la llamada de creación de usuario (/wp/v2/Users, …?_=1)
    --primer PATHruta de desync malformada alternativa si un WAF identifica la http://: por defecto
    --user-agent UAfijar el UA (por defecto: un UA de navegador realista aleatorio por ejecución)
    --embed-base URLsobrescribir la base de la URL oembed (evitar un loopback de auto-embed)