Заражение магазинов Magento: 953 сайта и код, который живёт в базе

Безопасность

Заражение магазинов Magento: 953 сайта и код, который живёт в базе

Заражение магазинов Magento: загрузчик deepveindrilling.com в таблице cms_block и обход сканеров

По данным Sansec, одна и та же группа с июля 2025 года внедрила вредоносный код в 953 интернет-магазина, в основном на Magento. В октябре 2026-го она перешла на пятый домен загрузчика, deepveindrilling.com. Новая волна заражения магазинов Magento обошлась без новой уязвимости: группа вернулась туда, где давно может писать в базу.

Коротко

  • Одна группа с июля 2025 года заразила 953 магазина, в основном на Magento, и сменила пять доменов загрузчика.
  • Пятый домен, deepveindrilling.com, нашли на 83 магазинах; 60 из них уже были заражены прежними волнами.
  • Загрузчик лежит в таблице cms_block и прячет нагрузку в браузере покупателя, поэтому блокировка домена её не убирает.
  • С 23 октября отпечаток браузера отсеивает сканеры: urlscan.io получил чистую страницу, финальную нагрузку пока никто не перехватил.
  • Полностью пропатченный Magento 2.4.7-p10 заразили через оставшиеся чужой админ и бэкдор GSocket: патч не равен лечению.

Как шло заражение магазинов Magento с июля 2025 года

Исследователи Sansec связывают с одной преступной группой 953 взломанных интернет-магазина, большинство из них работает на Magento. За 15 месяцев кампания сменила пять доменов загрузчика и переезжает на новый адрес раз в несколько месяцев. В марте 2026 года Sansec уже описывала её как «массовую атаку PolyShell». Имени у группы нет, к какой-либо стране её не привязывают.

Пятый домен, deepveindrilling.com, зарегистрировали 6 октября 2026 года. Сканер eComscan впервые увидел новый загрузчик 7 октября в 21:54 UTC, а к концу 8 октября краулер Sansec нашёл его уже на 74 магазинах. Новые взломы так быстро не идут. Скорее группа массово правила записи там, где доступ на запись у неё уже был.

Всего домен нашли в CMS-блоках 83 магазинов, почти все на Magento. Самое показательное число — 60 из 83, около 72 %: столько магазинов уже загружали прежние скрипты группы. По данным Sansec, 34 из них делали это ещё с октября 2025 года. Октябрьская волна — в основном обновление старого доступа.

Складывать цифры не нужно: 953 — счёт за всю кампанию, 83 — магазины на пятом домене. Такие атаки на клиентскую сторону магазинов называют Magecart, но это название жанра, а не группы.

Старые адреса тоже никуда не делись. Домены manulfie.click и neswnsssn.click истекли, в мае 2026 года их перерегистрировали и припарковали. Между августом и октябрём Sansec всё ещё находила их загрузчики на девяти и шести магазинах. Браузеры посетителей отправляют новому владельцу домена адрес предыдущей страницы и заголовок текущей, а также выполняют любой скрипт, который он вернёт.

Почему загрузчик сидит в cms_block, а не в файлах темы?

Потому что база данных переживает почти любую чистку файлов. Загрузчик лежит в таблице cms_block, где Magento хранит содержимое статических блоков, встраиваемых в страницы. За всю кампанию eComscan нашёл его в cms_block на 148 серверных установках. В core_config_data или в файлах темы он не попадался ни разу.

После подозрения на взлом обычно сравнивают файлы с репозиторием, просматривают шаблоны и ищут вставки в настройках вроде «Miscellaneous Scripts». Здесь все три проверки дают чистый результат: код попадает на страницу из контента, который не лежит в git и который почти никто не сверяет с эталоном.

Если магазин сопровождает подрядчик, спросите, проверяет ли он CMS-контент. Когда мы берём магазин на доработку и сопровождение на Magento, проверка CMS-контента входит в регламент.

Как загрузчик остаётся у покупателя после блокировки домена?

Он прячет полезную нагрузку в браузере самого посетителя, поэтому блокировка домена останавливает только новые заражения. Загрузчик ставит на страницу два скрипта; второй до октября был интеграцией Keitaro, о ней ниже. Первый читает из хранилища браузера значение fpCode. Если оно есть, скрипт кладёт сохранённый код в невидимый div и программно кликает по нему, а браузер выполняет код как обработчик события.

Разработчикам здесь важны две детали. Во-первых, в коде нет eval(), и поиск по eval или new Function такую вставку пропустит: обработчики событий в DOM — штатный способ выполнить JavaScript. Во-вторых, сама вставка никогда не записывает fpCode. Это делает удалённый скрипт с домена загрузчика при первом же визите подходящего посетителя.

