Эктоплазма npm Install Hooks Кража учетных данных AWS

Эктоплазма: npm install hooks которые собирают учетные данные AWS, используя триггер, срабатывающий только в контейнере.

TL, д-р

Группа пять пакетов npmОпубликовано в двух учетных записях, отправлено postinstall Этот хук считывает учетные данные облака с хоста и отправляет их за пределы сервера. Пакеты имеют псевдонимы и пиратские имена — coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit — и превратить все собранное ими в подделку, используя серийный номер. ecto_module: YAML-манифест перед передачей. Мы отслеживаем кластер следующим образом: флюид.

Полезная нагрузка запускается только при обнаружении определенной среды: хоста, имя которого является 12-символьная шестнадцатеричная строка и рабочий каталог в /app/node_modules — структура контейнеризированной сборки или CI-воркера. Когда этот этап пройден, хук запрашивает информацию у Сервис метаданных экземпляров AWS (IMDSv2) для учетных данных роли IAM, перечисляет Менеджер секретов AWS в трех регионах, выгружает переменные среды, читает файлы в /appи собирает строки для захвата флага. Затем он передает результат двумя способами: от маяка к webhook.site Сборщик данных и PUT-запрос манифеста к конечной точке с необработанным IP-адресом, а также список резервных вариантов, начинающихся с localhost.

В более поздних описаниях пакетов указано: «Полезная нагрузка CTF для тестирования цепочки поставок Verdaccio». Мы сообщаем об этом самоописании как о наблюдаемом факте. Само поведение — исходящий трафик на публичный IP-адрес, реальное чтение учетных данных IMDS, реальные вызовы Secrets Manager — остается тем, чем оно является, независимо от метки, и именно поэтому эти версии были классифицированы как вредоносные.

В этой группе всего одно имя. coral-wraithИгра не ограничилась одним релизом. Она переиздавалась в быстрой последовательности, выпуская десятки версий за считанные часы. 1.0.0 восхождение на 6.0.0 — а в более ранней версии с тем же названием использовались надувные 9999.0.x номера версий, классическая форма попытка вызвать путаницу зависимостейВ процессе этих изменений полезная нагрузка заметно повзрослела: из одноразового маяка для перечисления хостов она превратилась в полноценную систему аутентификации по учетным данным AWS, защищенную проверками среды, которые не позволяют ей оставаться незамеченной за пределами целевого объекта.

Packages5 имен; coral-wraith один был переиздан в десятках версий
ЭкосистемаНПМ
Установить векторpostinstall скрипт жизненного цикла
Основная цельУчетные данные роли AWS IAM + значения секретов Secrets Manager, переменные среды. /app файлов
изгнаниеwebhook.site маяк + необработанный IP C2 PUT
Затвор триггера12-шестнадцатеричное имя хоста + /app/node_modules текущий рабочий каталог (cwd), а также проверка окружения, которая подавляет полезную нагрузку вне этого контекста.
Строгостьвысокая — раскрытие учетных данных облачного сервиса и управляемого секрета от контейнеризированные среды сборки и выполнения

Анатомия атаки

Каждый пакет в кластере собирается одинаково: практически пустой index.js (модуль.экспорт = {}), в одну строку пакет.json сценарий — “postinstall”: “node postinstall.js” — и полезная нагрузка в postinstall.jsДля запуска хука достаточно установить пакет; импорт или вызов не требуются.

Наведение на цель. Прежде чем что-либо предпринять, полезная нагрузка семейства эктоплазмы проверяет окружающую среду:

function isAppWorker():   host = os.hostname()   if host does NOT match /^[0-9a-f]{12}$/  -> exit   if cwd does NOT contain "/app/node_modules" -> exit   if cwd contains "/tmp/npm-safe"            -> exit   otherwise -> proceed

