TL; DR
Sakumpulan lima pakét npm, diterbitkeun dina dua gagang akun, dikirimkeun a postinstall hook anu maca kredensial awan ti host sareng ngirimkeunana kaluar tina kotak. Paket-paket éta mawa nami hantu sareng bajak laut — coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit — sareng ngaruntuykeun naon waé anu dikumpulkeun janten palsu ecto_module: Manifes YAML sateuacan ngirimkeunana. Urang ngalacak klaster salaku Éktoplasma.
Payload ngan ukur jalan nalika ngadeteksi lingkungan anu khusus: host anu namina a String heksadesimal 12 karakter sareng diréktori kerja di handapeun /app/node_modules — bentukna wangunan dina wadah atanapi pagawé CI. Nalika gerbang éta ngaliwat, hook naroskeun ka Layanan metadata instansi AWS (IMDSv2) pikeun kredensial peran IAM, sebutkeun AWS Rahasia Manajer di tilu wilayah, miceun variabel lingkungan, maca file di handapeun /app, sareng ngeruk senar pikeun nangkep bendera. Teras éta ngaluarkeun hasilna ku dua cara: suar ka webhook.site kolektor sareng manifest PUT ka titik tungtung raw-IP, kalayan daptar fallback localhost-first.
Pedaran pakét anu langkung énggal maca "muatan CTF pikeun uji ranté suplai verdaccio." Kami ngalaporkeun pedaran diri éta salaku kanyataan anu tiasa dititénan. Paripolahna sorangan — kaluar langsung ka IP umum, maca kredensial IMDS anu asli, nelepon Manajer Rahasia anu asli — nyaéta naon waé henteu paduli labélna, sareng éta alesan kunaon vérsi ieu digolongkeun jahat.
Hiji ngaran dina gugusan éta, coral-wraith, teu eureun dina hiji rilisan waé. Éta medalkeun deui sacara gancang ngaliwatan puluhan vérsi dina sababaraha jam — 1.0.0 naek ka 6.0.0 — sareng versi sateuacanna anu namina sami parantos nganggo inflated 9999.0.x nomer vérsi, bentuk klasik tina hiji usaha kabingungan-katergantungan. Di sakuliah éta ngarobah payload anu katingali dewasa: tina beacon host-enumeration hiji-shot kana poros kredensial AWS lengkep anu dibungkus ku pamariksaan lingkungan anu ngajagana tetep jempé di luar target anu dituju.
| bungkusan | 5 ngaran; coral-wraith nyalira diterbitkeun deui dina puluhan vérsi |
| ékosistem | npm |
| Pasang vektor | postinstall skrip siklus hirup |
| Target utama | Kredensial peran AWS IAM + nilai rahasia Manajer Rahasia, variabel lingkungan, /app payil |
| Exfil | webhook.site suar + atah-IP C2 PUT |
| Gerbang pemicu | Ngaran host 12-hex + /app/node_modules cwd, ditambah pamariksaan lingkungan anu ngurangan muatan di luar kontéks éta |
| severity | luhur — kredensial awan sareng panyingkepan rahasia anu dikelola ti lingkungan ngawangun sareng runtime anu disimpen dina wadahna |
Anatomi serangan
Unggal pakét dina klaster diwangun ku cara anu sami: ampir kosong indéks.js (modul.ékspor = {}), hiji baris rangkep.json naskah — "pascapasang": "node postinstall.js" — sareng muatan dina postinstall.js. Masang pakétna cekap pikeun ngajalankeun hook; teu kedah impor atanapi nelepon.
Gerbang target. Sateuacan ngalakukeun nanaon, muatan ecto-family mariksa sakurilingna:
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 Ngaran host 12-hex nyaéta bentuk standar anu ditugaskeun ku Docker ka wadah, sareng /aplikasi/modul_node nyaéta jalur pamasangan dina wadah konvensional. Klausa katilu bakal kaluar upami jalurna katingalina sapertos diréktori ékstraksi anu di-sandbox. Éfékna nyaéta payload tetep teu aktip dina laptop pamekar atanapi sandbox analisis sareng ngan ukur diaktipkeun di jero worker build atanapi runtime anu di-container — jinis lingkungan anu paling dipikaresep pikeun mawa kredensial awan langsung. Paket anu pangheubeulna dina klaster, hantu karang, teu boga gerbang kitu sarta ngajalankeun koleksina (anu leuwih basajan) tanpa syarat.
kumpulanNalika gerbang ngaliwat, pancingna kaluar execFileSync(“/bin/sh”, [“-c”, …]) sareng ngajalankeun hiji paréntah sanyawa tunggal anu, dina urutan:
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) Léngkah 1–3 nyaéta pamilarian IMDSv2 buku ajar: nyuhunkeun token sési, teras lampirkeun salaku Token-metadata-X-aws-ec2 lulugu pikeun narik peran IAM instansi sareng konci aksés samentawis peran éta. Pilihan pikeun nerapkeun IMDSv2 tinimbang IMDSv1 anu langkung saderhana sareng henteu diauténtikasi meunangkeun perlu dicatet — éta hartosna payload tiasa dianggo sanajan dina instansi anu dikonfigurasi pikeun meryogikeun aksés metadata berbasis token, nyaéta hardening anu disarankeun ku AWS. Kredensial anu dipulangkeun ku léngkah 3 umurna pondok. AccessKeyId/KonciAksésRahasia/token rangkep tilu anu dicakup kana peran instansi; naon waé anu tiasa dilakukeun ku peran éta, anu gaduh konci éta tiasa dilakukeun salami umur kredensial.
Léngkah 4–6 ngalegaan jalanna. utusan dump ngarékam naon waé anu diwariskeun ku prosés ngawangun atanapi runtime — dina praktékna ieu tempat token pendaptaran, string sambungan database, sareng konci API paling sering aya. / aplikasi file walk maca nepi ka lima belas file aplikasi di luar simpul_modul, anu tiasa ngabentuk konfigurasi permukaan, .env file, atanapi sumber. Léngkah 6 nelepon aws secretsmanager daptar-rahasia di tilu wilayah; kredensial anu ditarik dina léngkah 1–3 nyaéta anu ngaoténtikasi telepon éta, janten IMDS maca sareng ranté énumérasi Manajer Rahasia ngahiji kana hiji éskalasi: peran instansi → inventaris rahasia-managed. Léngkah 7 mangrupikeun anggukan kana framing capture-the-flag — nalika hiji HTB{…} Lamun bandéra kapanggih, éta bakal dikirim sorangan, upami henteu gumpalan atah anu dikumpulkeun bakal dipotong jadi opat bagian teras dikirim.
Versi anu langkung énggal dina klaster ieu ngalaksanakeun éskalasi langkung jauh. Tinimbang eureun dina inventaris, aranjeunna nganalisis réspon IMDS, ngékspor konci samentawis salaku AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN variabel lingkungan, mastikeun idéntitasna ku aws sts kéngingkeun idéntitas-panelepon, teras ngulang unggal rusiah anu dipulangkeun ku daptar-rahasia nelepon aws secretsmanager kéngingkeun nilai-rahasia dina masing-masing — meunangkeun eusi rusiah, teu ngan ukur ngaranna. Vérsi anu sami ogé maca binér flag anu digentos ku prosés (/bacabendera jeung babaturan) sarta nyobaan a muatan ngajalankeun ngalawan proyék Rust naon waé anu kapanggih dina / aplikasi, ngalegaan panén saluareun kredensial awan kana naon waé anu diungkabkeun ku lingkungan wangunan.
Versi-versi anu langkung énggal ieu ogé nga-gate sorangan langkung agrésif. Salian ti 12-hex-hostname sareng /aplikasi/modul_node Saatos dipariksa, payload mariksa konfigurasi pendaptaran pakét aktif sareng jalur diréktori kerja teras kaluar sacara teu langsung nalika nunjukkeun analisis atanapi kontéks eunteung tinimbang target langsung. Éfék gabungan nyaéta payload anu teu ngalakukeun nanaon anu tiasa dititénan dina kalolobaan lingkungan pamariksaan sareng ngajalankeun koleksi lengkepna ngan ukur nalika nangtoskeun dirina aya dina host wadah asli.
ExfiltrationData anu dikumpulkeun ninggalkeun host dina dua saluran. Mimitina, hiji suar POST ka hiji anu tetep situs webhook. kolektor, mawa hostname, UID numerik, diréktori kerja, sareng dugi ka 120 KB data anu dikumpulkeun. Kadua, data dilipat kana "manifest modul" YAML palsu sareng neundeun ka /api/modul/ dina server target:
ecto_module: name: "<flag-or-chunk-0>" version: "1.0.0" power_level: "<chunk-1>" ship_deck: "<chunk-2>" cargo_hold: "<chunk-3>" Ngaran widang manifes (tingkat_kakuatan, dek_kapal, cargo_hold) mangrupikeun hiasan — data anu dipaling aya di jero nilai string, éta sababna monitor jaringan ningali naon anu katingalina sapertos unggahan manifes pendaptaran pakét anu teu bahaya tinimbang dump data anu jelas. Saluran beacon mawa langkung seueur: POST awak ka situs webhook. ngawengku hostname, UID numerik, diréktori kerja, sareng dugi ka 120 KB tina blob anu dikumpulkeun, janten bahkan hiji beacon anu suksés ogé bakal ngahasilkeun gambaran lengkep. situs webhook. nyaéta layanan pamariksaan pamundut gratis; ngagunakeunana salaku pangumpul hartosna operator henteu kedah nangtung pikeun nampi infrastruktur sorangan pikeun saluran éta, sareng pamundut anu dirékam tetep aya dina tempat sampah layanan.
Manifes éta neundeun ngajalankeun daptar cadangan anu dimimitian ku sababaraha 127.0.0.1/localhost palabuhan teras murag ka tilu alamat umum dina `154.57.164.0/24` rentang, eureun di titik tungtung munggaran anu ngajawab ku status 2xx. Urutan localhost-first saluyu sareng pedaran mandiri "verdaccio testing" (registri lokal dina loopback), tapi fallback IP publik hartosna data ninggalkeun host iraha waé loopback henteu ngadangukeun — nyaéta, dina mesin naon waé anu sanés rig tés pangarang sorangan.
Gariswanci
Klaster ieu nunjukkeun kamekaran kamampuan sacara bertahap tinimbang hiji panurunan. Urang ngaturna dumasar kana paripolah anu dititénan, sanés ku cara nyebarkeun jam témbok:
| Panggung | Pakét / Vérsi | tingkah laku |
|---|---|---|
| Lumpat awal | coral-wraith 9999.0.x | Nomer vérsi anu digedekeun saluyu sareng usaha kabingungan-katergantungan; enumerasi waktos-instalasi sareng exfil |
| siki | coral-wraith 1.0.0 | postinstall ngumpulkeun file id/env/flag; PUT tunggal ka 154[.]57[.]164[.]71:30782, pananda ECT-472839 |
| Iteration gancang | coral-wraith 1.0.1 → 6.0.0 | Puluhan rilis dina sababaraha jam; payload kéngingkeun isAppWorker() gerbang, tarikan kredensial IMDSv2, lengkepna get-secret-value pivot, pamariksaan lingkungan registri/jalur, sareng spidol dual sink |
| Ngaran-ngaran anu sami | ecto-corsair-whisper-6f3b9 1.0.14–1.0.18 | Muatan anu dipager sarua; webhook.site daptar cadangan suar sareng multi-titik tungtung |
| varian | ecto-rust-read-f3a9c1 1.0.1–1.0.2 | Nambahkeun spidol solokan tambahan ECT-987654, ECT-654321, ECT-839201 |
| varian | ecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0 | Muatan anu dipager sami, C2 sareng suar anu sami |
Ciri anu ngabédakeun tina klaster ieu nyaéta irama penerbitanna: tinimbang hiji pakét sareng hiji vérsi, nami anu sami diterbitkeun deui sareng deui sacara gancang, masing-masing ngaluarkeun variasi alit tina anu terakhir, sareng sababaraha sadulur anu namina béda anu mawa muatan anu sami. Dina ngorong kulawarga kode dibagi jadi dua sidik jari anu caket — hiji set anu ngahalangan dua deteksi kritis, tilu deui (hiji wadah baca file tambahan) — tapi duanana ngaréngsékeun kana muatan anu sami; bédana nyaéta penyimpangan kode, sanés garpu paripolah. Versi tina ngorong saluareun rentang anu dianalisis (dugi ka sahenteuna 1.0.25 dina waktos nyerat) dititénan langsung dina pendaptaran, sareng hantu karang ngaranna terus nanjak tangga vérsi sorangan dina jandela anu sami.
Indikator kompromi
Sadaya indikator di handap ieu diekstrak tina sumber pakét dina disk. Indikator jaringan parantos di-default.
Network
| indikator | peran |
|---|---|
hxxp://154[.]57[.]164[.]71:30782 | Sasaran C2 PUT (coral-wraith) |
hxxp://154[.]57[.]164[.]80:30543 | C2 PUT cadangan (ecto-*) |
hxxp://154[.]57[.]164[.]82:31250 | C2 PUT cadangan (ecto-*) |
hxxp://154[.]57[.]164[.]71:31289 | C2 PUT cadangan (ecto-*) |
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5 | Kolektor suar |
169[.]254[.]169[.]254/latest/... | Maca kredensial IMDSv2 (sisi target, metadata AWS) |
Paripolah/file
| indikator | peran |
|---|---|
"postinstall": "node postinstall.js" | Pasang vektor |
ecto_module: YAML sareng power_level / ship_deck / cargo_hold kenop | Skéma manifest Exfil |
Pananda wastafel ECT-472839, ECT-987654, ECT-654321, ECT-839201 | Segmen jalur C2 /api/modules/<marker> |
isAppWorker() gapura: nu boga imah /^[0-9a-f]{12}$/, cwd ngandung /app/node_modules | Kaayaan aktivasi |
aws secretsmanager list-secrets di luhur us-east-1, eu-west-1, eu-central-1 | Énumerasi rusiah |
HTB{...} regex scraping | Panén rebut bendera |
Hash file (sha256, direkam dina waktos analisis)
| file | sha256 |
|---|---|
coral-wraith/postinstall.js | ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824 |
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js | b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3 |
Atribusi & paripolah anu dititénan
Lima ngaran pakét dipedalkeun dina dua gagang akun npm, tapi infrastrukturna sami pikeun nganggap éta salaku hiji klaster: sami modul_ékto skéma manifes, sami ECT-472839 pananda solokan utama, sami situs webhook. ID kolektor, sareng titik tungtung C2 dina anu sami Blok 154.57.164.0/24`. Bungkus siki (`coral-wraith, leuwih basajan jeung teu dipager) sarta kulawarga ecto anu dipager ku kituna dibaca salaku iterasi dina hiji toolkit tinimbang usaha mandiri.
Pakét-pakét éta ngagambarkeun dirina sorangan, dina vérsi anu langkung énggal, salaku "Muatan CTF pikeun uji ranté suplai verdaccio." Kami ngungkabkeun labél éta salaku fakta anu tiasa dititénan sareng henteu nyatakeun deui salaku panemuan ngeunaan tujuan. Naon anu dilakukeun ku kode éta teu ambigu sareng henteu gumantung kana kumaha éta dilabélan: éta maca kredensial peran IAM tina layanan metadata instansi, ngadaptar rahasia anu dikelola di tilu daérah AWS, sareng ngirimkeun hasilna ka IP umum sareng kolektor webhook pihak katilu. Harness tés anu ngan ukur loopback moal peryogi daptar fallback IP umum, kredensial IMDS maca, atanapi nelepon Manajer Rahasia lintas daérah. Kusabab jangkauan kaluar sareng kredensial nyata, vérsi anu dijaga diklasifikasikeun jahat.
Gerbang wadah wungkul mangrupikeun sipat anu paling penting sacara operasional. Éta mangrupikeun ukuran nyingkahan — cicing waé dina laptop sareng dina kotak pasir analisis — sareng ukuran targeting, ngan ukur diaktipkeun dimana peran IAM nyata sareng rahasia langsung paling dipikaresep aya. Analis anu ngajalankeun pakét ieu dina kotak pasir umum moal niténan nanaon; paripolahna ngan ukur némbongan dina nami host gaya Docker sareng jalur pamasangan dina wadah.
Dampak, tren & pituduh pikeun para pembela
Paparan di dieu nyaéta kredensial awan sareng panyingkepan rahasia di jero wadah build sareng runtime. Kredensial peran IAM anu dicandak tina IMDS ngandung idin naon waé anu dipiboga ku peran éta; manajerrahasia:DaptarRahasia (sareng naon waé tindak lanjutna MeunangkeunNilaiRahasia) ngalegaan éta kana rusiah aplikasi anu disimpen. Dump variabel lingkungan sering mawa token pendaptaran, URL database, sareng konci API. Dina kontéks CI atanapi wadah — persis naon anu dipilih ku gerbang — hiji pamasangan transitif tina salah sahiji pakét ieu cekap pikeun ngabocorkeun bahan éta.
Ectoplasm cocog sareng pola anu terus urang tingali: muatan waktos pamasangan anu ngahontal metadata awan sareng rahasia anu dikelola tinimbang file lokal, sareng anu ngajagi dirina pikeun dipecat ngan ukur dina lingkungan anu bernilai tinggi. Dua observasi pertahanan nuturkeun.
- Bentukna tiasa dideteksi. Hiji hook pamasangan npm/PyPI anu grafik panggerona ngahontal API rusiah awan (manajer rahasia aws, rusiah gcloud, az keyvault) atanapi alamat IMDS sareng saluran kaluar jaringan mangrupikeun pola anu sempit sareng sinyal luhur — ampir henteu pernah kajadian dina skrip siklus hirup anu sah. Analisis aliran statis tiasa nandakeunana tanpa gumantung kana domain atanapi IP khusus naon waé.
- Lingkungan anu beuki keras ngaleuleuskeun éta. Ngalaksanakeun IMDSv2 kalayan wates hop 1 nyegah beban kerja wadah ngahontal metadata instansi; ngacakup peran IAM kana hak istimewa pangleutikna ngawatesan radius blast tina kredensial naon waé anu bocor; sareng ngajalankeun pamasangan kalayan –ngalalaworakeun-skrip dina CI ngahapus véktor install-hook sagemblengna pikeun pakét anu henteu peryogina.
Pikeun para pembela, pamariksaan praktisna nyaéta: waspada kana sambungan kaluar ti wadah build/CI ka IP publik anu henteu diijinkeun salami npm install; awas aksés IMDS anu asalna tina skrip siklus hirup paket; sareng anggap naon waé hook pamasangan anu ngaluarkeun ka CLI awan salaku anu dicurigai dugi ka kabuktian sanés.
Dua catetan salajengna anu khusus pikeun klaster ieu. Kahiji, kusabab aktivasina dijaga ka lingkungan anu dikontainerisasi, pakét anu katingalina teu aktip nalika dipariksa dina workstation masih tiasa langsung diproduksi — pamariksa kedah ngahasilkeun deui nami host wadah sareng kaayaan jalur, atanapi maca sumberna sacara langsung, tinimbang ngandelkeun "Kuring masangna sareng teu aya anu kajantenan." Kadua, panggunaan layanan pamariksaan pamundut umum salaku kolektor suar hartosna sababaraha data anu diekstraksi tiasa dipulihkeun pikeun réspon kajadian: organisasi anu mendakan salah sahiji pakét ieu dina tangkal katergantunganana tiasa mikirkeun naon anu bakal dikandung ku suar anu suksés tina logika pangumpulan payload, sareng kedah muterkeun kredensial peran IAM, token pendaptaran, sareng rahasia anu dikelola anu tiasa dihontal tina lingkungan ngawangun atanapi runtime anu kapangaruhan. Rotasi kredensial, lain miceun paket, nyaéta remediasi operasional saatos pamasangan dijalankeun.





