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 — wp2shell (CVE-2026-63030 & CVE-2026-60137) - cadena RCE completa | Kitploit
Herramientas/GitHubGitHub/icex0/wp2shell-poc
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónComando y ControlAutenticaciónRed TeamingDesarrollo de Payloads
GitHubicex0/wp2shell-poc

wp2shell-poc

wp2shell (CVE-2026-63030 & CVE-2026-60137) - cadena RCE completa

Ver Repositorio
737168hace 9 díasRevisado por Kitploit

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

Prueba de concepto independiente para la inyección SQL por confusión de rutas en el lote REST de WordPress sin autenticación, asociada al aviso wp2shell de Searchlight Cyber.

Este repositorio no es el verificador oficial de Searchlight Cyber. check confirma la ruta del SQLi, read demuestra la lectura de la base de datos, y shell abre un shell de comandos respaldado por un plugin, ya sea con credenciales de administrador proporcionadas o ejercitando primero el puente de SQLi a admin.

wp2shell — el comando shell ejercitando el puente de SQLi a admin sin autenticación

Versiones afectadas

El aviso de Searchlight Cyber enumera estos rangos de exposición a RCE de wp2shell:

Rango de versionesEstado
<= 6.8.5No afectada
6.9.0 – 6.9.4Afectada
7.0.0 – 7.0.1Afectada

Cómo funciona

El endpoint de lote REST (/batch/v1) no requiere autenticación y ejecuta varias sub-solicitudes en una sola llamada, confiando en que cada sub-solicitud sea validada y verificada en cuanto a permisos por sí misma.

serve_batch_request_v1() construye dos arrays paralelos — $matches (el manejador coincidente por sub-solicitud) y $validation (el resultado de validación por sub-solicitud) — y luego indexa ambos por el mismo offset al despachar. Una sub-solicitud cuya ruta falla en wp_parse_url() se añade a $validation pero no a $matches, de modo que los arrays se desincronizan y una sub-solicitud se despacha bajo el manejador de una sub-solicitud diferente. Eso es la confusión de rutas.

El PoC anida la primitiva dos veces:

  1. Una solicitud POST /wp/v2/posts que lleva un cuerpo requests se despacha bajo el propio manejador de lote. Al haber sido validada como solicitud de posts, su lista requests nunca se comprueba contra el esquema del lote, por lo que sus sub-solicitudes pueden usar GET — la lista de métodos permitidos se omite.
  2. Dentro de ese lote interno, una solicitud de ruta de ítem GET /wp/v2/posts/999999 lleva parámetros de consulta de la colección de posts como author_exclude, orderby y per_page. El ID 999999 no necesita existir; es solo un ID de post improbable usado para coincidir con la ruta de ítem, cuyo esquema no valida esos parámetros exclusivos de colección. La desincronización entonces despacha la misma solicitud bajo get_items() de posts, donde author_exclude se asigna a la variable de consulta author__not_in de , que la build vulnerable interpola en SQL como cadena.

El resultado es una inyección SQL ciega basada en booleano y en tiempo, alcanzable sin autenticación. Este PoC también incluye la primitiva de post falso por UNION utilizada en la cadena de SQLi a admin.

La ruta de RCE implementada aquí es:

  1. Usar filas falsas de wp_posts por UNION para renderizar contenido controlado por el atacante a través de una colección de posts. El puente de renderizado usa la fuente de ruta de ítem /wp/v2/posts/999999 — la misma ruta que usa la lectura SQLi para alcanzar get_items().
  2. Usar ese renderizado para hacer que WordPress cree posts reales de caché oEmbed.
  3. Recuperar esos IDs reales de posts de caché mediante el SQLi.
  4. En una solicitud de lote envenenada, reconvertir esos IDs en un changeset del personalizador, un elemento de navegación y una forma de gancho de solicitud.
  5. Dejar que la misma solicitud alcance POST /wp/v2/users, creando un administrador generado.
  6. Iniciar sesión como ese administrador generado y usar el comportamiento de carga de plugins para ejecutar un comando.

Los pasos 1–5 son sin autenticación; el paso de ejecución de comandos es una carga de plugin autenticada como administrador.

Requisitos

Python 3.8+ y la biblioteca estándar. Sin dependencias de terceros.

Uso

Ejecútalo desde el directorio del repositorio:

root@kitploit:~
./wp2shell.py <command> <url> [options]

O pip install . para obtener un comando wp2shell en tu PATH.

check — comprobación de vulnerabilidad no destructiva

Primero imprime marcadores pasivos de WordPress y pistas públicas de versión, y luego envía una sonda benigna de marcadores de lote. Una implementación de lote vulnerable devuelve HTTP 207 con el patrón de marcadores de confusión de rutas parse_path_failed, block_cannot_read y rest_batch_not_allowed.

La sonda de marcadores se basa en la corrección del núcleo de WordPress. La solicitud malformada /// crea parse_path_failed; una solicitud /wp/v2/posts actúa como espaciador permitido en el lote; la ruta /wp/v2/block-renderer/... no está permitida en el lote pero devuelve block_cannot_read si su manejador se alcanza de forma anónima; /batch/v1 da rest_batch_not_allowed. En builds vulnerables, el error de parseo desincroniza los arrays del manejador de lote, por lo que la solicitud espaciadora se despacha bajo el manejador de block-renderer. Las builds corregidas mantienen los arrays alineados, por lo que este patrón exacto de los tres no debería aparecer para la sonda elaborada.

