TL, д-р
Один оператор npm витратив шість тижнів на публікацію фальшивих пакетів «утиліт» TypeScript, таких як ts-form-utils, ts-project-lint та ts-enum-helper.
Хоча пакети надають невеликі помічники валідації, що виглядають легітимно, справжнє корисне навантаження виконується під час встановлення або першого запиту та виконує відбитки пальців хоста, виявлення організації GitHub, клонування репозиторію та вилучення вихідного коду.
Шкідливе програмне забезпечення спеціально націлене на високоцінні організації GitHub, включаючи кілька Shopify репозиторії, потім архівує та вилучає доступні дерева вихідних кодів до централізованої кінцевої точки колекції.
Як частина робочого процесу компрометації, корисне навантаження commitsa-файл назад до репозиторіїв жертви, видаючи себе за автономну ідентичність кодування Google google-labs-jules[bot].
Ми відстежували кампанію — названу ДжулсДжекер — для кількох видавців та щонайменше п’яти поколінь корисного навантаження, включаючи зашифровані варіанти та варіанти з підтримкою ізольованого програмного середовища.
Найновіший варіант спеціально націлений на інфраструктуру аналізу шкідливих програм: він активується лише всередині середовищ аналізу, краде токени облікових записів служб хмарних метаданих та досліджує площини керування Kubernetes і хмарні сховища.
Основним IOC, спільним для всіх поколінь корисного навантаження, є кінцева точка колекції. aaronstack[.]com/jules-collect.
Ступінь тяжкості: критичний.
Атака: як це працює
Кожен пакет JulesJacker дотримується одного й того ж шаблону. package.json рекламує безпечний помічник TypeScript з ліцензією MIT та без посилання на репозиторій вихідного коду. index.js експортує кілька реальних, робочих функцій — регулярні вирази електронної пошти, карти перерахувань, таблиці правил lint — щоб розробник, який фактично імпортує пакет, бачив правдоподібну поведінку. Зловмисність криється деінде: у після встановлення гачок або в блоці внизу index.js який виконується в момент, коли модуль потрібен.
Корисні навантаження пройшли чітко пронумеровані внутрішні етапи (оператор сам позначає свої телеметричні події sc1-, sc3-, sc4-тощо), і спостереження за цією еволюцією – найчіткіший спосіб зрозуміти кампанію.
Покоління 1–2: розвідка та крадіжка git-конфігурації
Найперші пакети були простими інфостеалами. Під час встановлення вони збирали змінні середовища, файл hosts командного рядка GitHub та глобальну конфігурацію git (git config –global –list, git віддалений -v), а потім відправив пакет до кінцевої точки колекції за допомогою POST. Це закріпило підпис оператора: історія-обкладинка «утиліти перевірки форм TypeScript», вихідний маяк для одного домену та схильність до облікових даних розробника, а не до даних споживачів.
Покоління 3: гіпервізор та зонди виходу ядра
Одна версія в середині кампанії різко перейшла до атак на інфраструктуру. Замість красти конфігурацію, вона виконала розвідувальне зондування дротяних систем. AF_VSOCK сокети, регіони virtio MMIO, / dev / mem, а також прапори посилення захисту ядра, і навіть спроби збоїв ядра, спричинених sysrq — поведінка, пов'язана зі спробами вийти з віртуальної машини або контейнера. Теги телеметрії (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, s3-kernel-probe) чітко висловив намір. Цей варіант був явно спрямований на хмарні середовища з ізольованим середовищем та безсерверні середовища — вид тимчасової віртуальної машини, яка створює та тестує ненадійний код.
Покоління 3 (SC3): черв'як для запису з перехресними репозиторіями
Центром ваги кампанії став саморозповсюджувач репозиторіїв. Після встановлення корисне навантаження виконує п'ятиетапну часову послідовність:
- Етап 0 (~100 мс): відбиток хоста — ім'я хоста, інформація про користувача, ідентифікатор git.
- Етап 1 (~3 с): визначити, до якої організації належить жертва, шляхом перевірки git віддалений -v, а потім знайдіть жорстко закодований ORG_CONFIG доступ до таблиці та тестового репозиторію за допомогою git ls-remote — маршрутизується через контрольований зловмисником проксі-сервер SSRF за адресою http://git@192.168.0.1:8080.
- Етап 2 (~10 с): гіт-клон кожен доступний репозиторій у цільовому списку, зархівувати дерево за допомогою tarball та gzip, закодувати його в base64 та вилучити фрагменти.
- Етап 3 (~45 с): «підтвердження доступу» — клонувати репозиторій з можливістю запису, скинути файл з назвою SECURITY-POC.md та commit його з автором, встановленим на google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>, та завданням повідомлення: оновити кеш залежностей, а потім надіслати до основної гілки жертви.
Жорстко запрограмований список цілей не є універсальним. Він містить понад тридцять Shopify репозиторії за назвою — Shopify/shopify, Shopify/ідентичність, Shopify/виставлення рахунків, Shopify/сховище, Shopify/секрети, Shopify/інфраструктура, Shopify/.githubта багато іншого — поряд з тестовою організацією, АаронСтекБарнс, який, здається, контролює оператор і використовує як ціль запису.
Покоління 4 (SC4): зашифроване та закрите
Найновіший варіант, орієнтований на розробників, додає два рівні ухилення поверх черв'яка SC3.
По-перше, корисне навантаження більше не постачається у вигляді відкритого тексту. Справжня логіка знаходиться в блобі, зашифрованому за допомогою AES-256-CBC. lib/.perf.dat, з IV у перших шістнадцяти байтах. Завантажувач у index.js реконструює ключ розшифрування з об'єднаних фрагментів рядків, розшифровує блоб та запускає його з нова функція()Навіть назви модулів розділені, щоб уникнути статичних сканерів — вимагати('крипта' + 'o'), вимагати('f' + 's').
По-друге, він обмежений хостом. Один варіант розшифровується та запускається лише тоді, коли ім'я_хоста_os.() дорівнює розробницька панель or ubuntu-fc-uvm (за замовчуванням Firecracker microVM) або містить підрядок розробницька панельЩе одні ворота на наявність .jules/ робочий каталог:
Іншими словами, корисне навантаження SC4 розроблене таким чином, щоб залишатися в режимі сну на звичайному ноутбуці розробника та прокидатися лише всередині автоматизованого агента штучного інтелекту. середовища пісочниці оператор насправді хоче компромісу.
Увімкнення лабораторії: варіант інфраструктури аналізу
Найновіший пакет кампанії, ts-enum-helper, взагалі не атакує розробників чи Shopify. Його postinstall.sh відкривається воротами, які видають гру:
Скрипт нічого не робить, якщо не встановлено змінну середовища, специфічну для платформи аналізу шкідливих програм. Коли це встановлено, корисне навантаження знає, що воно працює всередині пісочниці, яка існує для детонації та вивчення пакетів, подібних до цього, і контратакує.
Спочатку він витягує токен OAuth облікового запису служби GCP із сервера метаданих екземпляра та вилучає його. Потім, використовуючи цей токен, він очищує Площина керування Kubernetes доступний за адресою kubernetes.default.svc:
- перераховує прив'язки ролей кластера (ClusterRoleBindings), ролі кластера (ClusterRoles) та вузли (Nodes);
- зондує поди, секрети та карти конфігурацій kube-система, дефолт, kube-public, оренда вузла kube, та простір імен аналізу;
- видає виклики SelfSubjectAccessReview, щоб точно визначити, що дозволено робити викраденій особистості.
Зрештою, він перебирає імена корзин Google Cloud Storage, створені на основі жорстко закодованого ідентифікатора проекту GCP (rare-signer-437603-p9) та номер проекту, вгадуючи такі комбінації, як *-збірки, *-артефакти, і кілька параліч- префікси (результати-малізу, пакети malysis, сканування-малізу). Кожен код та тіло відповіді реєструються та надсилаються назад до того ж jules-collect кінцева точка.
Це рідкісний випадок, коли корисне навантаження ланцюга поставок було створено спеціально для атаки на власну інфраструктуру захисників. Прикриття всієї кампанії — фрагменти якої з'являються всередині корисних навантажень як коментарі, що описують поведінку як «Security Research PoC … перехресний запис у репозиторій через перевантажений токен проксі-сервера git» — є тим самим самовиправданням, незалежно від того, чи є цільовою групою монорепозиторій Shopify, чи сервер метаданих кластера аналізу.
Хронологія та міграція сфери застосування
JulesJacker — це не одноразове зникнення. Це стабільна операція, яка пережила видалення з реєстру, просто змінивши свою назву.
| Коли | Event |
|---|---|
| Середина квітня 2026 року | Перші пакети з'являються в оригінальній області дії видавця: TS-utility facade, environment та git-config exfiltration. |
| Початок травня 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 та фрагменти tar-архівів репозиторію 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 | BLOB-об'єкт корисного навантаження, зашифрований за допомогою 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. |




