wp2shell: Ejecución de código RCE en WordPress sin autenticación y cómo bloquearla
wp2shell es una cadena de ejecución remota de código sin autenticación presente en el núcleo de WordPress. Combina una SQL Injection (CVE-2026-60137) con un fallo de confusión de rutas por lotes en REST (CVE-2026-63030) y no requiere Login ni utilizar ningún plugin de terceros. Los sitios que ejecutan ReportedIP Hive ya están protegidos: las reglas están activas en la configuración básica incluida y publicadas en la API del conjunto de reglas, por lo que las instalaciones gratuitas y sincronizadas bloquean este patrón de solicitud desde hoy mismo.
Aplica primero el parche al núcleo de WordPress para actualizarlo a la versión corregida. Así se elimina la causa principal. Un cortafuegos protege el sistema hasta que se actualicen todos los sitios de tu red y detecta las variantes, pero no sustituye al parche del núcleo. Si utilizas Hive, actualízalo también a la versión 2.1.25, ya que las dos nuevas reglas se incluyen en la versión básica Free. La guía del plugin contiene los pasos de instalación y actualización, y la última versión se encuentra en la página de GitHub Releases.
Los dos errores y por qué es importante la cadena
Ninguno de los dos errores es grave por sí solo. Pero, al encadenarse, permiten que una solicitud anónima llegue hasta la ejecución del código.
- CVE-2026-60137 (SQL Injection, CVSS 9,1). El parámetro
author_excludese asigna a laauthor__not_invariable de consulta enWP_Queryy se interpola como una cadena en unapost_author NOT IN (…)cláusula. Un valor como0) UNION SELECT …-- -cierra laIN()lista y añade código SQL arbitrario. Por sí solo, solo es accesible desde una solicitud de colección autenticada. - CVE-2026-63030 (confusión en la ruta de lotes REST). En
/wp-json/batch/v1, una sub-solicitud cuya ruta fallawp_parse_url()se añade a la$validation, pero no a$matches. Las dos matrices se desincronizan, y una sub-solicitud validada se envía al controlador de la siguiente sub-solicitud. Esto permite que unaGET /wp/v2/posts/999999queauthor_excludese ejecute bajo la colección de entradasget_items(), donde se encuentra la variable de consulta inyectable, sin autenticación.
La escalada por lotes se aplica a WordPress 6.9 y versiones posteriores, que es donde se gestiona la confusión de rutas.
De un ataque SQLi ciego a un shell
Una vez que la inyección llega a una consulta sin dividir (el exploit utiliza orderby=none y per_page=500 por lo que la fila se mantiene como una publicación falsa), falsifica una fila completa de 23 columnas wp_posts con UNION SELECT y transporta el valor filtrado en la post_title. A partir de ahí, la cadena genera tres oembed_cache entradas, recupera sus ID mediante la misma inyección, reconvierte esos ID en un conjunto de cambios del personalizador y un grafo de elementos del menú de navegación, y crea un nuevo administrador a través de la ruta REST de usuario. Con un administrador en mano, la subida de un plugin o tema permite la ejecución de código. No se necesitan credenciales en ningún paso.
Cómo lo bloquea ReportedIP Hive
El cortafuegos de Hive se activa init con prioridad 1, y el complemento opcional se ejecuta aún antes a través de un auto_prepend_file guard, antes de que se inicie WordPress. En el caso de una solicitud no autenticada, inspecciona la URI, el agente de usuario y el cuerpo de la solicitud hasta un máximo de 64 KB. Desde la versión 2.1.25, inspecciona el cuerpo tanto en formato sin procesar como decodificado como URL, por lo que una Payload codificada en porcentaje dentro de un lote JSON (SLEEP%283%29 en lugar de SLEEP() es visible para las mismas firmas. El artículo sobre el cortafuegos trata el motor con mayor profundidad.
La ruta de creación del administrador depende de UNION SELECT, de cuál de las reglas gratuitas waf_sqli_union ya bloqueaba antes de esta versión. La versión 2.1.25 añade dos reglas estructurales que no dependen de que las palabras clave de SQL se mantengan en el cuerpo.
waf_rest_batch_desynccoincide con la clase de rutas de sub-solicitudes mal formadas que rechaza un analizador por lotes, como dos o más barras iniciales o un esquema con un host vacío. Se aplica al propio «desync primer», por lo que cambiar el token no permite eludirlo.waf_rest_batch_nestedcoincide con la única invariante que el ataque no puede eliminar, una sub-solicitud cuyo cuerpo es, a su vez, un lote ("body":{…"requests":[).
Ambas reglas son de «Paranoia Level-1» y ambas están protegidas contra el retroceso catastrófico. Se incluyen en la línea base sin conexión que lleva cada instalación, por lo que la protección se activa en el momento en que se actualiza el complemento, sin que sea necesaria la Rule Sync. En el caso de los sitios Professional, estas mismas reglas se publican en la API del conjunto de reglas firmado y se aplican en la siguiente sincronización. Frente a la prueba de concepto pública, las seis etapas fueron rechazadas tanto en el nivel Free como en el Professional, y un corpus de False Positives compuesto por llamadas por lotes normales, URL relativas al protocolo y URL absolutas no dio ningún resultado positivo.
¿Qué hacer ahora?
Actualiza el núcleo de WordPress en todos tus sitios. Actualiza ReportedIP Hive a la versión 2.1.25 desde la sección «Plugins», o haz clic en «Buscar actualizaciones» para descargarlo al instante. Los sitios Free y no sincronizados obtienen ambas reglas con la actualización del plugin. Los sitios Professional sincronizados las obtienen en la siguiente sincronización del conjunto de reglas, o al instante con «Sincronizar ahora». Si gestionas muchos sitios, aplica primero el parche del núcleo y deja que el cortafuegos mantenga la defensa mientras se propaga.
Preguntas frecuentes
¿Reemplaza ReportedIP Hive la actualización del núcleo de WordPress?
No. El parche del núcleo es la solución. Hive bloquea el patrón de solicitud antes de que llegue al código vulnerable, lo que protege el margen de aplicación del parche y detecta variantes, pero no elimina el error subyacente.
¿Están protegidos los sitios web gratuitos contra wp2shell?
Sí. Ambas nuevas reglas son de «Paranoia Level-1» y se incluyen en la configuración básica, por lo que se aplicarán a todos los planes tan pronto como el complemento se actualice a la versión 2.1.25.
¿Impedirán las nuevas normas las solicitudes REST por lotes legítimas?
No. Se centran en rutas de sub-solicitudes mal formadas y en un lote anidado dentro del cuerpo de una sub-solicitud. Las llamadas por lotes normales no producen esas estructuras, y el corpus de False Positives lo ha confirmado.
Los días cercanos a la divulgación aparecen reflejados en nuestra telemetría: las pruebas de los Endpoints REST por lotes aumentaron a mediados de julio. El WordPress Attack Report correspondiente al periodo de mayo a julio de 2026 sitúa a «wp2shell» en su contexto junto con otros 1,69 millones de ataques, y el centro de Threat Reports realiza un seguimiento de los datos cada trimestre.