Дальше всё решает устройство веб-хранилища. Оно привязано к origin магазина и доступно любому скрипту на его страницах, а флаг HttpOnly защищает только cookie. Покупатель, однажды получивший нагрузку, выполняет её на каждой следующей странице магазина, даже если домен отключён или заблокирован на периметре. Мартовская версия вела себя скромнее и стирала сохранённую нагрузку после первого запуска.

Сам домен тоже не раскрывается. Он скрыт за Cloudflare, на главной отдаёт 404, а на запросы скрипта отвечает, только если они приходят от посетителей заражённых магазинов. Открыть домен вручную и посмотреть, что там лежит, не получится.

Зачем 23 октября переписали блоки и убрали Keitaro?

Чтобы встроить фильтрацию ботов в собственный загрузчик и не зависеть от чужой системы распределения трафика. 23 октября оператор снова переписал CMS-блоки. Вместо обычного тега script появился встроенный загрузчик, который собирает отпечаток браузера и отправляет его на домен вместе с псевдонимом кампании. Тогда же загрузчик появился ещё на 9 магазинах.

До октября второй скрипт был интеграцией «Script (async)» от Keitaro — коммерческого рекламного трекера, который работает и как система распределения трафика (TDS). Скрипт передавал реферер, заголовок страницы и строку запроса, а Keitaro решал, что отдать конкретному посетителю: нагрузку, редирект или ничего.

Сам Keitaro никто не взламывал: злоумышленники использовали легальный продукт по его прямому назначению, но в преступных целях. 24 октября Sansec запросила старый скрипт как посетитель с десктопной Windows. Сервер вернул пустой ответ вида QWE=123; и поставил cookie, которая помечает посетителя на 24 часа.

По словам Sansec, deepveindrilling.com «отказывается от Keitaro и переносит фильтрацию ботов в загрузчик». Новый отпечаток ищет признаки автоматизации и собирает характеристики машины:

  • флаг navigator.webdriver, глобальные объекты Selenium и свойства cdc_, которые оставляет ChromeDriver;
  • название видеокарты через WebGL, число ядер процессора, объём памяти;
  • размер экрана, часовой пояс, языки и client hints.

По этим данным сервер решает, что ответить посетителю. Приём работает: автоматический Chrome сервиса urlscan.io получил HTTP 200 и страницу без единой лишней строки. К 24 октября все 71 магазин, которые Sansec обошла повторно, уже работали на версии с отпечатком.

Отсюда главный вывод для тех, кто проверяет сайты автоматикой. 404 на главной домена и чистый ответ в песочнице ничего не говорят о том, что увидит живой покупатель. При этом код никуда не исчезает: он лежит в базе, и увидеть его можно, если читать содержимое CMS напрямую, а не отрисованную страницу.

Откуда у группы запись в базу, если новой дыры нет?

Из прошлых взломов. По оценке Sansec, октябрьская волна не опиралась на новую уязвимость, а исходный доступ группа получила раньше через уязвимости загрузки файлов в Magento. Sansec сообщает, что в марте 2026 года группа за один час внедрила код в 471 магазин, загрузив веб-шеллы через PolyShell (CVE-2026-48356). На части магазинов нашлись и файлы, загруженные через SessionReaper (CVE-2025-54236).

Насколько широко эксплуатировались эти бреши, видно по соседней выборке Sansec. Среди 3 024 магазинов, атакованных другим скиммером, заражёнными оказались 32 %, около 968 сайтов. Это цифра по другой кампании, а не доля уязвимых Magento-магазинов вообще.

Два магазина из отчёта показывают обе стороны проблемы.

  • Magento 2.4.7-p1. На сервере лежали веб-шеллы PolyShell под видом PNG-картинок, а CMS-блок 7 октября переключился с прежнего домена на deepveindrilling.com. Исправление Adobe для PolyShell, APSB26-73, здесь так и не установили.
  • Magento 2.4.7-p10. Все патчи ядра на месте, и всё же 23 октября магазин заразили. Ранее сканирование уже находило на нём чужую учётную запись администратора и бэкдор GSocket.

Второй случай важнее первого. Патч закрывает дверь, через которую злоумышленники вошли, но не выгоняет тех, кто уже внутри. Лишний администратор работает через штатную панель. GSocket — инструмент удалённого доступа со своей инфраструктурой связи, и версия Magento ему безразлична. Расширение .png тоже ничего не гарантирует: веб-шелл распознают по содержимому и происхождению файла.

Вывод Sansec категоричен: если магазин обращается к доменам кампании, атакующий может писать в вашу базу, и удаление скрипта этот доступ не снимает.

Как проверить магазин Magento на эту кампанию

