Ektoplasma npm Installeer Hooks Wat AWS-geloofsbriewe steel

Ektoplasma: npm-installasie hooks wat AWS-geloofsbriewe agter 'n houer-alleen sneller insamel

TL; DR

'n Groep van vyf npm-pakkette, gepubliseer oor twee rekeninghandvatsels, gestuur a postinstall haak wat wolkbewyse van die gasheer lees en dit van die boks af versend. Die pakkette dra spook-en-piraatname — coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit — en serialiseer wat hulle ook al insamel in 'n vals ecto_module: YAML-manifes voordat dit gestuur word. Ons volg die groepering as Ektoplasma.

Die vrag loop slegs wanneer dit 'n spesifieke omgewing opspoor: 'n gasheer wie se naam 'n is 12-karakter heksadesimale string en 'n werkgids onder /app/node_modules — die vorm van 'n houergebou of KI-werker. Wanneer daardie hek verbygaan, vra die haak die AWS-instansie-metadatadiens (IMDSv2) vir IAM-rolbewyse, tel op AWS Secrets Bestuurder oor drie streke, stort omgewingveranderlikes, lees lêers onder /app, en skraap vir vlagvanger-stringe. Dit verwyder dan die resultaat op twee maniere: 'n baken na 'n webhook.site versamelaar en 'n manifest PUT na 'n rou-IP-eindpunt, met 'n lys van localhost-eerste terugvalfunksies.

Die latere pakketbeskrywings lui "CTF-vrag vir verdaccio-voorsieningskettingtoetsing." Ons rapporteer daardie selfbeskrywing as 'n waarneembare feit. Die gedrag self - lewendige uitgang na 'n publieke IP, werklike IMDS-bewyslesings, werklike Secrets Manager-oproepe - is wat dit is, ongeag die etiket, en is die rede waarom hierdie weergawes as kwaadwillig geklassifiseer is.

Een naam in die groep, coral-wraith, het nie by 'n enkele vrystelling gestop nie. Dit is vinnig heruitgegee deur dosyne weergawes binne 'n paar uur — 1.0.0 klim na 6.0.0 — en 'n vroeëre reeks met dieselfde naam het opgeblase gebruik 9999.0.x weergawenommers, die klassieke vorm van 'n afhanklikheid-verwarringspogingOor daardie warboel heen het die vrag sigbaar volwasse geword: van 'n eenmalige gasheer-enumerasie-baken tot 'n volledige AWS-bewysstuk-spilpunt toegedraai in omgewingskontroles wat dit stil hou buite sy beoogde teiken.

Pakkette 5 name; coral-wraith alleen heruitgegee oor dosyne weergawes
ekosisteem NPM
Installeer vektor postinstall lewensiklus-skrip
Primêre teiken AWS IAM-rolbewyse + Geheime Bestuurder geheime waardes, omgewingveranderlikes, /app lêers
Exfil webhook.site baken + rou-IP C2 PUT
Snellerhek 12-heks gasheernaam + /app/node_modules cwd, plus 'n omgewingskontrole wat die vrag buite daardie konteks onderdruk
Erns hoë — wolkbewyse en bestuurde geheime openbaarmaking van gekontaineerde bou- en looptydomgewings

Aanvalsanatomie

Elke pakket in die groep is op dieselfde manier gebou: 'n byna leë index.js (module.uitvoere = {}), 'n eenreël pakket.json skrif — “nainstallasie”: “node nainstallasie.js” — en die vrag in postinstall.jsDie installering van die pakket is genoeg om die hook te laat loop; geen invoer of oproep is nodig nie.

Die teikenhek. Voordat enigiets gedoen word, kontroleer die ekto-familie vrag sy omgewing:

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

'n 12-heks gasheernaam is die standaardvorm wat Docker aan 'n houer toewys, en /app/node_modules is 'n konvensionele installasiepad in 'n houer. Die derde klousule val uit as die pad lyk soos 'n sandbox-onttrekkingsgids. Die netto effek is dat die vrag dormant bly op 'n ontwikkelaar se skootrekenaar of 'n ontledingsandkas en slegs binne 'n houer-bou of looptydwerker aktiveer - die soort omgewing wat waarskynlik lewendige wolkbewyse sal dra. Die vroegste pakket in die groep, koraalgees, het geen so 'n hek nie en bestuur sy (eenvoudiger) versameling onvoorwaardelik.

versamelingWanneer die hek verbygaan, dop die haak uit execFileSync("/bin/sh", ["-c", …]) en voer 'n enkele saamgestelde opdrag uit wat, in volgorde:

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)

