Ektoplazma npm Įdiegti Hooks Tai vagia AWS įgaliojimus

Ektoplazma: npm diegimas hooks kurie renka AWS kredencialus, esančius už tik konteinerio aktyviklio

Lt; DR

Klasteris penki npm paketai, paskelbta dviejose paskyrose, išsiuntė postinstall kabliukas, kuris nuskaito debesies prisijungimo duomenis iš pagrindinio kompiuterio ir išsiunčia juos iš karto. Paketuose yra vaiduokliški ir piratiniai pavadinimai – coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit – ir viską, ką surinks, paversdami klastotėmis ecto_module: YAML manifestą prieš jį perduodant. Klasterį sekame kaip Ektoplazma.

Naudingoji apkrova paleidžiama tik tada, kai aptinka konkrečią aplinką: pagrindinį kompiuterį, kurio pavadinimas yra 12 simbolių šešioliktainė eilutė ir darbinį katalogą po /app/node_modules — konteinerizuotame kompiliavime arba CI darbuotojui skirta forma. Kai šis vartas praeina, užklausa pateikiama AWS egzemplioriaus metaduomenų paslauga (IMDSv2) IAM vaidmens kredencialams išvardija AWS paslapčių vadybininkas trijuose regionuose, iškelia aplinkos kintamuosius, nuskaito failus iš /appir ieško vėliavos pagavimo eilučių. Tada rezultatas išfiltruojamas dviem būdais: švyturiu į webhook.site rinktuvas ir manifesto PUT į neapdoroto IP galinį tašką su vietinio serverio-pirmiausia atsarginių variantų sąrašu.

Vėlesniuose paketų aprašymuose rašoma „CTF naudingoji apkrova, skirta „Verdaccio“ tiekimo grandinės testavimui“. Šį aprašymą pateikiame kaip stebimą faktą. Pats elgesys – tiesioginis išėjimas į viešą IP adresą, tikri IMDS kredencialų nuskaitymai, tikri „Secrets Manager“ iškvietimai – yra toks, koks yra, nepriklausomai nuo žymos, ir yra priežastis, kodėl šios versijos buvo klasifikuojamos kaip kenkėjiškos.

Vienas vardas grupėje, coral-wraith, neapsiribojo vienu leidimu. Jis buvo greitai perleistas dešimtimis versijų per kelias valandas – 1.0.0 kopimas į 6.0.0 – ir ankstesniame to paties pavadinimo bėgime buvo panaudotas pripūstas 9999.0.x versijų numeriai, klasikinė forma priklausomybės ir supainiojimo bandymasViso to ciklo metu naudingoji apkrova pastebimai subrendo: nuo vienkartinio pagrindinių kompiuterių sąrašo švyturio iki visiško AWS kredencialų posūkio, apimančio aplinkos patikrinimus, kurie neleidžia jai veikti už numatyto taikinio ribų.

Paketai 5 vardai; coral-wraith vien perpublikuotas dešimtimis versijų
ekosistema npm
Įdiekite vektorių postinstall gyvavimo ciklo scenarijus
Pagrindinis tikslas AWS IAM vaidmens prisijungimo duomenys + „Secrets Manager“ slaptos reikšmės, aplinkos kintamieji, /app failai
Exfil webhook.site švyturys + neapdorotas IP C2 PUT
Trigerio vartai 12 šešioliktainių kodų pagrindinio kompiuterio pavadinimas + /app/node_modules cwd, plius aplinkos patikrinimas, kuris slopina naudingąją apkrovą už šio konteksto ribų
Sunkumas aukštas — debesies kredencialų ir valdomos paslapties atskleidimas iš konteinerizuotas kūrimo ir vykdymo aplinkas

Atakos anatomija

Kiekvienas klasterio paketas sukurtas vienodai: beveik tuščias rodyklė.js (modulis.exports = {}), vienos eilutės paketas.json scenarijus — „postinstall“: „mazgas postinstall.js“ — ir naudingoji apkrova postinstall.jsPaketo įdiegimas yra pakankamas, kad būtų paleista užklausa; nereikia importuoti ar iškviesti.

