Kit de herramientas LFI-to-RCE para WordPress CVE-2026-87902 con una cadena de explotación weaponizada (PEAR RCE, webshell, creación de admin, loot) y una versión SafeChecker no intrusiva y auditor de riesgos.

SOLO USO ÉTICO – PRUEBAS DE SEGURIDAD AUTORIZADAS
Este repositorio proporciona herramientas únicamente para profesionales de seguridad autorizados, equipos defensivos y pentesters.
El acceso no autorizado a sistemas informáticos es ilegal según la CFAA (EE. UU.), la Computer Misuse Act (Reino Unido), el TCK 243/244 (Turquía) y leyes similares en todo el mundo.
CVE‑2026‑87902 es una vulnerabilidad crítica de path traversal y local file inclusion (LFI) no autenticada en WordPress Core (versiones 4.7.0 hasta 7.1.1) que permite a un atacante no autenticado incluir archivos .php locales arbitrarios a través del parámetro de consulta pagename, y bajo condiciones específicas del servidor escalar a ejecución remota de código (RCE) encadenando el archivo PEAR pearcmd.php. Puntuación CVSS: 9.2 (Crítica). Divulgada por Robert Ressl a través del programa HackerOne de WordPress en julio de 2026. Parcheada en 7.1.2 el 22 de septiembre de 2026, con backports hasta 4.7.
La falla afecta a todas las versiones de WordPress desde 2016 — una década de versiones que pasaron la revisión de código sin ser detectadas. La causa raíz es una única llamada de validación faltante en una de las rutas de código más transitadas del CMS.
Resolución de plantilla no saneada – get_page_template() en wp-includes/template.php construye candidatos de plantilla a partir de la variable de consulta pagename. Una ruta de código vecina en la misma función aplica validate_file() para bloquear secuencias ../, pero la rama de $pagename no la llama. Cualquier traversal en pagename pasa sin ser verificado.
Bypass de traversal con doble codificación – WordPress aplica sanitize_title_for_query() a pagename, que reemplaza puntos literales (.) con guiones para prevenir traversal. Pero la función opera sobre entrada ya decodificada y no decodifica recursivamente. Un atacante envía %252e%252e%252f; el servidor web lo decodifica una vez a %2e%2e%2f; el saneador no ve puntos literales y lo deja pasar; luego get_page_template() llama a urldecode() de nuevo dentro de la función, produciendo ../.
Precondición del directorio del tema – El tema activo debe contener un directorio de nivel superior cuyo nombre comience con page- (por ejemplo, page-templates/). El nombre de archivo construido page-{pagename}.php entonces escapa la raíz del tema mediante el traversal. Temas predeterminados más antiguos (Twenty Twelve, Twenty Fourteen) y temas populares de terceros (Neve, Hestia, Sydney) incluyen este directorio. Los temas hijos que heredan de dichos padres también cumplen la precondición.
Sumidero LFI en locate_template() – La ruta candidata se pasa a locate_template(), que busca en los directorios del tema. Debido a que el traversal resuelve a un archivo fuera de esos directorios, y la función solo verifica file_exists(), cualquier archivo .php legible se incluye con privilegios completos del servidor web. Esto hace que el LFI sea incondicional en cualquier sitio sin parchear que cumpla la precondición del tema — incluyendo wp-config.php con sus credenciales de base de datos y sales de autenticación.
Escalada a RCE mediante PEAR pearcmd.php – PEAR se distribuye con muchas instalaciones de PHP. Su pearcmd.php normalmente es solo CLI, pero cuando register_argc_argv=On, PHP rellena $_SERVER['argv'] desde la cadena de consulta de la URL. El atacante incluye pearcmd.php mediante el LFI, pasa config-create como argumento y proporciona código PHP más una ruta de salida (/tmp/shell.php). PEAR escribe el código del atacante en disco; una segunda inclusión lo ejecuta.
Segunda ruta de explotación – Una solicitud que combina name (slug de la página de inicio), page_id (ID de la página de entradas), preview=true y un payload en pagename desvía WP_Query hacia su rama post_name, que nunca reescribe pagename a través de sanitize_title_for_query(). Esto permite puntos literales en el traversal. Requiere un tema sin single.php.
Requisitos de configuración del servidor – El RCE depende de dos condiciones comunes en despliegues reales: pearcmd.php presente/legible (frecuente en hosting compartido, cPanel, imágenes oficiales de PHP Docker), y register_argc_argv=On (predeterminado en PHP anterior a 8.5). PHP 8.5 cambió el valor predeterminado a Off. En un servidor moderno con PHP 8.5+ sin PEAR, la explotación se detiene en el LFI.
El parche – WordPress 7.1.2 añade dos capas de defensa: (a) la llamada faltante a validate_file() en la rama de pagename, y (b) una nueva función _wp_is_template_path_allowed() llamada por locate_template() para cada plantilla resuelta. La función rechaza rutas que contienen .., luego resuelve la ruta real mediante realpath() y verifica que se encuentre dentro de uno de los directorios de tema permitidos. Esta defensa en profundidad cierra el sumidero, no solo una ruta hacia él.
Explotación activa en el mundo real – Las primeras solicitudes maliciosas se observaron 5 horas después de la publicación del parche (17:44 UTC, 22 de septiembre de 2026). El tráfico se multiplicó por diez durante el día siguiente. Se observaron tres etapas: reconocimiento con config-show → detección de archivos del núcleo → armamentización con config-create. Los nombres de archivo de los payloads incluían wp-pear-rce-flag.php, poc87902.php, luci_*.php, zeta_*.php, escritos en /tmp y /var/tmp. IPs atacantes: 169.58.48.193, 169.58.48.195, 2001:df1:e8c0::106b.
Impacto – Ejecución de código con privilegios del servidor web. Toma de control total del sitio, robo de credenciales de wp-config.php, exfiltración de datos, instalación de webshell, creación de usuarios administradores, reverse shell, ataques a la cadena de suministro mediante plugins/temas modificados y movimiento lateral hacia servicios conectados. La puntuación CVSS 9.2 refleja impacto explotable por red, sin autenticación, alto en confidencialidad/integridad/disponibilidad. La alta complejidad del ataque refleja las precondiciones del tema y del servidor, pero en hosting compartido típico esas condiciones se cumplen con frecuencia.