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-32475 — Prueba de concepto del exploit para CVE-2026-32475, una subida de archivos arbitraria sin autenticación en Elementor Pro que conduce a la ejecución remota de código. Incluye descubrimiento automatizado, subida y ejecución de comandos con limpieza. | Kitploit
Herramientas/GitHubGitHub/sahmsec/cve-2026-32475
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPruebas de PenetraciónAprendizaje y EducaciónRed Teaming
GitHubsahmsec/cve-2026-32475

CVE-2026-32475

Prueba de concepto del exploit para CVE-2026-32475, una subida de archivos arbitraria sin autenticación en Elementor Pro que conduce a la ejecución remota de código. Incluye descubrimiento automatizado, subida y ejecución de comandos con limpieza.

Ver Repositorio
120hace 1 mesAún no revisado

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 →
Compartir

CVE-2026-32475 — Elementor Pro ≤ 4.2.1 Carga Arbitraria de Archivos sin Autenticación → RCE

PoC para CVE-2026-32475 (CVSS 9.0 Crítico, CWE-434): una carga arbitraria de archivos sin autenticación en el módulo de Formularios de Elementor Pro que conduce a la ejecución remota de código. Corregido en Elementor Pro 4.2.2 (2026-08-19). Reportado por Tin Pham (TF1T) a través del programa Bug Bounty de Patchstack.

  ███████╗  █████╗  ██╗  ██╗ ███╗   ███╗ ███████╗ ███████╗  ██████╗
  ██╔════╝ ██╔══██╗ ██║  ██║ ████╗ ████║ ██╔════╝ ██╔════╝ ██╔════╝
  ███████╗ ███████║ ███████║ ██╔████╔██║ ███████╗ █████╗   ██║
  ╚════██║ ██╔══██║ ██╔══██║ ██║╚██╔╝██║ ╚════██║ ██╔══╝   ██║
  ███████║ ██║  ██║ ██║  ██║ ██║ ╚═╝ ██║ ███████║ ███████╗ ╚██████╗
  ╚══════╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═╝     ╚═╝ ╚══════╝ ╚══════╝  ╚═════╝

⚠️ Aviso legal

Esta prueba de concepto se proporciona únicamente para investigación de seguridad autorizada, educación y pruebas defensivas.

  • Debe ser propietario del sistema objetivo o contar con permiso explícito por escrito del propietario del sistema antes de ejecutar esta herramienta contra él.
  • El acceso no autorizado a sistemas informáticos es ilegal en la mayoría de las jurisdicciones (por ejemplo, la Computer Fraud and Abuse Act en EE. UU., la Computer Misuse Act en el Reino Unido y leyes similares en todo el mundo) y puede conllevar sanciones penales y civiles.
  • Los autores y colaboradores no asumen ninguna responsabilidad por el mal uso, daños o consecuencias legales derivados del uso de este código.
  • Al utilizar este software, acepta usarlo de manera responsable y en cumplimiento de todas las leyes aplicables.

En qué consiste la vulnerabilidad

El campo de Carga de Archivos de los formularios de Elementor Pro procesa las entradas subidas en dos bucles separados con semánticas diferentes (modules/forms/fields/upload.php):

// validation()
foreach ( $files[$id] as $index => $file ) {
    if ( ! $field['required'] && UPLOAD_ERR_NO_FILE === $file['error'] ) {
        return;                    // <-- aborta TODO el método
    }
    // is_file_type_valid() ...    // nunca se alcanza para la entrada #2
}

// process_field()
foreach ( $files[$id] as $index => $file ) {
    if ( UPLOAD_ERR_NO_FILE === $file['error'] ) {
        continue;                  // <-- omite solo ESTA entrada
    }
    $filename = uniqid() . '.' . $file_extension;   // extensión controlada por el atacante
    move_uploaded_file( $file['tmp_name'], $new_file );
}

Al enviar dos partes de archivo para el mismo campo de carga — una primera parte vacía (filename="" → UPLOAD_ERR_NO_FILE) seguida de la carga útil .php — hace que validation() retorne antes de que la lista de extensiones bloqueadas vea la carga útil, mientras que process_field() aún la mueve a wp-content/uploads/elementor/forms/<uniqid()>.php, un directorio web público. Solicitar esa URL directamente = ejecución remota de código.

La carga se gestiona mediante POST /wp-admin/admin-ajax.php (action=elementor_pro_forms_send_form) sin autenticación y sin nonce. El post_id, form_id y el nombre del campo de carga son visibles en el HTML de la página pública, por lo que todo el ataque no requiere autenticación.