Taikymo vartai. Prieš ką nors darydamas, ektošeimos krovinys patikrina aplinką:

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 šešioliktainių kodų pagrindinio kompiuterio pavadinimas yra numatytoji forma, kurią „Docker“ priskiria konteineriui, ir /programa/mazgo_moduliai yra įprastas diegimo konteineryje kelias. Trečioji sąlyga netaikoma, jei kelias atrodo kaip smėlio dėžės išgavimo katalogas. Galutinis rezultatas yra tas, kad naudingoji apkrova lieka neveikli kūrėjo nešiojamajame kompiuteryje arba analizės smėlio dėžėje ir aktyvuojama tik konteinerizuotame kūrimo arba vykdymo laiko darbe – aplinkoje, kurioje greičiausiai bus gyvi debesies prisijungimo duomenys. Ankstyviausias klasterio paketas, koralų vaiduoklis, neturi tokių vartų ir besąlygiškai vykdo savo (paprastesnę) kolekciją.

kolekcijaKai vartai praeina, kabliukas išlenda pro juos. execFileSync(„/bin/sh“, [“-c“, …]) ir paleidžia vieną sudėtinę komandą, kuri tokia tvarka:

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 veiksmai yra vadovėlio IMDSv2 gavimas: užklauskite sesijos prieigos raktą, tada pridėkite jį kaip X-aws-ec2-metadata-token antraštė, skirta išgauti egzemplioriaus IAM vaidmenį ir to vaidmens laikinus prieigos raktus. Pasirinkimas įdiegti IMDSv2, o ne paprastesnį neautentifikuotą IMDSv1 GET verta paminėti – tai reiškia, kad naudingoji apkrova veikia net ir tose instancijose, kurios sukonfigūruotos taip, kad būtų reikalinga prieiga prie žetonų pagrįstų metaduomenų, o tai yra AWS rekomenduojama apsaugos priemonė. 3 veiksme grąžinti prisijungimo duomenys yra trumpalaikiai. AccessKeyId/Secret AccessKey/žetonas trigubai, susiję su egzemplioriaus vaidmeniu; ką gali padaryti tas vaidmuo, tų raktų turėtojas gali daryti visą kredencialų galiojimo laiką.

4–6 žingsniai praplečia vaizdą. env „dump“ fiksuoja viską, ką paveldėjo kūrimo arba vykdymo procesas – praktiškai čia dažniausiai saugomi registro žetonai, duomenų bazės ryšio eilutės ir API raktai. / app failų apėjimas nuskaito iki penkiolikos programų failų, esančių už jo ribų mazgo_moduliai, kuris gali paviršiaus konfigūraciją, .NS failai arba šaltinis. 6 veiksmas iškviečia AWS secretsmanager sąrašas-paslaptys trijuose regionuose; 1–3 veiksmuose gauti prisijungimo duomenys yra būtent tai, kas autentifikuoja šiuos skambučius, todėl IMDS nuskaitymas ir „Secrets Manager“ išvardijimo grandinė sujungiama į vieną eskalaciją: egzemplioriaus vaidmuo → valdomas slaptas inventorius. 7 veiksmas yra užuomina į vėliavėlės fiksavimo rėmelį – kai HTB{…} Jei vėliava randama, ji siunčiama atskirai, kitu atveju neapdorotas surinktas blobas suskaidomas į keturias dalis ir siunčiamas.

Vėlesnės klasterio versijos toliau plėtoja problemą. Užuot sustoję ties inventoriumi, jie analizuoja IMDS atsakymą, eksportuoja laikinus raktus kaip AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN aplinkos kintamuosius, patvirtinkite tapatybę su aws sts gauti skambinančiojo tapatybę, ir tada kartoti kiekvieną grąžintą paslaptį sąrašo-slaptys paskambinus aws secretsmanager get-secret-value kiekviename – atkuriant slaptą turinį, o ne tik jų pavadinimus. Tos pačios versijos taip pat skaito procesų pakeistus vėliavėlių dvejetainius failus (/skaityti vėliavą ir draugais) ir pabandykite įkrovimo paleidimas prieš bet kokį „Rust“ projektą, rastą pagal / app, išplėsdami derliaus nuėmimą ne tik debesijos įgaliojimams, bet ir viskam, ką atskleidžia kūrimo aplinka.

Šios vėlesnės versijos taip pat agresyviau save vartuoja. Be 12 šešioliktainių prieglobos pavadinimo ir /programa/mazgo_moduliai Atlikus patikrinimus, naudingoji apkrova tikrina aktyvią paketo registro konfigūraciją ir darbinio katalogo kelią ir tyliai išeina, kai jie nurodo analizės arba veidrodinį kontekstą, o ne veikiantį taikinį. Bendras poveikis yra tas, kad naudingoji apkrova daugumoje tikrinimo aplinkų neatlieka jokių pastebimų veiksmų ir paleidžia visą savo rinkinį tik tada, kai nusprendžia, kad yra tikrame konteinerizuotame serveryje.

