wp2shell: Ejecución de código remoto (RCE) en WordPress sin autenticación y cómo bloquearla
wp2shell es una cadena de ejecución remota de código sin autenticación en el núcleo de WordPress. Combina una inyección SQL (CVE-2026-60137) con un fallo de confusión de rutas por lotes en REST (CVE-2026-63030) y no requiere iniciar sesión ni utilizar ningún plugin de terceros. Los sitios que ejecutan ReportedIP 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 ya este patrón de solicitud.
Aplica primero el parche al núcleo de WordPress para 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 gratuita. La guía del complemento contiene los pasos de instalación y actualización, y la última versión se encuentra en la página de lanzamientos de GitHub.
Los dos errores y por qué es importante la cadena
Ninguno de los dos errores es grave por sí solo. Sin embargo, al encadenarse, permiten que una solicitud anónima llegue hasta la ejecución del código.
- CVE-2026-60137 (inyección SQL, CVSS 9,1). El REST
author_excludeEl parámetro se asigna alauthor__not_inconsulta var enWP_Queryy se inserta como cadena en unpost_author NOT IN (…)cláusula. Un valor como0) UNION SELECT …-- -cierra elIN()enumera y añade código SQL arbitrario. Por sí sola, solo se puede acceder a ella mediante una solicitud de recopilación autenticada. - CVE-2026-63030 (confusión de rutas por lotes en REST). En
/wp-json/batch/v1, una subpetición cuya ruta da errorwp_parse_url()se añade al archivo interno$validationincluir en la lista, pero no$matches. Las dos matrices se desincronizan y una sub-solicitud validada se envía a través del controlador de la siguiente sub-solicitud. Esto permite que unaGET /wp/v2/posts/999999transportandoauthor_excludeformar parte de la colección «Posts»get_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 (de modo que la fila se mantiene como una entrada falsa), falsifica una columna completa de 23 wp_posts fila con UNION SELECT y transporta el valor filtrado en el reflejado post_title. A partir de ahí, la cadena genera tres oembed_cache publica entradas, recupera sus ID mediante la misma inyección, transforma esos ID en un conjunto de cambios del personalizador y en un grafo de elementos del menú de navegación, y crea un nuevo administrador a través de la ruta REST de usuario. Una vez que se dispone de un administrador, la subida de un plugin o un tema permite la ejecución de código. No se necesitan credenciales en ningún paso.
Cómo lo bloquea ReportedIP
Los hooks del cortafuegos de Hive init con prioridad 1, y la ruta opcional sin cita previa se realiza aún antes a través de un auto_prepend_file de seguridad, antes de que se inicie WordPress. En el caso de una solicitud no autenticada, comprueba 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, comprueba el cuerpo tanto en formato sin procesar como decodificado en URL, por lo que una carga útil codificada en porcentaje dentro de un lote JSON (SLEEP%283%29 en lugar de SLEEP() es visible para las mismas firmas. El descripción del cortafuegos trata el tema del motor con mayor profundidad.
La ruta de creación del administrador depende de UNION SELECT, que la versión gratuita waf_sqli_union Regla ya bloqueada antes de esta versión. La versión 2.1.25 añade dos reglas estructurales que no dependen de que las palabras clave 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-Nivel-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 sincronización de las reglas. 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 gratuito como en el Professional, y un corpus de falsos positivos 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 a la versión 2.1.25 desde la sección «Plugins», o haz clic en «Buscar actualizaciones» para descargarlo al instante. Los sitios gratuitos 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 la opción «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 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-Nivel-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 presentan esas características, y el corpus de falsos positivos lo ha confirmado.
Los días cercanos a la divulgación aparecen reflejados en nuestra telemetría: las pruebas de los puntos finales REST por lotes aumentaron a mediados de julio. El Informe de ataques a WordPress correspondiente al periodo de mayo a julio de 2026 sitúa a wp2shell en contexto junto con otros 1,69 millones de ataques, y el centro de Informes de amenazas realiza un seguimiento de los datos cada trimestre.