Stappe 1–3 is 'n handboek IMDSv2-herwinning: versoek 'n sessietoken, en heg dit dan aan as die X-aws-ec2-metadata-token opskrif om die instansie se IAM-rol en daardie rol se tydelike toegangsleutels te trek. Die keuse om IMDSv2 te implementeer eerder as die eenvoudiger ongeverifieerde IMDSv1 KRY is die moeite werd om daarop te let — dit beteken dat die vrag selfs werk op gevalle wat gekonfigureer is om token-gebaseerde metadata-toegang te vereis, wat die AWS-aanbevole verharding is. Die geloofsbriewe wat deur stap 3 terugbesorg word, is van korte duur. AccessKeyId/Geheime Toegangssleutel/Teken drievoudiges is toegeken aan die instansie se rol; wat daardie rol ook al kan doen, kan die houer van daardie sleutels vir die geloofsbriewe se leeftyd doen.

Stappe 4–6 verbreed die benadering. Die env dump vang enigiets vas wat die bou- of looptydproses geërf het — in die praktyk is dit waar registertokens, databasisverbindingsstringe en API-sleutels meestal voorkom. /toepassing lêerwandeling lees tot vyftien toepassingslêers buite node_modules, wat oppervlakkonfigurasie kan hê, .a V lêers, of bron. Stap 6 oproepe aws geheimebestuurder lys-geheime in drie streke; die geloofsbriewe wat in stappe 1–3 verkry word, is presies wat daardie oproepe verifieer, so die IMDS-lesing en die Secrets Manager-opsomming word saamgevoeg in 'n enkele eskalasie: instansierol → bestuurde-geheime inventaris. Stap 7 is 'n knik na die vang-die-vlag-raamwerk — wanneer 'n HTB{…} vlag gevind word, word dit op sy eie gestuur, andersins word die rou versamelde blob in vier stukke verdeel en gestuur.

Latere weergawes in die groep voer die eskalasie verder. Eerder as om by 'n inventaris te stop, ontleed hulle die IMDS-respons, voer die tydelike sleutels uit as AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN omgewingveranderlikes, bevestig die identiteit met aws sts kry-oproeper-identiteit, en dan oor elke geheim wat teruggegee word deur lus lys-geheime roep aws geheimebestuurder kry-geheime-waarde op elkeen — die geheime inhoud word herwin, nie net hul name nie. Dieselfde weergawes lees ook prosesvervangde vlagbinêre lêers (/leesvlag en vriende) en probeer 'n lading loop teen enige Rust-projek wat onder gevind word /toepassing, wat die oes verder as wolkbewyse verbreed na wat ook al die bou-omgewing blootstel.

Hierdie latere weergawes gebruik ook meer aggressiewe poorte vir hulself. Benewens die 12-heks-gasheernaam en /app/node_modules kontroles, die vrag inspekteer die aktiewe pakketregisterkonfigurasie en die werkgidspad en sluit stilweg wanneer hulle 'n analise- of spieëlkonteks aandui eerder as 'n lewendige teiken. Die gekombineerde effek is 'n vrag wat niks waarneembaars in die meeste inspeksie-omgewings doen nie en sy volle versameling slegs uitvoer waar dit homself as op 'n egte houergasheer beoordeel.

EkfiltrasieDie versamelde data verlaat die gasheer op twee kanale. Eerstens, 'n baken POS na 'n vaste webhook.site versamelaar, wat die gasheernaam, numeriese UID, werkgids en tot 120 KB versamelde data bevat. Tweedens word die data in 'n vals YAML-"modulemanifes" gevou en PUT om /api/modules/ op 'n teikenbediener:

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

Die manifestveldname (kragvlak, skipdek, vragruim) is versiering — die gesteelde data ry binne die stringwaardes, en daarom sien 'n netwerkmonitor wat lyk soos 'n goedaardige pakketregister-manifesoplaai eerder as 'n ooglopende datastorting. Die bakenkanaal dra meer: ​​die POS liggaam aan webhook.site sluit die gasheernaam, numeriese UID, werkgids en tot 120 KB van die versamelde blob in, sodat selfs 'n enkele suksesvolle baken die volle opname lewer. webhook.site is 'n gratis versoek-inspeksiediens; deur dit as 'n versamelaar te gebruik, hoef die operateur nooit sy eie ontvangsinfrastruktuur vir daardie kanaal op te stel nie, en die opgeneemde versoeke bly in die diens se asblik.

Die manifes PUT loop 'n terugvallys wat met verskeie begin 127.0.0.1/localhost poorte en val dan deur na drie openbare adresse in die `154.57.164.0/24` reeks, en stop by die eerste eindpunt wat met 'n 2xx-status antwoord. Die localhost-eerste ordening is in ooreenstemming met die "verdaccio testing" selfbeskrywing (’n plaaslike register op teruglus), maar die publieke-IP-terugvalle beteken dat die data die gasheer verlaat wanneer die teruglus nie luister nie – dit wil sê, op enige masjien wat nie die outeur se eie toetsopstelling is nie.

