Разработчики, использующие официальный 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 для публикации и ограничивать исходящий трафик из сред выполнения.
Индикаторы компрометации
IPv4
- 160.119.64.3
- 83.142.209.194
Domains
- check.git-service.com
- git-service.com
- t.m-kosche.com
URLs
- http://169.254.169.254/
- http://169.254.170.2/
- https://check.git-service.com/api/public/version
- https://check.git-service.com/audio.mp3
- https://check.git-service.com/rope.pyz
- https://check.git-service.com/v1/models
- https://t.m-kosche.com/rope.pyz
- https://t.m-kosche.com:443/api/public/otel/v1/traces
SHA256
- 069ac1dc7f7649b76bc72a11ac700f373804bfd81dab7e561157b703999f44ce
- 3de04fe2a76262743ed089efa7115f4508619838e77d60b9a1aab8b20d2cc8bf
- 7c24b4d9a8f448832f3752d7f67dcdbf1b7f0f41e10bf633efa175e627144e8b
- 7d80b3ef74ad7992b93c31966962612e4e2ceb93e7727cdbd1d2a9af47d44ba8
- 85f54c089d78ebfb101454ec934c767065a342a43c9ee1beac8430cdd3b2086f
- 877ff2531a63393c4cb9c3c86908b62d9c4fc3db971bc231c48537faae6cb3ec
- aeaf583e20347bf850e2fabdcd6f4982996ba023f8c2cd56bbd299cfd56516f5
- c0b094e46842260936d4b97ce63e4539b99a3eae48b736798c700217c52569dc