Начинать стоит не с удаления, а с фиксации следов. Иначе потом не получится отличить исходный взлом от повторного заражения. Порядок, которого мы придерживаемся при разборе инцидентов в e-commerce:

  1. Снимите копию. До любой чистки сохраните дамп базы, файлы, список процессов, задания cron и журналы веб-сервера. Время изменения блока и его связь с admin_user и загрузками файлов пригодятся при разборе.
  2. Проверьте контент прямо в базе. Ищите в таблицах cms_block и cms_page домены из списка индикаторов в отчёте Sansec, в том числе закодированные в base64, а также строки fpCode и se_referrer. Учитывайте префикс таблиц и отдельно просмотрите блоки, изменённые около 7 и 23 октября.
  3. Сверьте администраторов и сессии. Каждой учётке в admin_user должен соответствовать живой сотрудник. Незнакомые учётки удалите после фиксации следов, смените пароли базы, админки и API-интеграций, сбросьте активные сессии.
  4. Ищите закрепление на сервере. Проверьте процессы и автозапуск GSocket, лишние SSH-ключи, задания cron, PHP-код в каталогах media и загрузок, в том числе в файлах с расширениями картинок.
  5. Поставьте патчи. APSB26-73 для PolyShell и APSB25-88 для SessionReaper обязательны, но ставятся после пунктов 2–4, а не вместо них.
  6. Проверьте результат глазами покупателя. Разовый скан urlscan.io очистку не подтверждает. Откройте страницы в обычном браузере гостем и под учётной записью покупателя, с реальным реферером и без очистки хранилища.

Проверка под учётной записью покупателя — не формальность. На ранних этапах кампания отдавала дополнительные скрипты именно авторизованным покупателям. 12 декабря 2025 года скрипт группы загрузил ресурс с crypto-insider.top, а через пять минут ещё один, с leqdger.click. Это домен с опечаткой в названии бренда криптокошельков Ledger; на момент отчёта Sansec он уже истёк.

Для наблюдения пригодится политика CSP в режиме отчётов: она покажет, если страница начнёт обращаться к незнакомому домену. Веб-файрвол прикроет уязвимости в механизме загрузки файлов, пока обновление не установлено. Но запись в базу через украденную учётку администратора он не остановит.

Из практики. Типичная ошибка — удалить блок в админке, поставить патч и закрыть тикет. Через неделю блок возвращается, потому что чужой администратор и бэкдор остались на месте. Если полноту очистки доказать нельзя, надёжнее восстановиться из заведомо чистой копии и затем закрыть исходный вектор. Так мы выстраиваем защиту сайта от взлома.

Чего пока не знают

Главного: что получает живой покупатель. Финальную нагрузку для реальных посетителей Sansec перехватить не удалось, и фильтрация по отпечатку для того и придумана. Домен с опечаткой в названии Ledger и путь на crypto-insider.top намекают на интерес к владельцам криптовалюты. Но как октябрьская версия монетизирует трафик, через кражу карт, подмену кошельков или редиректы, пока неизвестно.

Неизвестна и сама группа: ни названия, ни связей с известными операторами.

Если автоматический сканер говорит, что всё чисто, а вы в этом не уверены, нужна проверка руками, с учётом бизнес-логики и сценариев авторизации. Именно это мы делаем при тестировании безопасности веб-приложений.

Частые вопросы

Это новый взлом Magento или возврат в старые магазины?

В основном возврат. По данным Sansec, в октябре новых уязвимостей не использовали: 60 из 83 магазинов на домене deepveindrilling.com уже были заражены раньше. Исходный доступ группе, по оценке Sansec, дали уязвимости загрузки файлов, в том числе PolyShell и SessionReaper.

Удаление блока в админке Magento останавливает кампанию?

Нет. Если магазин обращался к доменам кампании, атакующий может писать в базу, и после удаления блок вернётся. Нужно удалить чужие учётки, сменить пароли базы, админки и API-интеграций и найти бэкдоры на сервере.

Почему сканер сайта показывает чистую страницу?

Загрузчик собирает отпечаток браузера и распознаёт автоматизацию по navigator.webdriver, следам Selenium и ChromeDriver. Ботам он ничего не отдаёт, поэтому проверять нужно содержимое cms_block и cms_page прямо в базе.

Какая версия Magento в безопасности, если ядро уже пропатчено?

Версия сама по себе не защищает: в отчёте заражён магазин на 2.4.7-p10 без пропущенных патчей ядра. APSB26-73 и APSB25-88 ставить обязательно, но после проверки администраторов и поиска закрепления.

Где в Magento искать вредоносный код этой кампании?

В таблицах cms_block и cms_page, особенно в записях, изменённых около 7 и 23 октября 2026 года. Ищите домены из индикаторов Sansec, base64-строки, fpCode и se_referrer. В core_config_data и файлах темы этот загрузчик Sansec не находила.

Нашли у себя подозрительный CMS-блок или не уверены, что магазин чист после PolyShell? Команда HirexTech разберёт инцидент, найдёт закрепление и закроет вход: защита сайта от взлома и вирусов.

Прокрутить вверх