Tydlyn

Die groep toon inkrementele vermoëgroei eerder as 'n enkele daling. Ons orden dit volgens waargenome gedrag, nie volgens gepubliseerde muurhorlosie nie:

Stadium Pakkette / Weergawes Gedrag
Vroeë lopie coral-wraith 9999.0.x Opgeblaasde weergawenommers in ooreenstemming met 'n poging tot afhanklikheidsverwarring; installasietyd-opsomming en exfil
Saad coral-wraith 1.0.0 postinstall versamel id/omgewing/vlag lêers; enkele PUT na 154[.]57[.]164[.]71:30782, merker ECT-472839
Vinnige iterasie coral-wraith 1.0.1 → 6.0.0 Dosyne vrystellings in ure; vrag kry die isAppWorker() hek, IMDSv2-bewysstuktrekking, die volle get-secret-value draaipunt, die register-/padomgewingkontrole en dubbele sinkmerkers
Parallelle name ecto-corsair-whisper-6f3b9 1.0.14–1.0.18 Dieselfde gehekte vrag; webhook.site baken en multi-eindpunt-terugvallys
Variante ecto-rust-read-f3a9c1 1.0.1–1.0.2 Voeg ekstra wasbakmerkers by ECT-987654, ECT-654321, ECT-839201
Variante ecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0 Dieselfde gehekte vrag, dieselfde C2 en baken

Die bepalende kenmerk van die groep is die publikasiekadens: eerder as een pakket en een weergawe, word dieselfde naam oor en oor in vinnige opeenvolging herpubliseer, elke vrystelling 'n klein variasie op die laaste, saam met 'n handjievol verskillend genoemde sibbe wat dieselfde vrag dra. Binne die fluister familie het die kode in twee noue vingerafdrukke verdeel - een stel wat twee kritieke opsporings aktiveer, 'n ander drie ('n bykomende lêerlees-sink) - maar albei los op na dieselfde vrag; die verskil is kode-drywing, nie 'n gedragsvurk nie. Weergawes van fluister buite die geanaliseerde reeks (tot ten minste 1.0.25 ten tyde van skryf) is lewendig op die register waargeneem, en die koraalgees naam het voortgegaan om sy eie weergawe-leer oor dieselfde venster te klim.

Aanwysers van kompromie

Alle aanwysers hieronder is uit die pakketbron op skyf onttrek. Netwerkaanwysers is gedeïnstalleer.

Netwerk

Indicator Rol
hxxp://154[.]57[.]164[.]71:30782 C2 PUT-teiken (coral-wraith)
hxxp://154[.]57[.]164[.]80:30543 C2 PUT-terugval (ecto-*)
hxxp://154[.]57[.]164[.]82:31250 C2 PUT-terugval (ecto-*)
hxxp://154[.]57[.]164[.]71:31289 C2 PUT-terugval (ecto-*)
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5 Bakenversamelaar
169[.]254[.]169[.]254/latest/... IMDSv2-bewysstuk gelees (teikenkant, AWS-metadata)

Gedrags-/lêer

Indicator Rol
"postinstall": "node postinstall.js" Installeer vektor
ecto_module: YAML met power_level / ship_deck / cargo_hold sleutels Exfil manifest skema
wasbakmerkers ECT-472839, ECT-987654, ECT-654321, ECT-839201 C2-padsegment /api/modules/<marker>
isAppWorker() hek: gasheer /^[0-9a-f]{12}$/, cwd bevat /app/node_modules Aktiveringsvoorwaarde
aws secretsmanager list-secrets oor us-east-1, eu-west-1, eu-central-1 Geheime opsomming
HTB{...} regex-skraap Vang-die-vlag-oes

Lêer-hashes (sha256, vasgelê tydens ontleding)

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

Toeskrywing en waargenome gedrag

Die vyf pakketname is onder twee npm-rekeninghandvatsels gepubliseer, maar hulle deel genoeg infrastruktuur om hulle as een groep te behandel: dieselfde ekto_module manifeste skema, dieselfde ECT-472839 primêre wasbakmerker, dieselfde webhook.site versamelaar-ID en C2-eindpunte in dieselfde 154.57.164.0/24` blok. Die saadpakket (`coral-wraith, eenvoudiger en ongepoort) en die gepoorte ekto-familie lees dus as iterasies op een gereedskapskis eerder as onafhanklike pogings.

