Разработчики, использующие официальный Python-клиент Microsoft Azure Durable Functions, оказались под ударом. В репозитории PyPI обнаружены три вредоносные версии пакета durabletask - 1.4.1, 1.4.2 и 1.4.3. Эти сборки содержат скрытый дроппер, который при импорте библиотеки загружает и выполняет модульный фреймворк для кражи данных и распространения по инфраструктуре. Инцидент напрямую связан с кампанией Mini Shai-Hulud, которую ведёт группировка TeamPCP. Microsoft уже подтвердила компрометацию и удалила проблемные версии из PyPI.
Описание
Пакет durabletask является частью среды выполнения Durable Task, используемой в облачных приложениях Azure. Он загружается более 400 тысяч раз в месяц и применяется в автоматизации, CI/CD и других серверных сценариях. Именно такие среды - Linux-серверы, контейнеры, виртуальные машины - стали главной целью злоумышленников.
Все три версии были загружены на PyPI в течение 35 минут. Ни одна из них не имеет соответствующих тегов или записей в системе непрерывной интеграции Microsoft GitHub. Атакующие получили доступ к учётным данным для публикации пакета, обойдя штатный конвейер сборки. По данным анализа, инцидент стал следствием предыдущей компрометации учётной записи GitHub: злоумышленники извлекли секреты репозитория, включая токен PyPI, и использовали его для прямой загрузки.
Как выяснили специалисты компании в своём анализе, код дроппера встроен непосредственно в исходные файлы пакета. После установки любой из трёх версий при первом импорте durabletask выполняется следующий сценарий. Сначала проверяется, работает ли система под управлением Linux. Если да, дроппер скачивает с сервера управления check.git-service.com файл rope.pyz и сохраняет его в /tmp/managed.pyz. Затем запускает его в отдельном процессе, перенаправляя весь вывод в /dev/null. Ошибки не логируются. Разработчик не видит никаких признаков заражения.
С каждой последующей версией число заражённых файлов увеличивалось: в 1.4.1 - только __init__.py, в 1.4.2 - также task.py, а в 1.4.3 дроппер срабатывает уже из пяти точек входа. Это сделано для того, чтобы payload запускался независимо от того, какой именно модуль импортирует пользователь.
Сам payload rope.pyz - это полноценный фреймворк для кражи учётных данных и бокового перемещения. Перед запуском он проверяет, что система является Linux, количество ядер процессора больше двух (чтобы обойти песочницы), а локаль не начинается с "ru" - характерная черта для группировок из Восточной Европы. Если все проверки пройдены, фреймворк запускает семь сборщиков, работающих параллельно.
Они извлекают данные из всех основных облачных провайдеров: AWS, Azure, GCP. Среди целей - менеджеры паролей (1Password, Bitwarden, pass, gopass), файлы конфигурации Kubernetes, токены HashiCorp Vault, SSH-ключи, Docker-сокет и даже настройки инструментов для разработчиков ИИ (Claude Desktop, Cursor, VS Code). Сборщики также читают файлы .env, историю команд и все переменные окружения.
Все собранные данные сжимаются, шифруются алгоритмом AES-256-GCM, а ключ упаковывается RSA-4096. Расшифровать их может только владелец соответствующего закрытого ключа. Отправка происходит несколькими способами. Первичный - POST-запрос к серверу управления. Если тот недоступен, payload ищет в коммитах GitHub строку "FIRESCALE" и по ней восстанавливает новый адрес, заверенный цифровой подписью. Третий способ - создание публичного репозитория на GitHub с использованием украденных токенов жертвы, куда загружается зашифрованный архив.
Фреймворк также умеет распространяться по инфраструктуре. Внутри AWS он через SSM Agent отправляет команду на выполнение payload на до пяти других EC2-инстансов. В Kubernetes использует kubectl exec для внедрения в до пяти подов. После заражения остаются маркерные файлы, которые предотвращают повторное заражение той же машины.
Особую опасность представляет модуль roulette.py. Если система находится в израильской или иранской локали (проверяется по часовому поясу и языку), модуль с шансом один к шести воспроизводит аудиофайл с сервера управления и выполняет команду rm -rf /*. Если условие не срабатывает, payload устанавливает персистентность в виде фальшивого systemd-сервиса с именем pgsql-monitor.service.
Связь с кампанией TeamPCP подтверждается использованием вторичного домена t.m-kosche.com, который ранее фигурировал в атаках на TanStack, Mistral AI, Guardrails AI и другие проекты. Кроме того, имена репозиториев для эксфильтрации взяты из русского фольклора: Баба-Яга, Кощей, Жар-птица.
Для защиты необходимо немедленно проверить установленные версии durabletask. Если используется любая из трёх проблемных, систему следует изолировать, проверить наличие маркерных файлов в ~/.cache/.sys-update-check и ~/.cache/.sys-update-check-k8s, а также следы сервиса pgsql-monitor.service. Все облачные учётные данные, SSH-ключи и токены, к которым имела доступ заражённая система, подлежат отзыву. На сетевом уровне нужно заблокировать домены check.git-service.com и t.m-kosche.com. В будущем стоит применять верификацию хешей пакетов, использовать OIDC для публикации и ограничивать исходящий трафик из сред выполнения.