TL; DR
Бір топ бес 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 Secrets Manager үш аймақ бойынша, орта айнымалыларын шығарады, файлдарды оқиды /app, және жалаушаны ұстап алу жолдарын қырып тастайды. Содан кейін нәтижені екі жолмен сүзгіден өткізеді: маяк арқылы webhook.site коллектор және манифестті localhost-first резервтік көшірмелерінің тізімімен шикі IP соңғы нүктесіне PUT.
Кейінгі пакет сипаттамаларында «Verdaccio жеткізу тізбегін сынауға арналған CTF пайдалы жүктемесі» деп жазылған. Біз бұл өзіндік сипаттаманы байқалатын факт ретінде хабарлаймыз. Мінез-құлықтың өзі – жалпыға қолжетімді IP мекенжайына тікелей шығу, нақты IMDS тіркелгі деректерін оқу, нақты Secrets Manager қоңыраулары – белгіге қарамастан солай және бұл нұсқалардың зиянды деп жіктелуінің себебі осында.
Кластерде бір есім, coral-wraith, бір ғана шығарылыммен шектелмеді. Ол бірнеше сағат ішінде ондаған нұсқалары арқылы тез арада қайта басылып шықты — 1.0.0 өрмелеу 6.0.0 — және осы атаудағы бұрынғы шығарылымда кеңейтілген мән қолданылған 9999.0.x нұсқа нөмірлері, классикалық пішіні тәуелділікті шатастыру әрекетіОсының арқасында пайдалы жүктеме айқын түрде жетілді: бір реттік хост нөмірлеу маякынан мақсатты нысанадан тыс тыныштықты сақтайтын орта тексерулеріне оралған толық AWS тіркелгі деректерінің айналма жолына.
| пакеттер | 5 есім; coral-wraith жалғыз өзі ондаған нұсқада қайта басылып шыққан |
| экожүйе | npm |
| Векторды орнату | postinstall өмірлік цикл скрипті |
| Негізгі мақсат | AWS IAM рөлінің тіркелгі деректері + Құпиялар менеджерінің құпия мәндері, орта айнымалылары, /app файлдар |
| Эксфил | webhook.site маяк + шикі IP C2 PUT |
| Триггер қақпасы | 12-он алтылық хост атауы + /app/node_modules cwd, сонымен қатар сол контекстен тыс пайдалы жүктемені басатын ортаны тексеру |
| Ауырлығы | биік — бұлттық тіркелгі деректері және басқарылатын құпия ақпарат контейнерленген құрастыру және орындау орталары |
Шабуыл анатомиясы
Кластердегі әрбір пакет бірдей түрде жасалған: бос дерлік index.js (модуль.экспорты = {}), бір жолды пакет.json сценарий — «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 контейнерге тағайындайтын әдепкі пішін, және /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-метадата-белгісі дананың IAM рөлін және сол рөлдің уақытша қатынау кілттерін алу үшін тақырып. Қарапайым аутентификацияланбаған IMDSv1 орнына IMDSv2 енгізуді таңдау GET Айта кету керек, бұл пайдалы жүктеме тіпті токенге негізделген метадеректерге қол жеткізуді талап ететіндей конфигурацияланған жағдайларда да жұмыс істейтінін білдіреді, бұл AWS ұсынған қатаңдату. 3-қадамда қайтарылған тіркелгі деректері қысқа мерзімді. AccessKeyId/Құпия қолжетімділік кілті/таңбалауыш үштіктер дананың рөліне қолданылады; сол рөл не істей алатынын, сол кілттердің иесі тіркелгі деректерінің өмір бойы жасай алады.
4-6 қадамдар көзқарасты кеңейтеді. ауд dump құрастыру немесе орындау уақыты процесі мұра еткен кез келген нәрсені жазып алады — іс жүзінде тізілім токендері, дерекқорға қосылу жолдары және API кілттері көбінесе осы жерде орналасқан. / қолданба file walk сыртта он беске дейін қолданба файлын оқиды түйін_модульдері, беткі конфигурацияны жасай алады, .env файлдар немесе дереккөз. 6-қадамды шақыру aws құпия менеджерінің тізім құпиялары үш аймақта; 1-3 қадамдарда алынған тіркелгі деректері сол қоңыраулардың түпнұсқалығын растайтын дәлме-дәл деректер болып табылады, сондықтан IMDS оқиды және Secrets Manager санау тізбегін бірыңғай эскалацияға біріктіреді: дана рөлі → басқарылатын құпия инвентаризация. 7-қадам - жалаушаны басып алу кадрына басу - қашан HTB{…} жалауша табылса, ол өздігінен жіберіледі, әйтпесе жиналған шикі дақ төрт бөлікке бөлініп, жіберіледі.
Кластердегі кейінгі нұсқалар эскалацияны одан әрі жалғастырады. Олар қорда тоқтаудың орнына, IMDS жауабын талдайды, уақытша кілттерді экспорттайды AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN орта айнымалылары, сәйкестікті растаңыз aws sts қоңырау шалушының сәйкестігін анықтау функциясын пайдаланады, содан кейін қайтарылған әрбір құпияны қайталаңыз құпия тізімдер қоңырау aws secretsmanager құпия мәнді алу әрқайсысында — тек атауларын ғана емес, құпия мазмұнды да алу. Сол нұсқалар сонымен қатар процеспен ауыстырылған жалаушалы екілік файлдарды оқиды (/оқужалаушасы және достар) және көріңіз зарядтау жүгірісі астында табылған кез келген Rust жобасына қарсы / қолданба, бұлттық деректерден тыс өнімді құрастыру ортасы көрсететін кез келген нәрсеге кеңейту.
Бұл кейінгі нұсқалар да өздерін агрессивті түрде қорғайды. 12-hex-hostname және басқа да /app/node_modules тексереді, пайдалы жүктеме белсенді пакет тізілімінің конфигурациясын және жұмыс каталогының жолын тексереді және олар тікелей нысананың орнына талдау немесе айна контекстін көрсеткен кезде үнсіз шығады. Біріктірілген әсер - бұл көптеген тексеру орталарында байқалатын ештеңе жасамайтын және толық жинағын тек өзін шынайы контейнерленген хостта деп санаған кезде ғана іске қосатын пайдалы жүктеме.
ЭксфильтрацияЖиналған деректер хостты екі арнада қалдырады. Біріншіден, маяк POST бекітілгенге дейін webhook.site хост атауын, сандық UID, жұмыс каталогын және 120 КБ дейінгі жиналған деректерді қамтитын коллектор. Екіншіден, деректер жалған YAML «модуль манифестіне» бүктеледі және PUT дейін /api/модульдер/ мақсатты серверде:
ecto_module: name: "<flag-or-chunk-0>" version: "1.0.0" power_level: "<chunk-1>" ship_deck: "<chunk-2>" cargo_hold: "<chunk-3>" Манифест өрісінің атаулары (қуат_деңгейі, кеме_палубасы, жүкті_ұстау) безендіру болып табылады — ұрланған деректер жол мәндерінің ішінде орналасады, сондықтан желі мониторы айқын деректердің төгіндісі емес, пакет тізілімінің манифестінің қауіпсіз жүктелуіне ұқсайтын нәрсені көреді. Маяк арнасы көбірек тасымалдайды: POST денеге webhook.site хост атауын, сандық UID-ті, жұмыс каталогын және жиналған 120 КБ дейінгі блокты қамтиды, сондықтан тіпті бір сәтті маяк толық ақпаратты береді. webhook.site тегін сұранысты тексеру қызметі болып табылады; оны жинаушы ретінде пайдалану операторға сол арна үшін өзінің инфрақұрылымын қабылдауды тоқтатудың қажеті жоқ екенін және жазылған сұраныстар қызметтің қалтасында сақталатынын білдіреді.
Манифест PUT бірнешеуінен басталатын резервтік тізіммен жүреді 127.0.0.1/жергілікті порттар, содан кейін үш жалпыға қолжетімді мекенжайға өтеді154.57.164.0/24` диапазон, 2xx мәртебесімен жауап беретін бірінші соңғы нүктеде тоқтайды. localhost-first реті «verdaccio testing» өзіндік сипаттамасына (циклбектегі жергілікті тізілім) сәйкес келеді, бірақ public-IP резервтік көшірмелері циклбек тыңдамаған кезде деректердің хосттан шығатынын білдіреді — яғни, автордың жеке сынақ құрылғысы емес кез келген машинада.
Timeline
Кластер бір реттік төмендеудің орнына инкрементальды мүмкіндіктердің өсуін көрсетеді. Біз оны жарияланатын қабырға сағаты бойынша емес, бақыланатын мінез-құлық бойынша реттейміз:
| кезең | Пакеттер / Нұсқалар | мінез-құлық |
|---|---|---|
| Ерте жүгіру | coral-wraith 9999.0.x | Тәуелділік-шатастыру әрекетіне сәйкес келетін нұсқа нөмірлерінің көбейтілген саны; орнату уақытын санау және exfil |
| тұқым | coral-wraith 1.0.0 | postinstall 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 дейін) тізілімде тікелей байқалды, және маржан перісі Name сол терезе арқылы өз нұсқасының баспалдағымен көтеріле берді.
Ымыраға келу көрсеткіштері
Төмендегі барлық индикаторлар дискідегі пакет көзінен алынған. Желі индикаторлары бұрмаланған.
Желі
| Индикатор | рөлі |
|---|---|
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.js | ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824 |
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js | b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3 |
Атрибуция және байқалған мінез-құлық
Бес пакет атауы екі npm тіркелгісінің тұтқалары астында жарияланды, бірақ оларды бір кластер ретінде қарастыруға жеткілікті инфрақұрылыммен бөліседі: бірдей ecto_module манифест схемасы, дәл солай ECT-472839 бастапқы раковина маркері, бірдей webhook.site коллекционер идентификаторы және C2 соңғы нүктелері бірдей 154.57.164.0/24 блок. Тұқым пакеті (`маржан-ертегі, қарапайым және бекітілмеген) және жабық экто-отбасы тәуелсіз күш-жігердің орнына бір құралдар жинағындағы итерациялар ретінде оқылады.
Пакеттер кейінгі нұсқаларында өздерін былай сипаттайды «Verdaccio жеткізу тізбегін сынауға арналған CTF пайдалы жүктемесі». Біз бұл белгіні байқалатын факт ретінде қарастырамыз және оны мақсат туралы жаңалық ретінде қайталамаймыз. Кодтың қызметі бірмәнді және оның қалай белгіленгеніне тәуелсіз: ол IAM рөлінің тіркелгі деректерін дана метадеректер қызметінен оқиды, үш AWS аймағындағы басқарылатын құпияларды санайды және нәтижелерді жалпыға қолжетімді IP мекенжайына және үшінші тарап веб-хук жинағышына жібереді. Шынымен тек циклдік сынақ сымына жалпыға қолжетімді IP резервтік тізімін, IMDS тіркелгі деректерін оқуды немесе аймақаралық құпияларды басқару шақыруларын қажет етпейді. Шығу және тіркелгі деректерінің қолжетімділігі нақты болғандықтан, жабық нұсқалар зиянды деп жіктелді.
Тек контейнерге арналған қақпа - операциялық тұрғыдан ең маңызды ерекшелік. Бұл жалтару шарасы - ноутбуктарда және талдау құм жәшіктерінде үнсіз қалу - және нысанаға алу шарасы, тек нақты IAM рөлі мен тірі құпиялар болуы мүмкін жерлерде ғана ату. Бұл пакеттерді жалпы құм жәшігінде іске қосатын аналитиктер ештеңе байқамайды; бұл мінез-құлық тек Docker стиліндегі хост атауында және контейнер ішіндегі орнату жолында көрінеді.
Қорғаушыларға әсер, үрдістер және нұсқаулық
Мұндағы көрініс бұлттық тіркелгі деректері және құрастыру және орындау уақыты контейнерлеріндегі құпия ақпаратты ашу болып табылады. IMDS-тен алынған IAM рөлінің тіркелгі деректері сол рөлге тиесілі кез келген рұқсаттарды қамтиды; құпияларды басқарушы:Құпияларды тізімдеу (және кез келген кейінгі GetSecretValue) сақталған қолданба құпияларына дейін кеңейтеді. Қоршаған орта айнымалыларының дамптарында жиі тізілім токендері, дерекқор URL мекенжайлары және API кілттері болады. CI немесе контейнер контекстінде — қақпаның таңдаған нәрсесі — осы пакеттердің бірінің бір транзитивті орнатуы сол материалдың ағып кетуіне жеткілікті.
Эктоплазма біз әлі де көріп жүрген үлгіге сәйкес келеді: жергілікті файлдарға емес, бұлттық метадеректер мен басқарылатын құпияларға жететін және тек жоғары құнды орталарда ғана жұмыс істеуге мүмкіндік беретін орнату уақытындағы пайдалы жүктемелер. Келесі екі қорғаныс бақылауы.
- Пішіні анықталадыnpm/PyPI орнату ілмегі, оның шақыру графигі бұлттық құпиялар API-іне де жетеді (aws құпия менеджері, gcloud құпиялары, az кілт қоймасы) немесе IMDS мекенжайы және желілік шығыс раковинасы тар, жоғары сигналды үлгі болып табылады — ол заңды өмірлік цикл сценарийінде ешқашан кездеспейді. Статикалық ағынды талдау оны кез келген нақты доменге немесе IP мекенжайына тәуелді болмай белгілей алады.
- Қоршаған ортаның ластануы оны тежейді. IMDSv2 бағдарламасын 1 секіру шегімен орындау контейнер жұмыс жүктемелерінің дана метадеректеріне жетуіне жол бермейді; IAM рөлдерін ең төменгі артықшылыққа дейін шектеу ағып кететін кез келген тіркелгі деректерінің жарылыс радиусын шектейді; және орнатуларды іске қосу –ескерту-скрипттері CI ішінде install-hook векторын қажет етпейтін пакеттер үшін толығымен жояды.
Қорғаушылар үшін практикалық тексерулер: build/CI контейнерлерінен рұқсат етілмеген жалпыға қолжетімді IP мекенжайларына шығыс қосылымдары туралы ескерту npm орнату; пакеттің өмірлік циклінің сценарийлерінен шығатын IMDS қатынасын бақылаңыз; және бұлттық CLI-ге жіберілетін кез келген орнату ілмегін басқаша дәлелденгенше күдікті деп санаңыз.
Бұл кластерге қатысты тағы екі ескертпе. Біріншіден, белсендіру контейнерленген орталарға бағытталғандықтан, жұмыс станциясында тексерілген кезде инертті болып көрінетін пакет әлі де өндірісте жұмыс істей алады — тексеру үшін контейнер хост атауы мен жолының шарттарын қайталау немесе «Мен оны орнаттым, бірақ ештеңе болған жоқ» дегенге сүйенудің орнына дереккөзді тікелей оқу қажет. Екіншіден, қоғамдық сұранысты тексеру қызметін маяк жинаушы ретінде пайдалану кейбір эксфильтрацияланған деректердің оқиғаға жауап ретінде қалпына келтірілуі мүмкін екенін білдіреді: осы пакеттердің бірін тәуелділік ағашынан тапқан ұйым пайдалы жүктеменің жинау логикасынан сәтті маяктың құрамында не болатыны туралы ойлана алады және әсер етілген құрастыру немесе орындау ортасынан қол жеткізуге болатын кез келген IAM рөлінің тіркелгі деректерін, тізілім токендерін және басқарылатын құпияларды айналдыруы керек. Тіркелгі деректерін ауыстыру, пакетті жою емес, орнату іске қосылғаннан кейінгі операциялық қалпына келтіру болып табылады.





