- Множество скомпрометированных релизов @7nohe/openapi-react-query-codegen внедрил вредоносное ПО в проекты, использующие хуки на основе TanStack Query.
- Злоумышленник воспользовался binding.gyp sandbox escape а также предварительно установить скрипты для выполнения обфусцированной JavaScript-нагрузки во время выполнения команды npm install.
- Полезная нагрузка собирает обширный опыт работы с облачными технологиями и знаниями разработчиков., передавая их в контролируемые злоумышленниками репозитории GitHub.
- Украденные жетоны затем используются для распространить вредоносное ПО на большее количество npm-пакетов и репозиториев GitHub.отравляет всю цепочку поставок JavaScript.
Для команд, которые используют TanStack Query в качестве основного npm-пакета для управления состоянием сервера в React и других фронтенд-фреймворках, недавний инцидент в цепочке поставок показывает, как быстро может быть подорвано это доверие. Популярный вспомогательный инструмент, созданный специально для генерации типобезопасных хуков TanStack Query из схем OpenAPI, был незаметно использован в качестве оружия и распространен в реестре npm со встроенным сложным вредоносным ПО.
Исследователи в области безопасности описывают эту атаку как кампанию в стиле TeamPCP , в которой повторно используются многие приемы и технические схемы, замеченные в предыдущих инцидентах. Однако на этот раз основное внимание уделяется разработчикам, которые создают структуру своего слоя данных с помощью пакета @7nohe/openapi-react-query-codegen — утилиты, которая обещает сэкономить время, автоматически генерируя хуки TanStack Query вместо написания шаблонного кода вручную.
Как генератор кода TanStack Query превратился в средство доставки вредоносного ПО
Пакет, оказавшийся в центре инцидента, @7nohe/openapi-react-query-codegen , предназначен для работы со спецификацией OpenAPI и генерации полностью типизированных хуков, совместимых с TanStack Query. С более чем 150 000 еженедельных загрузок, он играет критически важную роль для многих команд, которые используют TanStack Query для организации получения, кэширования и синхронизации данных бэкэнда в своих фронтендах на основе React.
Согласно результатам анализа инцидента, злоумышленнику удалось скомпрометировать как сам пакет npm, так и его репозиторий на GitHub . Взлом был осуществлен путем использования уязвимости в одном из рабочих процессов GitHub Actions проекта, что означало, что вредоносные сборки по-прежнему выглядели так, будто они происходят из легитимного конвейера CI и поставляются с действительными подтверждениями происхождения. Эти криптографические подтверждения, обычно являющиеся сильным сигналом доверия для пользователей npm, стали вводить в заблуждение, как только сам рабочий процесс оказался под контролем злоумышленников.
В течение коротких промежутков времени, примерно двадцати минут, злоумышленник опубликовал в npm десять зараженных версий пакета, каждая из которых содержала код, предназначенный для выполнения во время установки и запуска многоэтапной вредоносной программы. Затронутые релизы охватывают несколько минорных и исправленных версий, и все они теперь должны рассматриваться как ненадежные.
- @7nohe/openapi-react-query-codegen@0.5.4
- @7nohe/openapi-react-query-codegen@0.5.5
- @7nohe/openapi-react-query-codegen@1.6.3
- @7nohe/openapi-react-query-codegen@1.6.4
- @7nohe/openapi-react-query-codegen@2.2.1
- @7nohe/openapi-react-query-codegen@2.2.2
- @7nohe/openapi-react-query-codegen@3.0.3
- @7nohe/openapi-react-query-codegen@3.0.4
- @7nohe/openapi-react-query-codegen@0.0.0-365d4eb738d3146583431948d3ba6e27a32556be
- @7nohe/openapi-react-query-codegen@0.0.0-ec7876d6c917dad516ba69bbfafc948b834bf0ab
Все эти варианты преследуют одну и ту же основную цель: воспользоваться популярностью пакета среди пользователей TanStack Query, чтобы обеспечить выполнение кода во время установки npm, а затем распространить его по всей цепочке поставок JavaScript.
Полезная нагрузка «Trinitite» и методы ее выполнения на этапе установки.
Вредоносная программа идентифицирует себя с помощью ироничного названия. «Trinitite: при поддержке Preview 2 Effects», отсылка к стеклообразному материалу, образующемуся в результате ядерных испытаний. Более ранние внутренние названия скриптов, такие как is_it_this_simple.js Это намекает на небрежное отношение нападающего, но лежащая в основе техника отнюдь не проста.
Основной механизм исполнения основан на binding.gyp sandbox escapeВ обычных проектах Node.js файл binding.gyp используется для настройки нативных дополнений, скомпилированных node-gyp, но здесь он используется в качестве оружия. Когда npm обнаруживает файл binding.gyp, node-gyp выполняет его проверку. conditions Злоумышленник использует Python для создания поля. Он вставляет в это поле тщательно составленное выражение на Python, используя иерархию классов Python для выхода за пределы ожидаемой «песочницы» и выполнения произвольных команд оболочки.
В скомпрометированном пакете выражение условий сильно обфусцировано. Экранирование в формате Юникода и шестнадцатеричном форматеПосле декодирования он проходит по внутренним механизмам Python. __subclasses__ дерево для определения местоположения catch_warnings класс, использует это как точку опоры для достижения __builtins__импортирует os модуль и, наконец, вызовы os.system() Для запуска основной полезной нагрузки с помощью Node.js. type Поле в файле binding.gyp кодируется в шестнадцатеричном формате следующим образом: noneТаким образом, настоящая нативная сборка не предпринимается; конфигурация существует исключительно для того, чтобы незаметно внедрить одну-единственную команду оболочки.
Такой подход означает, что пакет может выполнить вредоносный код во время установки даже если нет явного preinstall скрипт определен в файле package.json. Однако не все «отравленные» версии используют именно этот трюк. Две предварительные сборки используют более простые хуки preinstall: одна выполняет скрипт Node с именем nu.js напрямую, а другой получает среду выполнения Bun через wget по трубам bash а затем запускается программа с подходящим названием. is_it_this_simple.jsБолее поздние версии объединяют оба метода, распространяя вредоносный файл binding.gyp. и a preinstall Для обеспечения избыточности, запись указывает на один и тот же основной JavaScript-код.
Уровни обфускации и обход песочницы в основном JavaScript-коде
После срабатывания первоначального механизма атаки, атака переключается на большой JavaScript-файл с именем 3FWCvzduYZg.js , помещенный в корневую папку пакета npm. Этот скрипт, размером примерно 5.4 МБ и минимизированный до одной строки, разработан таким образом, чтобы быть максимально непрозрачным на первый взгляд, а дальнейший анализ показывает, что он защищен несколькими различными уровнями шифрования и обфускации.
Самый внешний слой состоит из целочисленный массив из 1.6 миллиона элементовРасшифровано с помощью простого XOR-операции над константой 29. В результате расшифровки получается вторичный скрипт, задача которого — незаметно получить среду выполнения Bun, сохранив её во временном файле с именем, соответствующим этому скрипту. trinnyyyy-XXXXX Затем, используя Bun, выполняется основная полезная нагрузка. Сама основная нагрузка защищена шифрованием AES-128-GCM, а затем обрабатывается с помощью пользовательских шифров поверх стандартных методов обфускации JavaScript, включая те, которые используются в популярных инструментах, таких как obfuscator.io.
В полностью распакованном виде эта многоуровневая полезная нагрузка демонстрирует сочетание возможностей: сборщик учетных данных, нацеленный на широкий спектр облачных и разработческих платформ, компонент червя, способный распространять заражение на новые цели, и деструктивный командный канал. Прежде чем что-либо из этого активируется, скрипт выполняет ряд проверок среды, чтобы обойти песочницы и инструменты безопасности, и незаметно завершает работу, если выполняются определенные характерные условия.
Среди проверок: индикаторы локали, среды и файловой системы Обычно встречается в исследовательских средах. Вредоносная программа прекращает работу, если системная локаль русская, если присутствуют каталоги, принадлежащие продуктам защиты конечных точек, таким как CrowdStrike, SentinelOne или Carbon Black, если текущий рабочий каталог совпадает с путями, используемыми известными инструментами сканирования цепочки поставок, или если переменные среды содержат поддельные учетные данные, используемые сканерами безопасности. Она также проверяет GITHUB_REPOSITORY_OWNER а также наличие инструментов повышения безопасности, таких как StepSecurity. harden-runnerизбегая учетных записей GitHub, которые, как известно, принадлежат исследователям в области безопасности.
Что именно вредоносная программа крадет из сред разработки на основе запросов TanStack?
После прохождения проверок среды вредоносная программа начинает сбор учетных данных в широком масштабе. Хотя исходный пакет позиционируется как вспомогательное средство для пользователей TanStack Query, на самом деле область его действия выходит далеко за рамки одной библиотеки, затрагивая практически все уровни инструментария и облачной инфраструктуры современного JavaScript-разработчика.
Со стороны разработчика полезная нагрузка сканирует... Персональные токены доступа GitHub в различных форматах, включая классические токены, начинающиеся с gho or ghp и более новые детализированные токены, начинающиеся с github_pat_В средах выполнения GitHub Actions также запрашиваются токены OpenID Connect через описанный в документации способ. ACTIONS_ID_TOKEN_REQUEST_TOKEN и ACTIONS_ID_TOKEN_REQUEST_URL переменные среды, предоставляющие злоумышленнику возможность получить доступ к идентификаторам рабочей нагрузки, а не только к статическим секретам.
Затем в сценарии появляются общеупотребительные языковые реестры. Там написано: токенов npm, PyPI и RubyGems. из конфигурационных файлов, таких как ~/.npmrcсканирование для поиска дополнительных локальных проектов .npmrc файлы и попытки проверки обнаруженных токенов npm bearer путем вызова /-/whoami Конечная точка в публичном реестре. Аналогичные схемы используются в PyPI и RubyGems, где происходит сбор данных аутентификации и подтверждение того, что каждый токен может успешно взаимодействовать с соответствующим реестром, прежде чем его извлечь.
Облачный след ещё больше. В Amazon Web Services вредоносное ПО перечисляет переменные среды, такие как AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY, анализирует ~/.aws/credentials и ~/.aws/configи отправляет запросы в службу метаданных экземпляра EC2 по адресу 169.254.169.254Отдавая предпочтение IMDSv2, но при необходимости переключаясь на него. Для контейнерных нагрузок используется конечная точка метаданных ECS по адресу 169.254.170.2Любые учетные данные или временные токены, которые он получает, проверяются на соответствие. sts:GetCallerIdentity для подтверждения действительности перед постановкой в очередь на эксфильтрацию.
Аналогичная логика присутствует и у других облачных провайдеров. Скрипт может собирать Учетные данные клиента Azure и управляемые удостоверения, включая AZURE_CLIENT_ID, AZURE_CLIENT_SECRET и AZURE_TENANT_IDа затем, после аутентификации, получить доступ к Azure Key Vault, Azure Resource Manager и Microsoft Graph. Для Google Cloud выполняется поиск... GOOGLE_APPLICATION_CREDENTIALS файлы, запрашивает данные с сервера метаданных GCP по адресу metadata.google.internal и, по возможности, использует полученные токены для вызова Google Secret Manager. Развертывания HashiCorp Vault также входят в список: полезная нагрузка ищет адреса и токены Vault через переменные среды и файлы токенов, а затем запрашивает HTTP API Vault для перечисления доступных секретов.
Помимо управления идентификацией и доступом в облаке, вредоносная программа выполняет обширную Проверка файловой системы с использованием более 150 шаблонов glob.Он ищет закрытые ключи SSH, конфигурации Docker и т. д. .env файлы, хранилища учетных данных Git, .npmrc и .pypirc Он проверяет файлы, учетные данные Terraform и Cargo, файлы истории командной строки, данные криптовалютных кошельков и каталоги конфигурации для широко используемых мессенджеров, таких как Signal, Telegram Desktop, Discord, Slack и Element. Он также проверяет файлы конфигурации VPN от таких сервисов, как NordVPN, ProtonVPN, CyberGhost, PIA и других, а также токены и домены для менеджеров бинарных репозиториев, таких как JFrog Artifactory.
Эксфильтрация данных через репозитории GitHub и коммиты типа «мяу-мяу-мяу».
Собрав все эти секреты, вредоносной программе нужно место, куда их отправить. Вместо использования фиксированного домена управления, который можно легко заблокировать, злоумышленники полагаются на общедоступные репозитории GitHub в качестве канала для утечки данных , вплетая украденные данные в обычный поток трафика разработчиков.
В первую очередь вредоносная программа ищет в истории публичных коммитов GitHub сообщения, соответствующие определенному шаблону, который внедряет зашифрованный токен в открытом виде, используя фразу, ругающую пользователей за его аннулирование. После обнаружения такого коммита вредоносная программа расшифровывает внедренный токен и использует связанную с ним учетную запись для создания нового репозитория, где будут храниться украденные данные. Такая косвенная передача данных означает, что учетные данные, полученные от одной жертвы, сохраняются в репозиториях, технически принадлежащих другому пользователю GitHub, что затрудняет отслеживание сети скомпрометированных репозиториев до конкретной личности злоумышленника.
Вновь созданные репозитории имеют причудливые, автоматически сгенерированные имена состоит из двух персонажей из серии Touhou Project и случайного числа, в результате чего получаются такие комбинации, как... cirno-marisa-74291 or reimu-kogasa-12048Их описания содержат ту же фразу «Trinitite: Sponsored by Preview 2 Effects», что и в полезной нагрузке, являясь одним из немногих четких маркеров для защитников, пытающихся идентифицировать эти репозитории в больших масштабах.
Украденные учетные данные сохраняются в виде зашифрованных JSON-файлов внутри results/ каталог, используя имена файлов, начинающиеся с doubletrinnys- за которым следует счетчик и метка времени. Каждый файл содержит envelope поле, содержащее зашифрованный пакет данных и key Поле, содержащее сам ключ шифрования, дополнительно упаковано с использованием открытого ключа RSA злоумышленника. На первый взгляд, это выглядят как произвольные зашифрованные блоки данных. Только тот, у кого есть соответствующий закрытый ключ, может обратить процесс вспять, поэтому даже если хранилища будут найдены, Истинные секреты остаются непрозрачными для третьих лиц.Сообщения о коммитах обычно короткие и легкомысленные, с повторяющимися строками типа «мяу-мяу-мяу».
Распространение червя в другие пакеты npm и проекты GitHub.
Одним из наиболее тревожных аспектов кампании Trinitite является ее способность повторно использовать украденные токены для компрометации дополнительных пакетов и репозиториев . Вместо того чтобы ограничиваться оригинальным пакетом генератора кода TanStack Query, вредоносная программа ведет себя как червь, систематически ища способы распространения.
Имея действительный токен npm, вредоносная программа запрашивает API npm для перечисления всех токенов, связанных с учетной записью, выбирая наиболее привилегированный токен публикации. Затем она выполняет поиск каждого пакета, принадлежащего этому сопровождающему, загружает существующий архив tarball для каждого из них и внедряет в содержимое пакета тот же файл binding.gyp, содержащий уязвимость песочницы и основной файл полезной нагрузки. После внесения изменений она публикует новую версию в npm под именем законного сопровождающего, фактически превращая доверенные пакеты в новые векторы заражения . Аналогичное поведение реализовано для PyPI и RubyGems через их соответствующие конечные точки загрузки, при этом проверка сертификатов TLS отключена в исходящих запросах, чтобы избежать проблем с фиксацией на стороне клиента.
Репозитории GitHub обрабатываются аналогичным образом. Когда вредоносная программа получает токен GitHub с достаточной областью действия, она перечисляет все доступные репозитории и ветки, пропуская несколько известных веток автоматизации, например, те, которые имеют префикс. release/, dependabot/, renovate/ or copilot/Для остальных ветвей он добавляет набор тщательно отобранных файлов, которые служат как лазейками, так и точками доступа к современным инструментам разработки.
Среди них Встроенные бэкдоры в VS Code и конфигурационные файлы Claude, включая .vscode/tasks.json, .claude/settings.json и скрипты вроде setup.mjs Эти вредоносные программы запускаются, когда разработчик открывает проект в определенных редакторах с поддержкой ИИ. Вредоносное ПО также распространяет поддельный файл. .github/workflows/codeql.yml Этот рабочий процесс маскируется под проверку безопасности, предоставляя при этом еще один канал для выполнения кода внутри CI. Дополнительные файлы нацелены на другие редакторы и инструменты, такие как Gemini, Cursor и различные помощники по коду, что помогает злоумышленнику сохранять свое присутствие там, где фактически работают разработчики.
Каждый из этих коммитов создан под следующим именем: github-actions идентификация, с сообщениями, похожими на сообщения о плановом техническом обслуживании, например, «задача: обновить зависимости», и индикатором загрузки. skip-checks:true чтобы обойти необходимые проверки. Для занятой команды, бегло просматривающей журналы коммитов, эти изменения легко можно принять за... безобидные обновления автоматизации.
Индикаторы компрометации для команд, использующих инструменты TanStack Query.
Для организаций, использующих TanStack Query и интегрировавших @7nohe/openapi-react-query-codegen в свой рабочий процесс, выявление потенциальных уязвимостей начинается с индикаторов на уровне версий и файлов, на которые уже указали многочисленные источники. Эти подсказки могут помочь определить, в каких проектах мог быть запущен скомпрометированный код на этапах установки.
Любое использование указанных выше версий @7nohe/openapi-react-query-codegen следует рассматривать как подозрительное, особенно если сборки выполнялись на общей CI-инфраструктуре или ноутбуках разработчиков, имеющих доступ к конфиденциальным учетным данным. Группам безопасности рекомендуется проверить файлы блокировок, историю package.json и журналы сборок, чтобы подтвердить, были ли эти релизы когда-либо загружены в производственную или тестовую среду.
Ключевым признаком компрометации на диске является наличие файла 3FWCvzduYZg.js в корневом каталоге пакета . Исследователи задокументировали несколько хешей SHA-256, связанных с различными обфусцированными сборками этого скрипта, все они связаны с одной и той же базовой функциональностью:
- 8e5d1af68ca340ae0c6e8132cb00c686ec2d60502c1994d94ce353d1472ad5a3
- b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6
- 59370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380
- 778d6f0058045d6a2ab9a7e1d3e3be8e7e6b4d9cc217d13949bf1dfbab759a7c
- b24d121667f21f492cb9db34fbfd515d5922a8dd30b9c45215c7220abbb10ca8
- e1f1162ece9a6e6ea21a20399cbf31c563a8149d433a68711f4223870c203d5a
- b6012b2ff87f08f93ee53921c48db907ddbcf5461b03bb988083b01a36886237
- 709af2fdeb50324229e94c44c679a0fab18bd8e17d3864405989c526cbb63ad8
Кроме того, многие зараженные хосты создают временные каталоги с именами, начинающимися с trinnyyyy- Затем следует короткая последовательность случайных буквенно-цифровых символов во временной папке системы. Хотя сам по себе этот шаблон не доказывает компрометацию, в сочетании с подозрительным файлом binding.gyp и одним из известных хешей полезной нагрузки он значительно повышает вероятность того, что вредоносная программа Trinitite была запущена в этой системе.
Некоторые поставщики решений в области безопасности уже включили эти индикаторы в свои каналы обнаружения. Например, платформы, ориентированные на инструменты для разработчиков и безопасность цепочки поставок, теперь помечают любой репозиторий или проект, импортирующий затронутые версии, как критическую проблему вредоносного ПО , часто присваивая ему максимальный уровень серьезности для немедленного расследования. Командам рекомендуется проводить повторное сканирование в масштабах всей организации, особенно в средах, где TanStack Query играет центральную роль в архитектуре приложений, а инструменты генерации кода широко используются.
Появляются специализированные инструменты и утилиты с открытым исходным кодом, которые работают поверх npm, yarn, pnpm и связанных с ними менеджеров пакетов, проверяя версии пакетов на соответствие тщательно отобранным источникам информации перед установкой. Идея заключается в перехвате вредоносных или подозрительных пакетов, особенно тех, которые связаны с инцидентами, подобными этому, еще до того, как они попадут в систему. node_modules, снижая риск того, что скомпрометированная вспомогательная библиотека может косвенно раскрыть информацию. Приложения TanStack, работающие на основе запросов и связанной с ними инфраструктуры.
Для команд разработчиков этот инцидент подчеркивает, как, казалось бы, безобидный пакет — тот, который просто генерирует типизированные хуки для TanStack Query на основе спецификации OpenAPI — может стать мощным вектором атаки, если его конвейер CI и канал распространения будут взломаны. Теперь меры защиты должны выходить за рамки проверки основных зависимостей приложения и включать генераторы, CLI и скрипты автоматизации, которые незаметно формируют то, как эти зависимости используются каждый день.