Популярный фреймворк для глубокого обучения PyTorch Lightning на несколько часов превратился в ловушку для разработчиков. Злоумышленники загрузили на официальный репозиторий PyPI версии 2.6.2 и 2.6.3 библиотеки, которые содержали встроенного червя для кражи учётных данных. Администрация PyPI оперативно удалила обе версии, но любой, кто успел их установить или обновить, уже мог скомпрометировать свои системы.
Описание
Это первый подтверждённый случай, когда кампания Shai-Hulud, ранее атаковавшая только экосистему npm, перешла на Python-пакеты. За атакой стоит группа TeamPCP, также известная как LAPSUS$. Механизм заражения существенно отличается от типичных атак через зависимости: полезная нагрузка запускается не в момент установки пакета, а при импорте библиотеки в работающем Python-скрипте. Это делает бесполезными большинство песочниц и изолированных сред, которые проверяют только процесс инсталляции.
Как устроена атака
Вредоносный код встроен непосредственно в файл lightning/__init__.py. Как только любой Python-процесс выполняет команду import lightning, запускается фоновый поток. Этот поток проверяет наличие вложенного каталога _runtime и запускает скрипт start.py, который, в свою очередь, загружает среду выполнения Bun (JavaScript-рантайм). Bun версии 1.3.13 скачивается с официального GitHub-репозитория, если его нет в системе. После этого выполняется основной файл router_runtime.js размером 11 мегабайт.
Этот JavaScript-червь полностью идентичен тому, что ранее использовался в атаках на SAP CAP через npm. Он использует обфускацию (запутывание кода), чтобы скрыть свои функции. Внутри червя есть защита от запуска в системах с русскоязычной локалью: если переменные окружения или часовой пояс указывают на Россию, процесс немедленно завершается.
Интересно, что две версии отличаются только степенью скрытности. В версии 2.6.2 дроппер (компонент, загружающий основную нагрузку) выводил отладочные сообщения в стандартный вывод. В версии 2.6.3 вся диагностика была убрана, и червь работает полностью бесшумно.
Что именно крадёт червь
Специалисты обнаружили несколько уровней компрометации. При каждом импорте библиотеки червь собирает все токены доступа из переменных окружения: GitHub OAuth-токены, персональные токены доступа GitHub (начинающиеся с ghp_ или gho_), токены автоматизации npm, токены сервисных учётных записей GitHub Actions (ghs_), а также любые облачные учётные данные, например ключи AWS.
Далее червь идентифицирует учётную запись AWS через вызов sts:GetCallerIdentity и перечисляет секреты в AWS Secrets Manager. Все собранные данные отправляются на зашифрованный командный центр (C2) через 443-й порт.
Но самое опасное - это способность червя распространяться внутри экосистемы Git. Если у жертвы есть права записи в репозитории GitHub, червь вносит вредоносные коммиты от имени пользователя claude с адресом users.noreply.github.com. Он добавляет в репозитории файлы .vscode/tasks.json, .claude/settings.json, .claude/router_runtime.js и .claude/setup.mjs. При этом используются поддельные коммиты, имитирующие автоматические действия инструмента Claude Code. Черви атакуют до 50 веток на один репозиторий и запускают до двух параллельных операций внесения коммитов.
Кроме того, червь переиздаёт вредоносные версии npm-пакетов, внедряя ту же самую полезную нагрузку. Таким образом, атака, начавшись в PyPI, быстро перекидывается на npm-экосистему.
Последствия и рекомендации
Любое окружение, в котором выполнялась команда import lightning в скомпрометированных версиях, следует считать скомпрометированным. Речь идёт не только о ноутбуках Jupyter и тренировочных скриптах, но и о CI/CD-пайплайнах, где фреймворк мог загружаться для проверки моделей. Весьма вероятно, что злоумышленники получили доступ к токенам, которые дают права на запись в репозитории и на облачные ресурсы.
Если вы устанавливали PyTorch Lightning в период действия уязвимых версий (точное время их присутствия на PyPI уточняется), необходимо немедленно отозвать все токены GitHub, токены npm, ключи AWS и любые другие секреты, которые могли оказаться в переменных окружения. Также стоит проверить историю коммитов в репозиториях на наличие подозрительных файлов по указанным выше путям.
Администрация PyPI уже удалила пакеты, но пользователям, которые скачали их через зеркала или кеши пакетных менеджеров, стоит вручную проверить содержимое установленной библиотеки. Наличие в каталоге lightning/_runtime файлов start.py, router_runtime.js или бинарного файла .bun/bun является надёжным признаком заражения.
Этот инцидент показывает, что угроза атак через цепочку поставок программного обеспечения становится всё более изощрённой. Злоумышленники не просто прячут вредоносный код в зависимости, но и адаптируют его под конкретные языки и среды выполнения. Следующий шаг может коснуться других репозиториев, например RubyGems или Maven Central. Разработчикам и командам безопасности стоит усилить мониторинг не только на этапе установки пакетов, но и в процессе их использования в рантайме.
Индикаторы компрометации
SHA256
- 2d4e21d2e78d0868ce7894487e67c67f929d8d81d78c5b07a3ad225b13eae890
- 3071422c3294e7b61cb490c57c48c8dea569bacf12e57a078293b6547d7586d3
- 56070a9d8de0c0ffb1ec5c309953cf4679432df5a78df9aeb020fbb73d2be9fb
- 5f5852b5f604369945118937b058e49064612ac69826e0adadca39a357dfb5b1
- 8046a11187c135da6959862ff3846e99ad15462d2ec8a2f77a30ad53ebd5dcf2
- d2815d425ae08cc627f1db69009442165f8bbc64b7e9157e2ff9d7aab02094d4