Por defecto, check se detiene ahí y no envía un payload de SQLi. Usa --confirm-sqli cuando también quieras una confirmación activa de SQLi. La confirmación intenta primero la primitiva de lectura por UNION y recurre a sondas de temporización emparejadas si la reflexión por UNION no está disponible.

Las señales son independientes: una pista de versión es solo una pista, el patrón de marcadores muestra confusión de rutas, y --confirm-sqli muestra que un payload llegó a la base de datos. Un WAF puede bloquear el payload, por lo que una confirmación fallida no demuestra que el fallo esté ausente.

root@kitploit:~
./wp2shell.py check http://target
./wp2shell.py check targets.txt          # scan every URL in the file

read — extraer datos mediante inyección SQL

root@kitploit:~
./wp2shell.py read http://target                      # server fingerprint
./wp2shell.py read http://target --preset users       # user logins and password hashes
./wp2shell.py read http://target --query "SELECT @@version"

Por defecto la extracción usa --technique auto, que prueba los métodos disponibles en este orden:

  1. union — forja una fila falsa de WP_Post mediante UNION y lee de vuelta su título desde la respuesta REST como ||HEX(value)||. El payload usa la misma ruta de origen /wp/v2/posts/999999 con orderby=none y per_page=500 para que la fila falsa sobreviva como un post renderizado. Una solicitud por valor.
  2. error — EXTRACTVALUE/UPDATEXML filtran ~15 bytes por solicitud, cuando el objetivo refleja errores de MySQL (p. ej. WP_DEBUG_DISPLAY activado).
  3. blind — búsqueda binaria booleana, ~8 solicitudes por carácter; lee la cabecera X-WP-Total de la colección de posts como señal de verdadero/falso y no necesita ningún valor reflejado.

Fuerza uno con --technique union|error|blind. Estas rutas de lectura no escriben filas en la base de datos.

shell — ejecución de comandos

Con --user y --password, shell inicia sesión con las credenciales de administrador proporcionadas y usa el comportamiento de carga de plugins de WordPress.

Sin credenciales, shell primero ejecuta el puente de SQLi a admin sin autenticación, inicia sesión como el administrador generado y luego carga el shell del plugin.

root@kitploit:~
./wp2shell.py shell http://target --user admin --password '<recovered>' --cmd id
./wp2shell.py shell http://target --user admin --password '<recovered>' -i   # interactive shell
./wp2shell.py shell http://target --cmd id                                   # pre-auth bridge
./wp2shell.py shell http://target -i                                         # pre-auth interactive

shell carga un webshell de plugin (protegido tras una ruta aleatoria y un token por ejecución) e imprime su ruta. El webshell cargado se elimina automáticamente. Cuando el puente sin autenticación crea un administrador, esa cuenta generada se elimina automáticamente después de que termine la sesión de shell.

Opciones

Mitigación

Actualiza a WordPress 7.0.2, o a 6.9.5 si el sitio está en la rama 6.9. Hasta entonces, bloquea tanto /wp-json/batch/v1 como el parámetro de consulta rest_route=/batch/v1 en el borde, o exige autenticación para el endpoint de lote mediante el filtro rest_pre_dispatch.

Aviso legal

Solo para pruebas de seguridad autorizadas. Úsalo exclusivamente contra sistemas que poseas o para los que tengas permiso explícito por escrito para realizar pruebas. No se proporciona garantía alguna y no se acepta responsabilidad por el mal uso.

Referencias

  • Anuncio del lanzamiento de WordPress 7.0.2 — https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
  • Aviso wp2shell de Searchlight Cyber — https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core/
  • sergiointel/wp2shell-poc: puente de SQLi a admin — https://github.com/sergiointel/wp2shell-poc
Descargar herramienta
WP_Query
OpciónAplica aDescripción
--proxy URLallEnruta el tráfico a través de un proxy HTTP (por ejemplo, Burp).
--timeout NallTiempo de espera de la solicitud en segundos.
--sleep NcheckRetardo usado por el respaldo de temporización para --confirm-sqli.
--samples NcheckPares de temporización usados por el respaldo de temporización para --confirm-sqli.
--confirm-sqlicheckEnvía también un payload activo de confirmación de SQLi.
--presetreadfingerprint o users.
--techniquereadauto (por defecto), union (en banda, forja un post falso), error (en banda, necesita errores visibles de BD), o blind.
--queryreadUna expresión SQL escalar para leer.
--prefixreadPrefijo de tabla de base de datos (por defecto wp_).
--max-length NreadMáximo de caracteres leídos por valor (por defecto 128).
--user / --passwordshellCredenciales de administrador opcionales; omite ambas para usar el puente sin autenticación.
--cmdshellComando a ejecutar (omítelo al usar -i).
-i / --interactiveshellAbre un shell interactivo después del despliegue.