EksfiltracijaSurinkti duomenys iš pagrindinio kompiuterio siunčiami dviem kanalais. Pirma, švyturys POST į fiksuotą webhook.site rinktuvas, kuriame yra pagrindinio kompiuterio pavadinimas, skaitmeninis UID, darbinis katalogas ir iki 120 KB surinktų duomenų. Antra, duomenys sulankstomi į netikrą YAML „modulio manifestą“ ir PUT į /api/moduliai/ tiksliniame serveryje:

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

Manifesto laukų pavadinimai (galios_lygis, laivo_denis, krovinių_skyrius) yra dekoracija – pavogti duomenys yra eilutės reikšmėse, todėl tinklo monitorius mato tai, kas atrodo kaip gerybinis paketo registro manifesto įkėlimas, o ne akivaizdus duomenų išklotinis. Švyturio kanalas perduoda daugiau: POST kūnas į webhook.site apima pagrindinio kompiuterio pavadinimą, skaitmeninį UID, darbinį katalogą ir iki 120 KB surinkto „blob“, todėl net vienas sėkmingas švyturys pateikia visą informaciją. webhook.site yra nemokama užklausų tikrinimo paslauga; naudojant ją kaip rinktuvą, operatoriui niekada nereikia kurti savo priėmimo infrastruktūros tam kanalui, o įrašytos užklausos išlieka paslaugos saugykloje.

