Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-97332-PoC — PoC independiente y laboratorio reproducible para CVE-2026-97332 — divulgación no autenticada de archivos privados en User Private Files < 2.2.0 en WordPress Multisite. | Kitploit
Herramientas/GitHubGitHub/kolya080808/cve-2026-97332-poc
Herramientas DefensivasAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónSeguridad WebPruebas de PenetraciónLabs y Práctica

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
GitHubkolya080808/cve-2026-97332-poc

CVE-2026-97332-PoC

PoC independiente y laboratorio reproducible para CVE-2026-97332 — divulgación no autenticada de archivos privados en User Private Files < 2.2.0 en WordPress Multisite.

Ver RepositorioSitio web
41hace 1 mesAún no revisado
Compartir

CVE-2026-97332 — Divulgación de archivos privados sin autenticación en WordPress User Private Files < 2.2.0 (Multisite)

CVE Severity Affected Fixed Requires PoC Ethics

[!NOTE] Este repositorio es una reproducción independiente y Prueba de Concepto para CVE-2026-97332.

Descubrimiento original de la vulnerabilidad: Akshat Parikh (SN1PER). CNA / aviso: WPScan. PoC y reproducción independientes: Kolya080808.

Divulgación sin autenticación de archivos privados de otros usuarios en el plugin de WordPress User Private Files (slug de wp.org user-private-files) anterior a 2.2.0 en instalaciones multisite. El plugin almacena los documentos privados de cada usuario dentro del árbol de uploads sin protección y los protege con una única RewriteRule añadida al .htaccess raíz, que enruta las solicitudes de archivos a través de una comprobación de acceso en PHP. En una red multisite esa regla nunca se alcanza: un simple GET — sin cookies, sin cabeceras, sin inicio de sesión — devuelve el archivo privado de otro usuario como contenido estático. Control de acceso roto, CWE-284, CVSS 3.1 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N).

Este repositorio contiene un exploit funcional en Python sin dependencias y un laboratorio docker de dos contenedores (vulnerable 2.1.9 y parcheado 2.2.0, ambos WordPress multisite) para reproducir el ataque de extremo a extremo.

[!CAUTION] Este material se proporciona únicamente para investigación de seguridad autorizada y pruebas defensivas (véase el descargo de responsabilidad al final). Atacar sistemas que no posee o no opera sin permiso por escrito es ilegal.

La vulnerabilidad

El plugin mantiene los archivos privados como adjuntos ordinarios en un subdirectorio de uploads plano por sitio — wp-content/uploads/upf-docs/ (sitio principal) y wp-content/uploads/sites/N/upf-docs/ (subsitio N) — sin aislamiento por usuario. El control de acceso no está en el directorio; reside en PHP (dl-file.php: 403 para usuarios anónimos, luego una comprobación de autor/lista de permitidos) y solo se alcanza a través de una reescritura emitida en la activación del plugin en el .htaccess raíz:

# appended by 2.1.9 (upvf_actdeact.php), AFTER the WordPress block
RewriteRule ^wp-content/uploads/upf-docs/(.*)$ https://site/?file=$1 [QSA,L]

En multisite esto nunca se dispara, por dos razones independientes:

  1. El .htaccess de la red cortocircuita primero los archivos existentes. WordPress multisite escribe su propio conjunto de reglas en el .htaccess raíz:

    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    

    Una solicitud que se asigna a un archivo físicamente existente termina la reescritura justo ahí — Apache lo sirve como contenido estático, y mod_rewrite nunca llega al bloque del plugin al final del archivo. (WordPress de sitio único usa condiciones negativas !-f/!-d, por lo que el mismo plugin sí funciona allí.) Esto ya expone archivos del sitio principal de la red.

  2. Las rutas de los subsitios no coinciden en absoluto con el patrón. En multisitio cada sitio tiene sus propias cargas — wp-content/uploads/sites/N/…, además del prefijo de URL /siteN/ en redes de subdirectorio — mientras que la regla está codificada de forma fija a ^wp-content/uploads/upf-docs/ desde la URL base del sitio principal. Incluso después de que la reescritura interna de la red elimine el prefijo /siteN/, el segmento sites/N/ sigue sin coincidir.

Así que para cualquier red multisitio (tanto de subdirectorio como de subdominio) un atacante no autenticado obtiene archivos privados directamente:

GET /wp-content/uploads/upf-docs/victim.pdf HTTP/1.1            (main site)
GET /site2/wp-content/uploads/sites/2/upf-docs/victim.pdf HTTP/1.1  (subsite)

La respuesta es 200 con el cuerpo del archivo — servido por Apache directamente desde uploads/, la comprobación de acceso del plugin nunca se ejecuta.

Los nombres de archivo son predecibles

Nada en la URL es secreto. El plugin construye los nombres a partir del id de usuario numérico del propietario y el segundo unix de la subida:

Generador (2.1.9)Nombre en disco
UI moderna, inc/functions-file.php:73-77usr{ID}_{unixtime}_{original}
plantilla clásica, inc/classic-user-functions.phpuser_{ID}_doc_{unixtime}.{ext}

Los ids de usuario en una red multisitio son enteros secuenciales pequeños de una única tabla wp_users compartida, por lo que un atacante solo necesita una hora de subida aproximada (una ventana de ±2 minutos son ≈240 peticiones) y o bien el nombre de archivo original o solo su extensión. Los sufijos de colisión (-1, -2) existen pero son raros.

La corrección (2.2.0)

La versión 2.2.0 reemplazó la reescritura del archivo raíz por un .htaccess a nivel de carpeta en upf-docs/ — RewriteRule ^(.*)$ {home}/?file=$1 [R=302,QSA,L], más Require all denied cuando mod_rewrite no está presente — recreado en cada admin_init (autorreparable, por subsitio). Una regla por directorio se activa para cualquier ruta física bajo upf-docs/ independientemente del prefijo de la URL, por lo que la petición GET directa ahora se convierte en un 302 hacia la comprobación de acceso y, para usuarios anónimos, en un 403. Los archivos no se mueven; solo cambia el mecanismo de intercepción. Esa distinción entre 302 y estático es también lo que el exploit usa como detector de comportamiento.

Versiones afectadas

  • User Private Files < 2.2.0 (verificado contra las fuentes 2.1.9; las etiquetas SVN 1.0.1–2.1.9 llevan el mismo diseño de reescritura raíz)
  • Solo despliegues multisitio (subdirectorio y subdominio). Las instalaciones de sitio único están protegidas por la regla raíz siempre que Apache lea .htaccess y el archivo fuera escribible en la activación (nginx necesita la reescritura manual del proveedor — véase el readme del plugin).
  • Referencia: aviso de WPScan d6a144b3-84e3-43eb-92d3-fd4505dd0e1c (publicado el 2026-10-02, investigador Akshat Parikh / SN1PER).

Cómo funciona el exploit

exploit.py es Python 3 puro de biblioteca estándar (http.client), no sigue redirecciones y no envía cookies:

Descargar herramienta