Уязвимости в панели управления задачами Qinglong привели к массовому внедрению криптомайнеров

vulnerability

В начале февраля 2026 года пользователи Qinglong - популярной платформы с открытым исходным кодом для планирования задач, набравшей более 19 тысяч звезд на GitHub, - начали жаловаться на аномальную загрузку процессора на своих серверах. Причиной оказался вредоносный файл .fullgc, представляющий собой бинарник криптомайнера. Злоумышленники развернули его с помощью двух уязвимостей, позволявших обойти аутентификацию и выполнить произвольный код без учетных данных. Хотя атаки остались практически незамеченными в англоязычном сообществе, на китайских форумах разработчиков и в обсуждениях GitHub развернулась настоящая картина: злоумышленники активно эксплуатировали открытые панели Qinglong для установки программ для добычи криптовалют.

Детали уязвимостей

Qinglong - это платформа для самостоятельного хостинга (self-hosted), которая позволяет запускать скрипты на Python3, JavaScript, Shell и TypeScript. Её активно используют разработчики из Китая для автоматизации повторяющихся задач: от сбора данных до отправки уведомлений. Основной способ развертывания - образ Docker или пакет npm (@whyour/qinglong). Несмотря на скромные показатели загрузок в npm, через Docker проект распространяется гораздо шире. По данным GitHub, у репозитория 19 400 звезд и 3 200 форков, а основная аудитория - китайскоязычные разработчики, которые устанавливают панель на облачные VPS-серверы или домашние серверы.

Первые сообщения о подозрительном процессе .fullgc, загружающем процессор на 85-100%, появились 7-8 февраля (issue #2923). Затем, 8 февраля, некий Copilot SWE Agent предложил патч (PR #2924), направленный на блокировку инъекций команд в конфигурационные файлы. Однако сообщество требовало более активной реакции: в issue #2926 пользователи призывали мейнтейнера опубликовать предупреждение в Telegram-канале проекта. К 14 февраля атаки подтвердили уже несколько человек, а 24 февраля появились новые детали о заражении. И только 27 февраля были опубликованы коренные причины - две уязвимости обхода аутентификации (issues #2933 и #2934). 1 марта мейнтейнер официально подтвердил наличие проблем и призвал обновить версию.

Обе уязвимости затрагивали Qinglong версии 2.20.1 и ниже. Они зафиксированы в базе уязвимостей Snyk (SNYK-JS-WHYOURQINGLONG-15440732 и SNYK-JS-WHYOURQINGLONG-15468374). Первая, CVE-2026-3965, связана с правилом перезаписи URL в промежуточном программном обеспечении (middleware) Express.js. Панель Qinglong преобразовывала запросы вида /open/* в /api/$1. Это открывало непреднамеренный доступ к защищенным административным конечным точкам. Атакующий мог сбросить пароль администратора одним запросом без аутентификации, а затем получить полный контроль над панелью и выполнять произвольные скрипты.

Вторая уязвимость, CVE-2026-4047, оказалась еще опаснее. Она позволяла удаленно выполнить код (remote code execution) без каких-либо сбросов пароля. Промежуточное ПО аутентификации проверяло совпадение пути с учетом регистра символов (req.path.startsWith('/api/')), но сам Express.js обрабатывал маршруты без учета регистра. Таким образом, запрос к /aPi/system/command-run вместо /api/system/command-run обходил проверку, но при этом корректно направлялся к точке выполнения команд. Это давало злоумышленнику возможность выполнить любую команду на сервере.

Обе уязвимости - классический пример рассинхронизации между логикой безопасности и поведением веб-фреймворка. Подобные проблемы давно известны: несовпадение представления запроса в слое авторизации и в слое маршрутизации позволяет обходить защиту. Snyk ранее освещал аналогичные схемы некорректного контроля доступа в Express.js, а похожий баг был обнаружен в Next.js (CVE-2025-29927). Это подчеркивает, что уязвим не только Qinglong.

Сам процесс атаки выглядел следующим образом. Используя обход аутентификации, злоумышленники модифицировали конфигурационный файл config.sh, внедряя shell-скрипт. Он загружал бинарный файл для конкретной платформы (поддерживались Linux x86_64, ARM64 и macOS) с сервера file.551911.xyz, сохранял его скрытым файлом /ql/data/db/.fullgc, делал исполняемым и запускал в фоне с подавленным выводом. Кроме того, в код была встроена логика автоматического перезапуска майнера в случае его остановки. Название .fullgc выбрано не случайно: в средах Java/JVM "Full GC" (полная сборка мусора) - известная причина скачков загрузки ЦП, что могло затянуть расследование администратора.

Масштаб заражения оказался значительным. Пользователи сообщали об инфицировании даже на системах, работавших за обратными прокси-серверами Nginx с поддержкой SSL. Поставщики облачных услуг, например Alibaba Cloud (Aliyun), помечали скомпрометированные экземпляры как занимающиеся майнингом. Один из пострадавших рассказал, что через ту же уязвимость злоумышленники получили доступ к его панели мониторинга Nezha, открывавшей обзор на сотни машин.

Интересно, что первоначальная реакция мейнтейнера была направлена на блокировку конкретных полезных нагрузок (payloads) - в PR #2924 предлагалось проверять поля задач на наличие команд curl, wget и других shell-символов. Однако этот патч так и не был влит. Вместо этого в PR #2941 исправили саму причину - обход аутентификации на уровне middleware. Такой порядок действий - сначала закрыть доступ, а затем рассматривать фильтрацию ввода как дополнительную защиту - является правильным с точки зрения безопасности.

Этот инцидент - наглядный урок для всех, кто использует самописные веб-панели. Во-первых, необходимо проверять согласованность цепочки промежуточного ПО: если в приложении есть перезапись URL или проверка путей по шаблону, убедитесь, что middleware безопасности и маршрутизатор одинаково интерпретируют запросы. Регистр символов, завершающие слеши, кодировка и правила перезаписи - частые источники несоответствий.

Во-вторых, любой веб-сервис, открытый в интернет, становится мишенью, даже если он узкоспециализированный. Если API может выполнять команды, он должен иметь работающую аутентификацию. Лучше размещать такие панели за VPN или SSH-туннелем, а не выставлять напрямую.

В-третьих, мониторинг использования ресурсов помогает вовремя заметить аномалии. В данном случае майнинг обнаружили из-за почти полной загрузки ЦП. Если бы злоумышленники ограничили его потребление 20-30%, обнаружение могло занять гораздо больше времени. Рекомендуется устанавливать лимиты ресурсов для контейнеров и использовать системы мониторинга.

Наконец, обновление Docker-образов - критически важная процедура. Qinglong распространяется преимущественно через Docker, и своевременная установка патчей могла бы предотвратить атаку. Пользователям, которые когда-либо запускали Qinglong, стоит проверить систему на признаки компрометации: наличие скрытых процессов с высоким потреблением ЦП, необычные файлы в каталоге /ql/data/db/, а также подозрительные строки в config.sh. При обнаружении заражения нужно удалить не только контейнер, но и связанные тома Docker, очистить config.sh, пересоздать контейнеры из чистой свежей версии и обновиться до последней.

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

Ссылки

Комментарии: 0