12-значное шестнадцатеричное имя хоста — это стандартная форма, которую Docker присваивает контейнеру. /app/node_modules Это обычный путь установки внутри контейнера. Третий пункт прерывается, если путь выглядит как изолированная директория для извлечения. В результате полезная нагрузка остается в спящем режиме на ноутбуке разработчика или в песочнице для анализа и активируется только внутри контейнеризированного рабочего процесса сборки или выполнения — среды, в которой, скорее всего, будут использоваться учетные данные для работы с облаком. Самый ранний пакет в кластере, коралловый призрак, не имеет такого вентиля и запускает свою (более простую) коллекцию безусловно.

Когда ворота проходят, крюк выдвигается наружу. execFileSync(“/bin/sh”, [“-c”, …]) и выполняет единую составную команду, которая в указанном порядке:

1. PUT /latest/api/token to 169.254.169.254          (IMDSv2 token request) 2. GET .../iam/security-credentials/                  (IAM role name) 3. GET .../iam/security-credentials/<role>            (temporary credentials) 4. dump env | sort                                    (environment variables) 5. list /app (excl. node_modules) + cat first 15      (application files) 6. aws secretsmanager list-secrets                    (us-east-1, eu-west-1, eu-central-1) 7. scrape readable files for HTB{...}                 (capture-the-flag strings)

Шаги 1–3 представляют собой стандартную процедуру получения IMDSv2: запросить токен сессии, а затем прикрепить его в качестве параметра. X-aws-ec2-metadata-token Заголовок для получения роли IAM экземпляра и временных ключей доступа этой роли. Выбор в пользу реализации IMDSv2 вместо более простого неаутентифицированного IMDSv1. ПОЛУЧИТЬ Стоит отметить, что это означает, что полезная нагрузка работает даже на экземплярах, настроенных на использование доступа к метаданным на основе токенов, что является рекомендуемым AWS усилением безопасности. Учетные данные, возвращаемые на шаге 3, имеют кратковременный срок действия. AccessKeyId/Секретаксесскей/Токены Тройки, ограниченные ролью экземпляра; все, что может делать эта роль, может делать владелец этих ключей в течение всего срока действия учетных данных.

Шаги 4–6 расширяют охват. окр Дамп содержит все данные, унаследованные процессом сборки или выполнения — на практике здесь чаще всего хранятся токены реестра, строки подключения к базе данных и ключи API. / приложение file walk считывает до пятнадцати файлов приложения извне. node_modules, которая может отображать конфигурацию, .env файлы или источник. Шаг 6 вызывает aws secretsmanager list-secrets в трех регионах; учетные данные, полученные на шагах 1–3, в точности соответствуют аутентификации этих вызовов, поэтому чтение IMDS и цепочка перечисления Secrets Manager объединяются в единую эскалацию: роль экземпляра → инвентаризация управляемых секретов. Шаг 7 — это отсылка к стратегии «захвата флага» — когда HTB{…} Если флаг найден, он отправляется отдельно, в противном случае собранный исходный блок данных разбивается на четыре части и отправляется отдельно.

Более поздние версии в кластере развивают эту функцию дальше. Вместо того чтобы останавливаться на инвентаризации, они анализируют ответ IMDS и экспортируют временные ключи. AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN переменные среды, подтвердите личность с помощью aws sts получить идентификатор вызывающего абонентаа затем пройтись циклом по каждому секретному ключу, возвращенному функцией. список секретов требуют aws secretsmanager get-secret-value на каждом — извлекая секретное содержимое, а не только их названия. Те же версии также считывают бинарные файлы флагов, замененные в процессе./readflag и друзей) и попытаться зарядный пробег против любого проекта Rust, найденного в / приложениерасширяя возможности сбора данных за пределы облачных учетных данных и охватывая все, что предоставляет среда сборки.