Die pakkette beskryf hulself, in latere weergawes, as "CTF-vrag vir verdaccio-voorsieningskettingtoetsing." Ons bring daardie etiket as 'n waarneembare feit na vore en herhaal dit nie as 'n bevinding oor doel nie. Wat die kode doen, is ondubbelsinnig en onafhanklik van hoe dit geëtiketteer is: dit lees IAM-rolbewyse vanaf die instansie-metadatadiens, tel bestuurde geheime oor drie AWS-streke op en stuur die resultate na 'n publieke IP en 'n derdeparty-webhook-versamelaar. 'n Werklik teruglus-enigste toetsharnas sou nie die publieke-IP-terugvallys, die IMDS-bewyslesings of die kruisstreek-Geheimebestuurder-oproepe nodig hê nie. Omdat die uitgang en geloofsbriewebereik werklik is, is die beheerde weergawes as kwaadwillig geklassifiseer.

Die houer-alleen-hek is die mees operasioneel noemenswaardige eienskap. Dit is beide 'n ontduikingsmaatreël – stilbly op skootrekenaars en in ontledingsandkaste – en 'n teikenmaatreël, wat slegs aktiveer waar 'n werklike IAM-rol en lewendige geheime heel waarskynlik teenwoordig is. Ontleders wat hierdie pakkette in 'n generiese sandkas uitvoer, sal niks waarneem nie; die gedrag manifesteer slegs onder 'n Docker-styl gasheernaam en 'n in-houer installasiepad.

Impak, tendense en leiding vir verdedigers

Die blootstelling hier is wolk-bewyse en geheime openbaarmaking binne bou- en looptydhouers. 'n IAM-rolbewys wat van IMDS afgetrek word, dra enige toestemmings wat daardie rol besit; geheimebestuurder:LysGeheime (en enige opvolg KryGeheimeWaarde) brei dit uit na gestoorde toepassingsgeheime. Omgewingsveranderlike stortings bevat gereeld registertokens, databasis-URL's en API-sleutels. In 'n CI- of houerkonteks – presies waarvoor die hek kies – is 'n enkele oorganklike installasie van een van hierdie pakkette genoeg om daardie materiaal te lek.

Ektoplasma pas by 'n patroon wat ons steeds sien: installasietyd-vragte wat na wolkmetadata en bestuurde geheime eerder as plaaslike lêers gryp, en wat hulself slegs in hoëwaarde-omgewings laat brand. Twee verdedigende waarnemings volg.

  • Die vorm is waarneembaar'n npm/PyPI-installasiehaak waarvan die oproepgrafiek beide 'n wolkgeheime-API bereik (aws geheimebestuurder, gcloud geheime, az sleutelkluis) of die IMDS-adres en 'n netwerk-uitgangsput is 'n nou, hoëseinpatroon — dit kom amper nooit voor in 'n wettige lewensiklusskrip nie. Statiese vloei-analise kan dit merk sonder om van enige spesifieke domein of IP afhanklik te wees.
  • Omgewingsverharding stomp dit af. Die afdwing van IMDSv2 met 'n hoplimiet van 1 verhoed dat houerwerkladings die instansiemetadata bereik; die omvang van IAM-rolle tot die minste voorregte beperk die ontploffingsradius van enige geloofsbriewe wat wel lek; en die uitvoer van installasies met –Ignoreer skrifte In CI verwyder die install-hook vektor heeltemal vir pakkette wat dit nie nodig het nie.

Vir verdedigers is die praktiese kontroles: waarskuwing oor uitgaande verbindings vanaf bou/CI-houers na nie-toelaatlys publieke IP's gedurende npm installeer; let op vir IMDS-toegang wat afkomstig is van pakketlewensiklusskripte; en behandel enige installasiehaak wat na 'n wolk-CLI uitstuur as verdag totdat die teendeel bewys word.

Twee verdere notas spesifiek vir hierdie groep. Eerstens, omdat aktivering gekoppel is aan houeromgewings, kan 'n pakket wat inert voorkom wanneer dit op 'n werkstasie gekeur word, steeds in produksie wees - keuring moet die houer se gasheernaam en padvoorwaardes reproduseer, of die bron direk lees, eerder as om staat te maak op "Ek het dit geïnstalleer en niks het gebeur nie." Tweedens, die gebruik van 'n openbare versoekinspeksiediens as 'n bakenversamelaar beteken dat sommige van die geëksfiltreerde data herwinbaar kan wees vir voorvalreaksie: 'n organisasie wat een van hierdie pakkette in sy afhanklikheidsboom vind, kan redeneer oor wat 'n suksesvolle baken sou bevat het uit die vrag se versamelingslogika, en moet enige IAM-rolbewyse, registertokens en bestuurde geheime roteer wat bereikbaar was vanaf die betrokke bou- of looptydomgewing. Geloofsbriefrotasie, nie pakketverwydering nie, is die operatiewe remediëring sodra 'n installasie uitgevoer is.

sca-tools-sagteware-samestelling-analise-gereedskap
Prioritiseer, herstel en beveilig jou sagtewarerisiko's
Kry jou gratis rekening.
Geen kredietkaart benodig nie.

Beveilig u sagteware-ontwikkeling en -lewering

met Xygeni-produksuite