Manifestas PUT eina atsarginiu sąrašu, kuris prasideda keliais 127.0.0.1/localhost prievadus ir tada patenka į tris viešuosius adresus „154.57.164.0/24` diapazonas, sustojant ties pirmuoju galiniu tašku, kuris atsako su 2xx būsena. „localhost-first“ tvarka atitinka „verdaccio testing“ savęs aprašymą (vietinis registras grįžtamajame ryšyje), tačiau viešojo IP atsarginiai adresai reiškia, kad duomenys palieka pagrindinį kompiuterį, kai grįžtamasis ryšys neklauso, t. y. bet kuriame kompiuteryje, kuris nėra autoriaus testavimo platforma.

Chronologija

Klasteris rodo laipsnišką pajėgumų augimą, o ne vienkartinį sumažėjimą. Mes jį rikiuojame pagal stebimą elgseną, o ne pagal publikuojamą sieninį laikrodį:

Etapas Paketai / Versijos Elgesys
Ankstyvas bėgimas coral-wraith 9999.0.x Išpūsti versijų numeriai, atitinkantys bandymą supainioti priklausomybes; diegimo metu atliktas išvardijimas ir ištrynimas
Sėklos coral-wraith 1.0.0 „postinstall“ renka id/env/flag failus; atlieka vieną PUT komandą 154[.]57[.]164[.]71:30782, žymeklis ECT-472839
Greita iteracija coral-wraith 1.0.1 → 6.0.0 Dešimtys išleidimų per kelias valandas; naudingoji apkrova padidėja isAppWorker() vartai, IMDSv2 kredencialų gavimas, pilnas get-secret-value „Pivot“, registro / kelio aplinkos patikrinimas ir dvigubi rinktuvo žymekliai
Lygiagretūs pavadinimai ecto-corsair-whisper-6f3b9 1.0.14–1.0.18 Tas pats uždaras krovinys; webhook.site švyturių ir kelių galinių taškų atsarginis sąrašas
Variantai ecto-rust-read-f3a9c1 1.0.1–1.0.2 Prideda papildomus kriauklės žymeklius ECT-987654, ECT-654321, ECT-839201
Variantai ecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0 Tas pats valdomas krovinys, tas pats C2 ir švyturys

Išskirtinis klasterio bruožas yra jo publikavimo ritmas: vietoj vieno paketo ir vienos versijos, tas pats pavadinimas yra pakartotinai publikuojamas greita seka, kiekvienas leidimas yra nedidelis ankstesniojo variantas, kartu su saujele skirtingai pavadintų giminingų paketų, turinčių tą pačią naudingąją apkrovą. šnabždesys šeimos kodas suskyla į du panašius pirštų atspaudus – vienas rinkinys suaktyvina du kritinius aptikimus, kitas – tris (papildomas failų skaitymo įrenginys) – tačiau abu išsprendžiami pagal tą pačią naudingąją apkrovą; skirtumas yra kodo dreifas, o ne elgesio išsišakojimas. Versijos šnabždesys registre buvo pastebėti tiesioginiai duomenys, viršijantys analizuojamą diapazoną (rašymo metu iki bent 1.0.25), ir koralų vaiduoklis pavadinimas toliau kopė savo versijos kopėčiomis per tą patį langą.

Kompromiso rodikliai

Visi toliau nurodyti indikatoriai buvo išgauti iš diske esančio paketo šaltinio kodo. Tinklo indikatoriai yra išvalyti.

tinklas

rodiklis Vaidmuo
hxxp://154[.]57[.]164[.]71:30782 C2 PUT taikinys (coral-wraith)
hxxp://154[.]57[.]164[.]80:30543 C2 PUT atsarginis variantas (ecto-*)
hxxp://154[.]57[.]164[.]82:31250 C2 PUT atsarginis variantas (ecto-*)
hxxp://154[.]57[.]164[.]71:31289 C2 PUT atsarginis variantas (ecto-*)
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5 Švyturių rinkėjas
169[.]254[.]169[.]254/latest/... IMDSv2 kredencialų nuskaitymas (tikslinė pusė, AWS metaduomenys)

Elgesio / byla

rodiklis Vaidmuo
"postinstall": "node postinstall.js" Įdiekite vektorių
ecto_module: YAML su power_level / ship_deck / cargo_hold raktai Exfil manifesto schema
Kriauklės žymekliai ECT-472839, ECT-987654, ECT-654321, ECT-839201 C2 kelio segmentas /api/modules/<marker>
isAppWorker() vartai: šeimininkas /^[0-9a-f]{12}$/, cwd sudėtyje yra /app/node_modules Aktyvinimo sąlyga
aws secretsmanager list-secrets per us-east-1, eu-west-1, eu-central-1 Paslapčių sąrašas
HTB{...} reguliariosios išraiškos iškarpa Vėliavos gaudymo derlius

Failų maišos kodai (sha256, užfiksuoti analizės metu)

filė sha256
coral-wraith/postinstall.js ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3

Priskyrimas ir stebimas elgesys

Penki paketų pavadinimai buvo paskelbti naudojant dvi npm paskyrų tvarkykles, tačiau jie turi pakankamai bendros infrastruktūros, kad būtų laikomi vienu klasteriu: tas pats ekto_modulis manifesto schema, ta pati ECT-472839 pirminis kriauklės žymeklis, tas pats webhook.site rinkėjo ID ir C2 galiniai taškai tame pačiame 154.57.164.0/24` blokas. Sėklų paketas („coral-wraith“), paprastesnės ir neapribotos), o apribota ektošeima taigi skaitoma kaip vieno įrankių rinkinio iteracijos, o ne savarankiškos pastangos.

Vėlesnėse versijose paketai apibūdinami kaip „CTF naudingoji apkrova Verdaccio tiekimo grandinės testavimui.“ Šią etiketę pateikiame kaip stebimą faktą ir neperteikiame jos kaip išvados apie tikslą. Kodo veiksmai yra nedviprasmiški ir nepriklausomi nuo to, kaip jis yra pažymėtas: jis nuskaito IAM vaidmens kredencialus iš egzemplioriaus metaduomenų paslaugos, išvardija valdomus slaptus duomenis trijuose AWS regionuose ir perduoda rezultatus į viešąjį IP adresą ir trečiosios šalies žiniatinklio kabliuko rinktuvą. Tikrai grįžtamojo ryšio pagrindu veikiančiai testavimo sistemai nereikėtų viešojo IP atsarginio sąrašo, IMDS kredencialų nuskaitymų ar tarpregioninių „Secrets Manager“ iškvietimų. Kadangi išeinantis ir kredencialų pasiekiamumas yra realūs, apsaugotos versijos buvo klasifikuojamos kaip kenkėjiškos.

Tik konteineriui skirtas vartas yra operatyviai pastebimiausias bruožas. Tai yra ir apėjimo priemonė – tylėjimas nešiojamuosiuose kompiuteriuose ir analizės smėlio dėžėse – ir taikymo priemonė, suaktyvinanti tik ten, kur labiausiai tikėtinas tikras IAM vaidmuo ir gyvi paslaptys. Analitikai, vykdantys šiuos paketus bendroje smėlio dėžėje, nieko nepastebėtų; toks elgesys pasireiškia tik esant „Docker“ stiliaus pagrindinio kompiuterio vardui ir konteinerio diegimo keliui.