Эти более поздние версии также более агрессивно ограничивают себя. В дополнение к 12-хеш-имя хоста и /app/node_modules В ходе проверок полезная нагрузка анализирует активную конфигурацию реестра пакетов и путь к рабочему каталогу и молча завершает работу, когда они указывают на контекст анализа или зеркалирования, а не на действующий целевой объект. В результате полезная нагрузка не делает ничего заметного в большинстве сред проверки и выполняет полный сбор данных только там, где, по ее мнению, она находится на подлинном контейнеризированном хосте.

эксфильтрацииСобранные данные передаются на хост по двум каналам. Во-первых, через маяк. POST к фиксированной вебхук.сайт Сборщик данных, содержащий имя хоста, числовой UID, рабочий каталог и до 120 КБ собранных данных. Во-вторых, данные объединяются в фиктивный YAML-«манифест модуля». ПОЛОЖИЛ в /api/modules/ на целевом сервере:

ecto_module:   name: "<flag-or-chunk-0>"   version: "1.0.0"   power_level: "<chunk-1>"   ship_deck: "<chunk-2>"   cargo_hold: "<chunk-3>"

Названия полей манифеста (уровень мощности, палуба корабля, грузовой трюм) являются декоративными элементами — украденные данные находятся внутри строковых значений, поэтому сетевой монитор видит то, что выглядит как безобидная загрузка манифеста реестра пакетов, а не как очевидный сброс данных. Канал маяка передает больше: POST тело к вебхук.сайт Включает имя хоста, числовой UID, рабочий каталог и до 120 КБ собранного BLOB-объекта, поэтому даже один успешный отправитель сигнала обеспечивает получение полной информации. вебхук.сайт Это бесплатный сервис для проверки запросов; использование его в качестве сборщика означает, что оператору никогда не придется развертывать собственную приемную инфраструктуру для этого канала, а записанные запросы сохраняются в корзине сервиса.

Манифест ПОЛОЖИЛ включает в себя список запасных вариантов, начинающийся с нескольких 127.0.0.1/локальный порты, а затем происходит переключение на три публичных адреса в `154.57.164.0/24` Диапазон запросов, с остановкой на первой конечной точке, которая отвечает статусом 2xx. Порядок «сначала локальный хост» соответствует самоописанию «тестирования Verdaccio» (локальный реестр на Loopback), но резервные варианты с публичным IP-адресом означают, что данные покидают хост всякий раз, когда Loopback не прослушивается — то есть на любой машине, кроме собственной тестовой установки автора.

Лента

В кластере наблюдается постепенный рост возможностей, а не единовременное снижение. Мы ранжируем его по наблюдаемому поведению, а не по опубликованным данным:

ЭтапПакеты / ВерсииПоведение
Ранний забегcoral-wraith 9999.0.xЗавышенные номера версий, соответствующие попытке ввести в заблуждение пользователей относительно зависимостей; перечисление и извлечение данных во время установки.
Сидcoral-wraith 1.0.0postinstall собирает файлы id/env/flag; выполняется один PUT-запрос для... 154[.]57[.]164[.]71:30782маркер ECT-472839
Быстрая итерацияcoral-wraith 1.0.1 → 6.0.0Десятки релизов за несколько часов; полезная нагрузка получает isAppWorker() ворота, получение учетных данных IMDSv2, полный get-secret-value сводная таблица, проверка среды реестра/пути и маркеры двойного приемника
Параллельные именаecto-corsair-whisper-6f3b9 1.0.14–1.0.18Та же полезная нагрузка с шлагбаумом; webhook.site список резервных точек для маяков и многоточечных систем
Вариантыecto-rust-read-f3a9c1 1.0.1–1.0.2Добавляет дополнительные маркеры для раковины. ECT-987654, ECT-654321, ECT-839201
Вариантыecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0Та же полезная нагрузка с шлагбаумом, тот же центр управления и связи и маяк.

