Киберпреступники активно эксплуатируют неисправленную уязвимость в Magento Open Source и Adobe Commerce, которая позволяет им выполнять вредоносный код на серверах интернет-магазинов без авторизации. Об этом сообщила нидерландская компания Sansec, специализирующаяся на безопасности электронной коммерции, в своем уведомлении от 5 сентября.
Компания Sansec, обнаружившая данный дефект и назвавшая его StyleSmuggler, указала, что атаки начались 4 сентября. Организация подчеркнула важность немедленного распространения информации, поскольку магазины компрометируются в реальном времени.
На момент 6 сентября Adobe не опубликовала официальное уведомление, идентификатор CVE, патч или временное решение. Индекс бюллетеней безопасности Adobe Commerce не содержит записей после обновления от 11 августа.
Успешная атака предоставляет преступнику полный контроль над кодом на сервере магазина и устанавливает постоянный бэкдор. Согласно Sansec, уязвимости подвержены все текущие версии, включая 2.4.9. Компания подтвердила полную цепь неаутентифицированной эксплуатации на свежих установках Magento Open Source версий 2.4.7, 2.4.8 и 2.4.9.
Первая обнаруженная жертва использовала версию 2.4.6-p15 с применением июльского и августовского обновлений безопасности от Adobe 2026 года, что является последним доступным уровнем патчей для этой версии.
Sansec не опубликовала воспроизведение эксплуатации для Adobe Commerce или облачной версии, а сама Adobe не подтвердила, какие версии подвержены уязвимости. Количество скомпрометированных магазинов не раскрывается.
До выхода официального исправления от Adobe специалисты рекомендуют владельцам магазинов, не использующим продукт Shield компании Sansec, временно отключить GraphQL.
Компания Disrex Group, занимающаяся хостингом и разработкой для Magento, отметила, что головная архитектура и прогрессивные веб-приложения требуют GraphQL, в то время как классические и Hyvä витрины обычно в нём не нуждаются.
Следующий плановый выпуск безопасности Adobe запланирован на 8 сентября. Пока неизвестно, будет ли этот релиз содержать исправление для данной уязвимости.
Выводы специалистов Disrex представляют независимое свидетельство эксплуатации. В опубликованном на 5 сентября репозитории инцидентов компания сообщила об обработке двух скомпрометированных и одного атакованного, но не успешно взломанного магазина. Опубликованные веб-серверные правила основаны на трафике, перехваченном во время атаки на один из взломанных магазинов.
Согласно ответам на вопросы, оба магазина использовали Magento Open Source, а не Adobe Commerce, и размещались на собственной платформе хостинга RexHosting компании Disrex.
Первый магазин использовал Magento Open Source 2.4.8 и был клиентом Sansec Shield. Атака произошла 4 сентября в 23:10 UTC, за несколько часов до появления первых блокирующих правил от Sansec. На момент атаки Shield был активен и блокировал другие вредоносные атаки против магазина.
Второй магазин не был клиентом Shield и использовал Magento 2.4.7-p2, версию безопасности от августа 2024 года, отставшую на восемь уровней от текущей 2.4.7-p10. Первая атака произошла 5 сентября в 00:55 UTC. Именно этот магазин стал источником веб-серверных правил и анализа уязвимого кода для Disrex.
Оба магазина были скомпрометированы в течение примерно восьмичасового окна между первой зафиксированной эксплуатацией и моментом внедрения защиты. Компания отметила критически важный момент: статус применённых патчей был здесь неактуален.
Репозиторий Disrex содержит предупреждение о том, что документация была написана с помощью искусственного интеллекта во время активного инцидента в течение нескольких часов, не подлежала полной проверке, а правила Apache никогда не тестировались на боевом сервере.
Sansec описывает вредоносный компонент как фоновый процесс, маскирующийся под [kworker/u:8:0] (название потока ядра Linux), с двоичным файлом, установленным в ~/.local/share/.gvfsd/gvfsd-user в домашней директории пользователя сайта вместо корня веб-сервера, и записью cron для его перезапуска каждые пять минут.
Disrex описал двоичный файл как очищенную, статически скомпилированную программу на Rust размером примерно 1,9 МБ для архитектур x86-64 и arm64. Запись cron записывается прямо в файл очереди /var/spool/cron/crontabs/, скрывая операцию из системных логов.
На одном из магазинов одна и та же строка повторялась 1728 раз, и вредоносная программа восстанавливала её в течение одной секунды после удаления.
На одном из взломанных магазинов вредоносная программа вообще не создавала исходящих соединений. Она поддерживала 28 соединений с Redis-инстансом магазина на порту 6379 и считывала хранилище сеансов Magento. Ни один из двух захватов пакетов размером свыше 200 МБ не содержал единого пакета к хосту загрузки или адресу управления и контроля, указанному Sansec.
Disrex сообщила, что каждый магазин работал в изолированной учётной записи с одним владельцем сайта без прав sudo и без доступа к другим клиентам. Вредоносная программа работала с правами непривилегированного пользователя сайта и не могла получить доступ к другим ресурсам. Компания подтвердила отсутствие латерального движения и других скомпрометированных сайтов на её платформе.
Оба магазина были изолированы в тот же день в течение 11-14 часов после первого обнаружения. Не обнаружено свидетельств утечки данных, несанкционированных учётных записей администраторов, внедренных платёжных скиммеров и бэкдоров БД. Все сеансы были инвалидированы и начата ротация учётных данных.
Благодаря тому, что Disrex управляет несколькими магазинами Magento на собственной платформе и обнаружила первый компромисс достаточно рано, компания провела проверку всей своей инфраструктуры в течение часа и обнаружила второй магазин тем же днём. Компания опубликовала подробный отчёт об инциденте.
Sansec указала, что для клиентов Shield, атакованных до внедрения защитных правил, нет свидетельств фактического использования бэкдора. Рекомендуется ротация учётных данных Magento везде, где был обнаружен вредоносный процесс.
Атака работает в два этапа. Сначала вредоносный код внедряется в файл, который Magento записывает самостоятельно (например, при создании отчёта об ошибке). Затем Magento принудительно выполняет этот файл путём запуска стандартного уведомления об отклонении платежа. Код выполняется во время рендеринга сообщения, поэтому его открытие не требуется, и атака может пройти даже при неудачной доставке письма.
Sansec ещё не опубликовала полную цепь эксплуатации и обещает выпустить подробный разбор в следующем обновлении.
По анализу Disrex, встроенная директива в внедренный текст запускает последовательность собственных классов Magento в код, предназначенный исключительно для компилятора зависимостей командной строки. Этот код в конце подключает путь файла, выбранный преступником: отравленный несколько ранее лог. Выполненный PHP-дроппер пробует шесть PHP-функций подряд для запуска процесса, затем загружает и запускает вредоносную программу.
Disrex указывает три файла в setup/src/Magento/Setup/Module/Di/Code/ как точку завершения цепи, и сообщила, что идентифицировала эту уязвимость путём анализа исходного кода Magento на скомпрометированном сервере. Sansec не подтвердила этот анализ, и Disrex не публикует собранный запрос.
Два места важны для первого этапа. Проверка Sansec ищет маркер X_TRACE_ в var/report/. Disrex сообщила, что обе атаки были выполнены через var/log/system.log и были бы пропущены этой проверкой, поэтому необходимо искать в обоих директориях.
Маркер уже изменился: Disrex обнаружила заголовок триггера вида X-TRACE- с последующими десятью шестнадцатеричными символами утром 5 сентября и тот же заголовок без слова TRACE днём, поэтому поиск должен соответствовать структуре, а не точной строке.
TypeError из array_merge() с целочисленным аргументом в system.log сразу после include указывает на успешную эксплуатацию. Однако более скрытый вариант возвращает пустой массив и ничего не оставляет в логе.
Для процесса Disrex отметила, что настоящий поток ядра принадлежит root и не имеет оперативной памяти, поэтому заключённое в скобки имя от пользователя сайта с реальным использованием памяти указывает на вредоноса. Вредоносная программа устанавливает командную строку на буквальную строку в скобках, поэтому проверка по полю comm процесса ничего не найдёт.
Disrex также обнаружила, что двоичный файл, работающий в памяти на одном магазине, отличался от файла на диске, и рекомендует хешировать запущенный процесс из /proc//exe, а также сам файл. Неожиданные всплески уведомлений об отклонении платежа - повод для расследования, хотя легитимные отклонённые платежи генерируют то же уведомление.
Один из двух компромиссов Disrex обнаружил именно такое письмо. Сооснователь Disrex Рик Боума сообщил, что магазин отправил владельцу уведомление об отклонении платежа, в котором переменные шаблона никогда не разрешались: тело письма содержало сырые {{var ...}} теги, адрес клиента в домене .invalid и сумму ноль.
Это выглядит как сломанный заказ, но это побочный эффект попытки эксплуатации, прошедший через фильтр шаблонов Magento. Пересылка этого письма владельцем магазина начала расследование, которое обнаружило вредоноса в течение часа.
Disrex опубликовала обезличенную копию в ранней документации, которая дополнительно указывает на резервный текст ошибки Magento, появляющийся в блоке адреса как третий признак, и называет письмо единственным наиболее полезным ранним сигналом тревоги для продавцов, поскольку его обнаружение не требует специальных инструментов.
Индикаторы компрометирования:
- Процесс: [kworker/u:8:0], принадлежащий непривилегированному пользователю
- Файл: ~/.local/share/.gvfsd/gvfsd-user
- Файл: ~/.local/share/.gvfsd/.gvfsd_<8hex>.lock
- Файл: /tmp/.gvfsd_<8hex>.lock
- Файл: /tmp/.kw_
- Cron: */5 * * * * exec /.local/share/.gvfsd/gvfsd-user
- SHA-256: e315687a1dfe61ef4a5a5642214db6d3b2b05d81391285eebc2af664641a26a7 (образец Sansec)
- SHA-256: 8334b434fa3fe9f59cebe9609b11e0b1fd19d10212c45c705adec1902a1d06ef (на диске магазинов Disrex)
- SHA-256: 251fabd50d7b18a8b5e1b3ef5d64e7198c17244778f6461fb1ab07f6169bf220 (в памяти одного магазина Disrex)
- Домен: 247.cdnflare[.]xyz (хост загрузки вредоноса)
- IP: 99.84.67[.]186:443 (управление и контроль через WebSocket и TLS)
- IP: 88.216.72[.]181 (источник атаки)
- IP: 5.181.86[.]133 (источник атаки с массовой рассылкой)
Sansec рекомендует использовать сканер eComscan для обнаружения вредоноса. Версия 1.9.7 будет прерывать процесс для клиентов Shield.
Disrex получила чистый результат на первом магазине. Сканирование eComscan прошло в 10:00 UTC 5 сентября, примерно через 11 часов после первого запуска вредоноса и наличия 1728 строк cron, но сканер показал чистый результат. Причина была в масштабе: запланированное сканирование было направлено на корень документов магазина, а вредонос установился на один уровень выше, в домашнюю директорию учётной записи. Disrex уже расширила путь сканирования.
Нет готового исправления от производителя. До выхода официального патча от Adobe остаются варианты: временное отключение GraphQL от Sansec, неофициальные смягчения от Disrex, ProxiBlue и Graycore, а также два параметра сервера, не зависящих от уязвимости.
Disrex опубликовала правила nginx и Apache, которые блокируют запросы с параметрами эксплуатации в строке запроса URL. Тестирование на боевом магазине показало ограничение: те же параметры, отправленные в теле POST или JSON, достигали PHP, поскольку nginx и Apache проверяют только строку запроса. Disrex описывает правила как остановку текущей кампании, а не уязвимости в целом.
Основное смягчение Disrex добавляет проверку в три метода сканеров зависимостей Magento, предотвращая их запуск вне командной строки. Ручное редактирование отменяется при каждом composer install, поэтому Disrex также поставляет его как исходный патч composer-patches, который переприменяется при развёртывании и работает без изменений от версии 2.4.6 до 2.4.9.
Один из трёх файлов (ClassesScanner.php) вызывается через HTTP по крайней мере одним модулем третьей стороны (mageplaza/module-admin-permissions), и его защита ломает экран администратора этого модуля, поэтому Disrex рекомендует администраторам проверить директорию vendor перед редактированием.
Защита тестировалась на тестовом стенде, а не в работающем магазине, и Disrex указывает, что это не полное исправление само по себе. Пользователь GitHub ProxiBlue отдельно опубликовал ту же защиту 5 сентября как три неофициальных патча. Боума сообщил, что ProxiBlue (идентифицирован как разработчик Magento Лукас ван Стаден) пришёл к идентичной защите без координации, в тех же трёх методах сканера, с той же проверкой PHP_SAPI !== 'cli' и тем же сообщением об ошибке, причём версия Disrex была написана во время её ответа.
Disrex с тех пор воспроизвела три патча ProxiBlue в своём репозитории с указанием авторства, чтобы совпадение можно было проверить в одном месте. Компания предупреждает, что оба патча - одно и то же исправление и не должны применяться один поверх другого. Disrex рассматривает тот факт, что две независимые стороны пришли к одному исправлению, как сильное подтверждение его правильности. Ни Sansec, ни Adobe не подтвердили, что эти сканеры - точка завершения цепи.
Graycore, LLC опубликовала модуль Magento на GitHub и Packagist 5 сентября, который, по их словам, укрепляет три точки цепи: директива блока шаблона электронной почты отказывает в доступе бэкенд-блокам, генератор URL строк сетки проверяет класс перед построением, а открывающие теги PHP в отчётах об ошибках Web API разрушены.
Версия на Packagist на момент написания была более ранним релизом, чей единственный способ защиты был направлен на резолвер GraphQL PayPal, который с тех пор удалён. README указывает на то, что это укрепление, а не исправление, и предупреждает, что другие пути через уязвимость остаются открытыми и магазин может уже быть скомпрометирован.
Два параметра сервера вообще не зависят от знания цепи, указала Disrex. На одном из двух магазинов первые четыре из шести PHP-функций, которые пробовал дроппер, были отключены; proc_open не был отключен, и дроппер использовал его для запуска вредоноса, при этом open_basedir ничего не делал для ограничения дочернего процесса.
Добавление proc_open в disable_functions PHP и монтирование /tmp, /var/tmp и /dev/shm с noexec, чтобы загруженный двоичный файл не мог запуститься, - это слои, которые Disrex ставит выше каждого правила в своём репозитории.
Для уже заражённого магазина руководство по очистке Disrex устанавливает порядок: сначала сохранить доказательства, удалить запись cron перед отключением процесса (поскольку процесс его восстанавливает), не перезагружать сервер (копия под /proc может быть единственным оставшимся двоичным файлом), не запускать composer install для очистки (потому что это перезаписывает временные метки).
Затем рекомендуется сбросить хранилище сеансов, так как вредонос его считывал, и ротировать crypt/key в app/etc/env.php, а также все пароли администраторов, все ключи API провайдеров платежей и все другие учётные данные интеграции в этом файле.
Поставщики хостинга Nexcess и Liquid Web опубликовали идентичные уведомления об инцидентах 5 сентября, заявив, что они проводят проверку своих серверных сред и реализуют предупредительные меры.
Ни один из них не утверждает подтверждённый компромисс клиента или собственное воспроизведение дефекта. Disrex записала 26 различных исходных адресов на двух магазинах, взятых из собственных логов nginx доступа магазинов и дедублицированных; два из них - инфраструктура хостинга, отправляющая в массовом порядке, остальные - пул резидентных прокси, отправляющих по 2-6 запросов каждый. Блокирование единственного адреса атакующего из консультации Sansec остановила бы менее четверти трафика, который видела Disrex. Более раннее количество 28 включало двух собственных серверов Disrex, отправляющих запросы проверки во время ответа, которые были исключены. Ни один источник не назвал злоумышленников.
