ТЛ; ДР
Група пет npm пакета, објављено преко два налога, послато postinstall кука која чита cloud акредитиве са хоста и шаље их ван кутије. Пакети носе лажна имена — 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 улоге, набраја АВС Сецретс Манагер кроз три региона, приказује променљиве окружења, чита датотеке под /appи претражује низове за снимање заставице. Затим извлачи резултат на два начина: као светионик ка webhook.site колектор и манифест PUT на крајњу тачку са сировим IP-ом, са листом резервних опција за localhost-first.
Каснији описи пакета гласе „CTF терет за тестирање ланца снабдевања Verdaccio“. Тај самоописи извештавамо као уочљиву чињеницу. Само понашање — уживо излаз на јавну IP адресу, стварно читање IMDS акредитива, стварни позиви менаџера секрета — је оно што јесте без обзира на ознаку и то је разлог зашто су ове верзије класификоване као злонамерне.
Једно име у групи, coral-wraith, није се зауставио на једном издању. Поново је објављиван у брзом низу кроз десетине верзија за само неколико сати — 1.0.0 пењући се на 6.0.0 — и ранија серија истог имена користила је надувани 9999.0.x бројеви верзија, класични облик покушај забуне зависностиПреко тог превирања, корисни терет је видљиво сазрео: од једнократног сигнала за набрајање хостова до потпуног AWS ослонца за акредитиве обавијеног проверама окружења које га држе тихим ван његове предвиђене мете.
| Пакети | 5 имена; coral-wraith сам поново објављен у десетинама верзија |
| Екосистем | нпм |
| Инсталирајте вектор | postinstall скрипта животног циклуса |
| Примарни циљ | Акредитиви за AWS IAM улогу + тајне вредности менаџера секрета, променљиве окружења, /app датотеке |
| Екфил | webhook.site beacon + raw-IP C2 PUT |
| Окидачка капија | 12-хексадецимално име хоста + /app/node_modules cwd, плус провера окружења која потискује корисни терет ван тог контекста |
| Озбиљност | висок — откривање акредитива у облаку и управљаних тајни од контејнеризована окружења за изградњу и извршавање |
Анатомија напада
Сваки пакет у кластеру је изграђен на исти начин: скоро празан индек.јс (модул.извоз = {}), једноредни пацкаге.јсон скрипта — „postinstall“: „чвор 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 додељује контејнеру, и /апликација/модули_чвора је конвенционална путања инсталације унутар контејнера. Трећа клаузула се искључује ако путања изгледа као директоријум за екстракцију у заштићеном простору. Крајњи ефекат је да корисни терет остаје неактиван на лаптопу програмера или у заштићеном простору за анализу и активира се само унутар контејнеризованог процеса изградње или извршавања — врсте окружења које највероватније носи активне cloud акредитиве. Најранији пакет у кластеру, корални дух, нема такву капију и покреће своју (једноставнију) колекцију безусловно.
колекцијаКада капија прође, кука се извлачи кроз њу execFileSync(“/бин/сх”, [“-ц”, …]) и покреће једну сложену команду која, редом:
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 су краткотрајни. АццессКеиИд/СецретАццессКеи/Жетон тројке ограничене на улогу инстанце; шта год та улога може да уради, власник тих кључева може да уради током животног века акредитива.
Кораци 4–6 проширују обим. енв dump бележи све што је процес изградње или извршавања наследио — у пракси је то место где се најчешће налазе токени регистра, низови за повезивање са базом података и API кључеви. / апликација File Walk чита до петнаест датотека апликације споља ноде_модулес, који може површинску конфигурацију, .енв датотеке или извор. Корак 6 позива aws tajnemenadžer lista-tajne у три региона; акредитиви преузети у корацима 1–3 су управо оно што аутентификује те позиве, тако да се IMDS читање и набрајање Менаџера тајни спајају у једну ескалацију: улога инстанце → инвентар управљаних тајни. Корак 7 је климање главом уоквиривању „снимај-заставицу“ — када ХТБ{…} Ако се пронађе заставица, шаље се сама, у супротном се сирови прикупљени блоб дели на четири дела и шаље.
Касније верзије у кластеру даље преносе ескалацију. Уместо да се зауставе на инвентару, оне анализирају IMDS одговор, експортују привремене кључеве као АВС_АЦЦЕСС_КЕИ_ИД / АВС_СЕЦРЕТ_АЦЦЕСС_КЕИ / АВС_СЕССИОН_ТОКЕН променљиве окружења, потврдите идентитет са AWS STS преузимање идентитета позиваоца, а затим петљом прелази преко сваке тајне која се враћа од стране тајне-листе позивање aws tajni menadžer preuzmi-tajnu-vrednost на сваком — преузимајући тајни садржај, не само њихова имена. Исте верзије такође читају бинарне датотеке са заставицама замењеним процесом (/readflag и пријатељи) и покушајте пуњење рун против било ког Rust пројекта који се налази под / апликација, проширујући прикупљање података изван cloud акредитива на све што окружење за изградњу открива.
Ове касније верзије се такође агресивније затварају. Поред 12-хексадецималног имена хоста и /апликација/модули_чвора Провере, корисни терет прегледа активну конфигурацију регистра пакета и путању радног директоријума и тихо се излази када указују на контекст анализе или огледала, а не на активну мету. Комбиновани ефекат је корисни терет који не ради ништа што се може уочити у већини окружења за инспекцију и покреће своју пуну колекцију само тамо где процени да се налази на правом контејнеризованом хосту.
ЕксфилтрацијаПрикупљени подаци напуштају хост на два канала. Прво, сигнални уређај ПОСТ до фиксног вебхук.сајт колектор, који садржи име хоста, нумерички UID, радни директоријум и до 120 KB прикупљених података. Друго, подаци се спајају у лажни 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>" Имена поља манифеста (ниво_снаге, палуба_брода, теретни простор) су декорација — украдени подаци се налазе унутар стринг вредности, због чега мрежни монитор види оно што изгледа као бенигно отпремање манифеста регистра пакета, а не очигледан дамп података. Канал „beacon“ преноси више: ПОСТ тело да вебхук.сајт укључује име хоста, нумерички UID, радни директоријум и до 120 KB прикупљеног блоба, тако да чак и један успешан beacon пружа комплетан снимак. вебхук.сајт је бесплатна услуга прегледа захтева; коришћење као сакупљача значи да оператер никада не мора да изгради сопствену инфраструктуру за пријем тог канала, а забележени захтеви остају у корпи сервиса.
Манифест ПУТ пролази резервну листу која почиње са неколико 127.0.0.1/лоцалхост портова, а затим се пробија до три јавне адресе у `154.57.164.0/24` опсег, заустављајући се на првој крајњој тачки која одговори са статусом 2xx. Редослед localhost-first је у складу са самоописом „verdaccio testing“ (локални регистар на loopback-у), али резервне public-IP адресе значе да подаци напуштају хост кад год loopback не слуша — то јест, на било којој машини која није ауторов сопствени тестни систем.
Тимелине
Кластер показује постепени раст капацитета, а не појединачни пад. Поређали смо га по посматраном понашању, а не по времену објављивања:
| Стаж | Пакети / Верзије | Понашање |
|---|---|---|
| Рано трчање | coral-wraith 9999.0.x | Надувавање бројева верзија у складу са покушајем забуне око зависности; набрајање при инсталацији и exfil |
| Семе | coral-wraith 1.0.0 | постинсталација прикупља id/env/flag датотеке; један PUT за 154[.]57[.]164[.]71:30782, маркер ECT-472839 |
| Брза итерација | coral-wraith 1.0.1 → 6.0.0 | Десетине ослобађања за сате; корисни терет добија isAppWorker() капија, IMDSv2 преузимање акредитива, пуна get-secret-value pivot, провера окружења регистра/путање и маркери двоструког сливника |
| Паралелна имена | 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 | Исти затворени корисни терет, исти C2 и светионик |
Кључна карактеристика кластера је његова ритам објављивања: уместо једног пакета и једне верзије, исто име се поново објављује изнова и изнова у брзом низу, свако издање је мала варијација претходног, уз неколико различито названих браће и сестара који носе исти корисни терет. Унутар шапат Породица кода се поделила на два блиска отиска прста — један сет који активира две критичне детекције, други три (додатни сливник за читање датотеке) — али оба се решавају на исти корисни терет; разлика је померање кода, а не бихевиорална форк. Верзије шапат ван анализираног опсега (до најмање 1.0.25 у време писања) примећени су уживо у регистру, и корални дух Име је наставило да се пење на сопствену лествицу верзија преко истог прозора.
Индикатори компромиса
Сви доленаведени индикатори су издвојени из изворног кода пакета на диску. Мрежни индикатори су дефастовани.
мрежа
| Индикатор | Улога |
|---|---|
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, снимљени у време анализе)
| Фајл | схаКСНУМКС |
|---|---|
coral-wraith/postinstall.js | ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824 |
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js | b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3 |
Атрибуција и посматрано понашање
Пет имена пакета објављено је под два идентификатора npm налога, али деле довољно инфраструктуре да би се третирали као један кластер: исто ектомодул манифестна шема, иста ЕЦТ-472839 примарни маркер судопера, исти вебхук.сајт ИД колектора и крајње тачке C2 у истом Блок 154.57.164.0/24`. Пакет семена (`coral-wraith, једноставнији и незатворени) и затворена екто-породица се стога читају као итерације на једном алату, а не као независни напори.
Пакети се, у каснијим верзијама, описују као „CTF корисни терет за тестирање ланца снабдевања Verdaccio.“ Ту ознаку приказујемо као видљиву чињеницу и не понављамо је као налаз о сврси. Оно што код ради је недвосмислено и независно од тога како је означен: чита акредитиве за IAM улогу из сервиса метаподатака инстанце, набраја управљане тајне у три AWS региона и преноси резултате на јавну IP адресу и колектор вебхукова треће стране. Заиста тест систем који користи само повратну петљу не би захтевао резервну листу јавних IP адреса, читање IMDS акредитива или позиве менаџера тајни из различитих региона. Пошто су излазни и досежни акредитиви стварни, затворене верзије су класификоване као злонамерне.
Капија која је доступна само контејнеру је најзначајнија карактеристика са оперативног становишта. То је и мера избегавања — остајање тихим на лаптоповима и у аналитичким „песчаницима“ — и мера циљања, активирајући се само тамо где је највероватније да су присутни права IAM улога и активни тајни подаци. Аналитичари који покрећу ове пакете у генеричком „песчанику“ не би ништа приметили; понашање се манифестује само под именом хоста у Docker стилу и путањом инсталације унутар контејнера.
Утицај, трендови и смернице за браниоце
Изложеност овде представља откривање акредитива у облаку и тајни подаци унутар контејнера за изградњу и извршавање. Акредитив за IAM улогу преузет из IMDS-а носи све дозволе које та улога поседује; tajnemenadžer:Listatajni (и свако накнадно GetSecretValue) проширује то на сачуване тајне апликација. Дампови променљивих окружења често садрже токене регистра, URL-ове базе података и API кључеве. У контексту CI или контејнера — управо оно што капија бира — једна транзитивна инсталација једног од ових пакета је довољна да процури тај материјал.
Ектоплазма се уклапа у образац који и даље виђамо: корисни терет током инсталације који посеже за метаподацима у облаку и управљаним тајнама уместо за локалним датотекама, и који се сами активирају само у окружењима високе вредности. Следе два одбрамбена запажања.
- Облик је препознатљив. npm/PyPI инсталациони хоок чији граф позива достиже и cloud secret API (AWS SecretManager, gcloud тајне, az keyvault) или IMDS адреса и мрежни излазни снок је узак образац са високим сигналом — готово никада се не јавља у легитимном скрипту животног циклуса. Статичка анализа тока може га означити без обзира на било који одређени домен или ИП адресу.
- Очвршћивање околине га отупљује. Примена IMDSv2 са ограничењем скока од 1 спречава да радна оптерећења контејнера дођу до метаподатака инстанце; ограничавање IAM улога на најмање привилегије ограничава радијус експлозије било ког акредитива који процури; и покретање инсталација са –Игнориши скрипте У CI потпуно уклања вектор install-hook за пакете којима није потребан.
За оне који се бране, практичне провере су: упозорење о одлазним везама из контејнера за изградњу/CI ка јавним IP адресама које нису на дозвољеној листи током нпм инсталл; пратите IMDS приступ који потиче из скрипти животног циклуса пакета; и третирајте сваку инсталациону удицу која се усмерава ка cloud CLI као сумњиву док се не докаже супротно.
Још две напомене специфичне за овај кластер. Прво, пошто је активација ограничена на контејнеризована окружења, пакет који делује инертно када се провери на радној станици може и даље бити активан у продукцији — провера мора да репродукује име хоста контејнера и услове путање или да директно прочита изворни код, уместо да се ослања на „Инсталирао сам га и ништа се није десило“. Друго, коришћење јавне услуге за инспекцију захтева као сакупљача сигнала значи да се неки од извучених података могу повратити за реаговање на инцидент: организација која пронађе један од ових пакета у свом стаблу зависности може да закључи о томе шта би успешан сигнал садржао на основу логике сакупљања корисног терета и требало би да ротира све акредитиве за IAM улогу, токене регистра и управљане тајне које су биле доступне из погођеног окружења за изградњу или извршавање. Ротација акредитива, а не уклањање пакета, је оперативна санација након што је инсталација покренута.