Отличительной чертой кластера является ритм публикации: вместо одного пакета и одной версии, одно и то же имя переиздается снова и снова с небольшой периодичностью, каждый релиз представляет собой небольшую вариацию предыдущего, наряду с несколькими другими пакетами с другими названиями, содержащими тот же контент. Внутри кластера шептать В семействе кодов произошел разрыв на два близких по характеристикам варианта — один набор активирует два критических обнаружения, другой — три (дополнительный обработчик чтения файла), — но оба приводят к одной и той же полезной нагрузке; разница заключается в изменении кода, а не в поведенческом форке. Версии шептать За пределами анализируемого диапазона (по крайней мере, до 1.0.25 на момент написания статьи) в режиме реального времени наблюдались данные в реестре, и коралловый призрак Название продолжало подниматься по лестнице версий в том же окне.

Индикаторы компромисса

Все приведенные ниже индикаторы были извлечены из исходного кода пакета на диске. Сетевые индикаторы обезличены.

Cеть

ИндикаторныеРоли
hxxp://154[.]57[.]164[.]71:30782Цель C2 PUT (coral-wraith)
hxxp://154[.]57[.]164[.]80:30543Резервный вариант C2 PUT (ecto-*)
hxxp://154[.]57[.]164[.]82:31250Резервный вариант C2 PUT (ecto-*)
hxxp://154[.]57[.]164[.]71:31289Резервный вариант C2 PUT (ecto-*)
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5Коллекционер маяков
169[.]254[.]169[.]254/latest/...Чтение учетных данных IMDSv2 (на стороне целевого устройства, метаданные AWS)

Поведенческий/файл

ИндикаторныеРоли
"postinstall": "node postinstall.js"Установить вектор
ecto_module: YAML с power_level / ship_deck / cargo_hold ключиСхема манифеста Exfil
Маркеры для раковины ECT-472839, ECT-987654, ECT-654321, ECT-839201Сегмент пути C2 /api/modules/<marker>
isAppWorker() ворота: хост /^[0-9a-f]{12}$/, cwd содержит /app/node_modulesУсловие активации
aws secretsmanager list-secrets за us-east-1, eu-west-1, eu-central-1перечисление секретов
HTB{...} регулярные выражения для сбора данныхУрожай в рамках операции «Захват флага»

Хэши файлов (sha256, полученные во время анализа)

Файлsha256
coral-wraith/postinstall.jsce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.jsb58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3

Атрибуция и наблюдаемое поведение

Пять названий пакетов были опубликованы под двумя учетными записями npm, но они используют достаточно общую инфраструктуру, чтобы рассматривать их как один кластер: один и тот же. ecto_module схема манифеста, та же самая ЭСТ-472839 основной маркер раковины, тот же самый вебхук.сайт Идентификатор сборщика и конечные точки C2 находятся в одном и том же месте. Блок 154.57.164.0/24. Пакет семян (`coral-wraith`)(более простые и без ограничений) и, таким образом, семейство эктоплазматических организмов с ограничениями воспринимается скорее как итерации одного инструментария, чем как независимые разработки.

В более поздних версиях эти пакеты описывают себя следующим образом: «Полезная нагрузка CTF для тестирования цепочки поставок Verdaccio». Мы представляем эту метку как наблюдаемый факт и не переформулируем её как вывод о цели. Действия кода однозначны и не зависят от того, как он обозначен: он считывает учетные данные ролей IAM из службы метаданных экземпляра, перечисляет управляемые секреты в трёх регионах AWS и передаёт результаты на публичный IP-адрес и стороннему сборщику веб-хуков. В тестовой среде, использующей только локальный доступ, не потребуется список резервных публичных IP-адресов, чтение учетных данных IMDS или вызовы Secrets Manager между регионами. Поскольку исходящий трафик и доступ к учетным данным реальны, версии с ограниченным доступом были классифицированы как вредоносные.