Requisitos

Objetivo:

  • Elementor Pro ≤ 4.2.1 (todas las versiones anteriores están afectadas)
  • Al menos una página publicada con un widget de Formulario que contenga un campo de Carga de Archivos
  • El campo de carga no debe estar marcado como Obligatorio (el estado predeterminado)
  • Sin CAPTCHA en el formulario (reCAPTCHA/turnstile bloquea el envío sin autenticación)
  • El directorio de cargas debe ejecutar PHP (predeterminado en la mayoría de los alojamientos Apache/cPanel; bloqueado en algunas configuraciones endurecidas de nginx)

Atacante:

  • Python 3.9+ (solo biblioteca estándar — sin dependencias)
  • Acceso de red al objetivo

Uso

Objetivo único (descubre automáticamente la página del formulario mediante sitemap/página de inicio):

python script.py --url https://target.example --command "id; hostname; uname -a" --cleanup

Página de formulario explícita:

python script.py --url https://target.example --page-url https://target.example/contact/ --cleanup

Modo por lotes (sites.txt: un sitio por línea — base_url o base_url page_url):

python script.py --list sites.txt --command "id" --cleanup --out results.json

Formato de lista JSON:

[{"url": "https://a.example"}, {"url": "https://b.example", "page_url": "https://b.example/jobs/"}]

Ejecutar un comando en una shell ya subida:

python script.py --url https://target.example --shell-url https://target.example/wp-content/uploads/elementor/forms/<name>.php --command "id"

Opciones clave

FlagPredeterminadoSignificado
--url-URL base de un solo objetivo
--list-archivo de lista para modo por lotes
--page-url--urlpágina que contiene el formulario
--commandid; hostname; uname -acomando a ejecutar a través de la shell
--cleanupdesactivadoautoeliminar la webshell después de las pruebas
--field k=v-sobrescribir un campo de formulario autocompletado (repetible)
--tail0.3segundos antes del tiempo estimado de carga para el barrido fino
--step-fine1paso en microsegundos del barrido fino
--full-seconddesactivadofuerza bruta del segundo completo de uniqid (anula la desviación del reloj)
--attempts1intentos de carga+barrido (nombre de archivo aleatorio nuevo cada vez)
--max-probes600000presupuesto de solicitudes de barrido por intento
--workers50hilos de barrido en paralelo
--insecuredesactivadoignorar errores TLS (objetivos con certificados autofirmados)
--out file.json-escribir el informe como JSON

Cómo funciona la herramienta

  1. Descubrimiento — obtiene la página objetivo (o rastrea el sitemap y los enlaces de la página de inicio, máx. 20 páginas) para encontrar un formulario con un campo de Carga de Archivos.
  2. Extracción — extrae post_id, form_id, el nombre del campo de carga y todos los demás campos del formulario; autocompleta todos los campos con valores plausibles para que los campos obligatorios pasen la validación (sobrescribir con --field).
  3. Carga — envía el POST multiparte de dos partes a admin-ajax.php. Nota: success:false con un objeto errors vacío aún se trata como cargado, porque la acción de Email predeterminada lanza después del movimiento del archivo cuando wp_mail() falla. Solo el rechazo del propio campo de carga (file type is not allowed) cuenta como bloqueado.
  4. Recuperación del nombre de archivo — uniqid() = 8 hex segundos + 5 hex microsegundos. Los segundos provienen del encabezado Date de la respuesta; la fracción de subsegundo se estima a partir de (t1 - date_epoch) % 1 (preciso cuando los relojes del atacante y del servidor están cercanos). Un sondeo keep-alive (~30x más rápido que una solicitud por conexión) barre la ventana de movimiento con resolución de microsegundos; --full-second fuerza bruta el segundo completo cuando los relojes están desviados.
  5. Ejecución — GET <shell>?c=<command> ejecuta el comando; --cleanup elimina la shell mediante ?x=1.

Estados de resultado

EstadoSignificado
vulnerableshell subida y comando ejecutado — parchear ahora
blockedcampo de carga rechazado (parcheado 4.2.2+, campo obligatorio, WAF, captcha)
uploaded_no_execarchivo colocado pero nombre no recuperado (reintentar con --full-second)
no_formno se encontró ningún formulario vulnerable en el objetivo
errorerror de conexión/red

Reproducción en laboratorio

Descargar herramienta