Poveikis, tendencijos ir gairės gynėjams

Čia atskleidžiami debesies kredencialai ir slapti duomenys kūrimo ir vykdymo laiko konteineriuose. Iš IMDS gauti IAM vaidmens kredencialai turi visas teises, kurias turi tas vaidmuo; paslapčių valdytojas:Paslapčių sąrašas (ir bet kokie tolesni veiksmai Gauti slaptą reikšmę) išplečia tai iki saugomų programų paslapčių. Aplinkos kintamųjų išklotinėse dažnai yra registro žetonai, duomenų bazės URL ir API raktai. CI arba konteinerio kontekste – būtent tam, kam pasirenka vartai – vieno iš šių paketų tranzitinio įdiegimo pakanka, kad ši medžiaga būtų nutekinta.

Ektoplazma atitinka modelį, kurį ir toliau matome: diegimo metu gaunami debesies metaduomenys ir valdomos paslaptys, o ne vietiniai failai, ir jie suaktyvinami tik didelės vertės aplinkose. Toliau pateikiami du gynybiniai pastebėjimai.

  • Forma yra aptinkama„npm/PyPI“ diegimo kabliukas, kurio iškvietimo grafikas pasiekia ir debesies paslapčių API (AWS paslapčių valdytojas, „gcloud“ paslaptys, az raktų saugykla) arba IMDS adresas ir tinklo išėjimo rinktuvas yra siauras, stipraus signalo šablonas – jis beveik niekada nepasitaiko teisėtame gyvavimo ciklo scenarijuje. Statinio srauto analizė gali jį pažymėti neatsižvelgdamas į konkretų domeną ar IP adresą.
  • Aplinkos grūdinimas jį atbukina. IMDSv2 taikymas su 1 šuolio riba neleidžia konteinerio darbo krūviams pasiekti egzemplioriaus metaduomenų; IAM vaidmenų nustatymas iki mažiausių privilegijų riboja bet kokių nutekančių kredencialų sprogdinimo spindulį; ir diegimų vykdymas su –Ignoruoti scenarijus CI visiškai pašalina diegimo kablio vektorių paketams, kuriems jo nereikia.

Praktiniai patikrinimai, skirti apsaugos teikėjams, yra šie: įspėjimai apie išeinančius ryšius iš kūrimo/CI konteinerių į neleistinus viešuosius IP adresus npm įdiegti; stebėti IMDS prieigą, kylančią iš paketo gyvavimo ciklo scenarijų; ir bet kokį diegimo kabliuką, kuris nukreipia į debesies CLI, laikyti įtartinu, kol neįrodyta kitaip.

Dar dvi pastabos, susijusios su šiuo klasteriu. Pirma, kadangi aktyvinimas skirtas konteinerinėms aplinkoms, paketas, kuris patikrinus darbo stotyje atrodo inertiškas, vis tiek gali būti aktyvus gamyboje – patikrinimui reikia atkurti konteinerio pagrindinio kompiuterio pavadinimą ir kelio sąlygas arba tiesiogiai nuskaityti šaltinį, o ne pasikliauti „Įdiegiau ir nieko neįvyko“. Antra, viešosios užklausų tikrinimo paslaugos naudojimas kaip švyturių rinkėjo reiškia, kad kai kuriuos išfiltruotus duomenis galima atkurti reaguojant į incidentą: organizacija, kuri savo priklausomybių medyje randa vieną iš šių paketų, gali samprotauti, ką sėkmingas švyturys būtų turėjęs, remdamasi naudingosios apkrovos rinkimo logika, ir turėtų pakeisti visus IAM vaidmens kredencialus, registro žetonus ir valdomas paslaptis, kurios buvo pasiekiamos iš paveiktos kūrimo arba vykdymo aplinkos. Kvalifikacijos rotacija, o ne paketo pašalinimas, yra operatyvus taisymas, kai diegimas jau paleistas.

sca-tools-software-composition-analyses-tools
Prioritetizuoti, pašalinti ir apsaugoti savo programinės įrangos rizikas
Gaukite nemokamą paskyrą.
Nebūtina kreditinės kortelės.

Apsaugokite savo programinės įrangos kūrimą ir tiekimą

su „Xygeni“ produktų rinkiniu