Наиболее заметной с оперативной точки зрения особенностью является ограничение доступа только для контейнеров. Это одновременно и мера обхода (сохранение анонимности на ноутбуках и в аналитических песочницах), и мера целевого воздействия, срабатывающая только там, где наиболее вероятно наличие реальной роли IAM и действующих секретов. Аналитики, запускающие эти пакеты в обычной песочнице, ничего не заметят; такое поведение проявляется только при использовании имени хоста в стиле Docker и пути установки внутри контейнера.

Влияние, тенденции и рекомендации для защитников

В данном случае речь идёт о раскрытии облачных учётных данных и секретной информации внутри контейнеров сборки и выполнения. Учётные данные роли IAM, полученные из IMDS, содержат все разрешения, которыми обладает эта роль; secretsmanager:ListSecrets (и любые последующие) GetSecretValueЭто расширяет область действия до хранимых секретов приложений. Дампы переменных окружения часто содержат токены реестра, URL-адреса баз данных и ключи API. В контексте CI или контейнеризации — именно то, что выбирает шлюз — одной транзитивной установки одного из этих пакетов достаточно, чтобы произошла утечка этой информации.

Ectoplasm соответствует наблюдаемой нами закономерности: вредоносные программы, устанавливаемые во время работы, обращаются к облачным метаданным и управляемым секретам, а не к локальным файлам, и срабатывают только в средах с высокой ценностью. Далее следуют два замечания по поводу защиты.

  • Форма различима.. Хук установки npm/PyPI, граф вызовов которого обращается как к API облачных секретов (aws secretsmanager, секреты gcloud, az keyvault) или адрес IMDS и сетевой исходящий приемник представляют собой узкий, высокосигнальный шаблон — он почти никогда не встречается в легитимном скрипте жизненного цикла. Анализ статического потока Можно пометить это независимо от конкретного домена или IP-адреса.
  • Ужесточение экологических норм ослабляет его. Применение протокола IMDSv2 с ограничением количества переходов до 1 предотвращает доступ контейнерных рабочих нагрузок к метаданным экземпляра; ограничение ролей IAM минимальными привилегиями снижает вероятность утечки учетных данных; а запуск установок с использованием –Ignore-scripts В системе непрерывной интеграции полностью удаляется вектор install-hook для пакетов, которым он не нужен.

Для специалистов по кибербезопасности практические проверки сводятся к следующему: оповещение об исходящих соединениях из контейнеров сборки/CI с незарегистрированными публичными IP-адресами во время выполнения запроса. Установка npm; следите за доступом к IMDS, исходящим из скриптов жизненного цикла пакетов; и рассматривайте любой обработчик установки, который обращается к облачному CLI, как подозрительный, пока не будет доказано обратное.

Еще два замечания, касающиеся именно этого кластера. Во-первых, поскольку активация ограничена контейнеризированными средами, пакет, который кажется неактивным при проверке на рабочей станции, все еще может быть активен в производственной среде — проверка должна воспроизводить условия имени хоста и пути контейнера или считывать исходный код напрямую, а не полагаться на «я установил его, и ничего не произошло». Во-вторых, использование общедоступной службы проверки запросов в качестве сборщика маяков означает, что часть украденных данных может быть восстановлена ​​для реагирования на инциденты: организация, обнаружившая один из таких пакетов в своем дереве зависимостей, может рассуждать о том, что содержал бы успешный маяк, исходя из логики сбора полезной нагрузки, и должна ротировать любые учетные данные ролей IAM, токены реестра и управляемые секреты, которые были доступны из затронутой среды сборки или выполнения. ротация учетных данныхПосле завершения установки оперативной мерой по устранению проблемы является не удаление пакета, а именно его замена.

sca-инструменты-программное обеспечение-композиция-анализ-инструменты
Расставьте приоритеты, устраните и защитите риски, связанные с программным обеспечением
Получите бесплатный аккаунт.
Нет необходимости кредитную карту.

Защитите свою разработку и доставку программного обеспечения

с пакетом продуктов Xygeni