TL; DR
Kundi la vifurushi vitano vya npm, iliyochapishwa katika akaunti mbili, imesafirishwa postinstall ndoano inayosoma hati miliki za wingu kutoka kwa mwenyeji na kuzisafirisha nje ya boksi. Vifurushi hivyo vina majina ya mizimu na maharamia — coral-wraith, ecto-corsair-whisper-6f3b9, ecto-corsair-flag-x9m4, ecto-rust-read-f3a9c1, ecto-nightly-spirit — na kuainisha kila wanachokusanya kuwa bandia ecto_module: MAONI YA YAML kabla ya kuisambaza. Tunafuatilia kundi kama ectoplasm.
Mzigo wa malipo huendeshwa tu wakati unagundua mazingira maalum: mwenyeji ambaye jina lake ni Mfuatano wa heksadi wenye herufi 12 na saraka inayofanya kazi chini ya /app/node_modules — umbo la jengo lililowekwa kwenye kontena au mfanyakazi wa CI. Lango hilo linapopita, ndoano huuliza Huduma ya metadata ya mfano wa AWS (IMDSv2) kwa sifa za jukumu la IAM, huhesabu Meneja wa Siri za AWS katika maeneo matatu, hutupa vigeu vya mazingira, husoma faili zilizo chini ya /app, na kukwaruza nyuzi za kukamata-bendera. Kisha huchuja matokeo kwa njia mbili: taa ya webhook.site mkusanyaji na PUT ya wazi kwa sehemu ya mwisho ya IP ghafi, yenye orodha ya vikwazo vya kwanza vya localhost.
Maelezo ya kifurushi cha baadaye yalisomeka "Mzigo wa malipo wa CTF kwa ajili ya upimaji wa mnyororo wa usambazaji wa verdaccio." Tunaripoti maelezo hayo ya kibinafsi kama ukweli unaoonekana. Tabia yenyewe — kutoka moja kwa moja hadi kwenye IP ya umma, usomaji halisi wa kitambulisho cha IMDS, simu za Meneja wa Siri halisi — ndivyo ilivyo bila kujali lebo, na ndiyo sababu matoleo haya yaliainishwa kuwa mabaya.
Jina moja katika kundi, coral-wraith, haikuishia kwenye toleo moja. Ilichapishwa tena mfululizo kupitia matoleo kadhaa katika muda wa saa chache — 1.0.0 kupanda kwa 6.0.0 — na toleo la awali la jina hilohilo lilikuwa limetumia 9999.0.x nambari za toleo, umbo la kawaida la jaribio la kuchanganyikiwa na utegemezi. Katika hilo, mzigo wa malipo umekomaa waziwazi: kutoka kwa taa ya kuhesabu mwenyeji ya risasi moja hadi kwenye kigezo kamili cha utambulisho wa AWS kilichofunikwa na ukaguzi wa mazingira unaouweka kimya nje ya shabaha yake iliyokusudiwa.
| Packages | Majina 5; coral-wraith pekee ilichapishwa tena katika matoleo kadhaa |
| mazingira | npm |
| Sakinisha vekta | postinstall hati ya mzunguko wa maisha |
| Lengo kuu | Sifa za jukumu la AWS IAM + Siri za Meneja thamani za siri, vigezo vya mazingira, /app files |
| Exfil | webhook.site beacon + raw-IP C2 PUT |
| Lango la kichocheo | Jina la mwenyeji la heksa 12 + /app/node_modules cwd, pamoja na ukaguzi wa mazingira unaokandamiza mzigo nje ya muktadha huo |
| Ukali | juu — kitambulisho cha wingu na ufichuzi wa siri unaosimamiwa kutoka mazingira ya ujenzi na ya muda wa utekelezaji yaliyo na kontena |
Anatomia ya mashambulizi
Kila kifurushi katika kundi kimejengwa kwa njia ile ile: karibu tupu index.js (moduli.usafirishaji nje = {}), mstari mmoja kifurushi.json hati — "baada ya kusakinisha": "nodi baada ya kusakinisha.js" — na mzigo ndani baada ya kusakinisha.jsKusakinisha kifurushi kunatosha kuendesha ndoano; hakuna uingizaji au simu inayohitajika.
Lango la kulenga. Kabla ya kufanya chochote, mzigo wa familia ya ecto huangalia mazingira yake:
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 Jina la mwenyeji la heksa 12 ni umbo chaguo-msingi ambalo Docker hugawa kwenye chombo, na /programu/node_modules ni njia ya kawaida ya kusakinisha ndani ya chombo. Kifungu cha tatu kinatoweka ikiwa njia inaonekana kama saraka ya uchimbaji yenye sanduku la mchanga. Athari halisi ni kwamba mzigo wa malipo hubaki bila kufanya kazi kwenye kompyuta ya msanidi programu au sanduku la mchanga la uchambuzi na huamilishwa tu ndani ya kifaa cha ujenzi au mfanyakazi wa muda wa utekelezaji - aina ya mazingira ambayo yana uwezekano mkubwa wa kubeba vitambulisho vya wingu moja kwa moja. Kifurushi cha kwanza kabisa katika kundi, matumbawe-wraith, haina lango kama hilo na inaendesha mkusanyiko wake (rahisi) bila masharti.
mkusanyikoLango linapopita, maganda ya ndoano hutoka nje execFileSync(“/bin/sh”, [“-c”, …]) na huendesha amri moja ya kiwanja ambayo, kwa mpangilio:
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) Hatua ya 1–3 ni kitabu cha kiada cha kurejesha IMDSv2: omba tokeni ya kipindi, kisha uiambatishe kama Tokeni ya metadata ya X-aws-ec2 Kichwa cha habari ili kuvuta jukumu la IAM la mfano na funguo za ufikiaji wa muda za jukumu hilo. Chaguo la kutekeleza IMDSv2 badala ya IMDSv1 rahisi isiyothibitishwa GET Inafaa kuzingatia — inamaanisha mzigo wa malipo hufanya kazi hata katika hali zilizowekwa ili kuhitaji ufikiaji wa metadata unaotegemea tokeni, ambayo ni ugumu unaopendekezwa na AWS. Vitambulisho vinavyorejeshwa kwa hatua ya 3 ni vya muda mfupi Kitambulisho cha Ufunguo wa Ufikiaji/Ufunguo wa Ufikiaji wa Siri/Ishara triples zililenga jukumu la mfano; chochote ambacho jukumu hilo linaweza kufanya, mwenye funguo hizo anaweza kufanya kwa maisha yote ya sifa.
Hatua ya 4–6 kupanua wigo. env dump hunasa chochote ambacho mchakato wa ujenzi au wa utekelezaji umerithiwa — kwa vitendo hapa ndipo tokeni za usajili, mifuatano ya muunganisho wa hifadhidata, na funguo za API mara nyingi huishi. / programu Faili ya matembezi husoma hadi faili kumi na tano za programu nje moduli za moduli, ambayo inaweza kusanidi uso, .a faili, au chanzo. Simu za hatua ya 6 orodha ya siri za meneja wa siri za aws katika maeneo matatu; sifa zilizotolewa katika hatua ya 1–3 ndizo hasa zinazothibitisha simu hizo, kwa hivyo IMDS ilisoma na mnyororo wa hesabu wa Meneja wa Siri pamoja katika uongezaji mmoja: jukumu la mfano → hesabu ya siri iliyosimamiwa. Hatua ya 7 ni ishara ya kuashiria uundaji wa kukamata-bendera — wakati HTB{…} bendera ikipatikana inatumwa yenyewe, vinginevyo kidonge kibichi kilichokusanywa hukatwa vipande vinne na kutumwa.
Matoleo ya baadaye katika kundi huendeleza ongezeko hilo zaidi. Badala ya kusimama kwenye orodha ya vitu, huchambua majibu ya IMDS, na kusafirisha funguo za muda kama AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN vigezo vya mazingira, thibitisha utambulisho kwa kutumia aws sts kupata-mpigaji-utambulisho, na kisha pitia kila siri iliyorejeshwa na siri za orodha wito aws secretsmanager pata thamani ya siri kwenye kila moja — kupata yaliyomo ya siri, si majina yao tu. Matoleo hayo hayo pia yanasoma jozi za bendera zilizobadilishwa kwa mchakato (/bendera ya kusoma na marafiki) na kujaribu malipo ya kukimbia dhidi ya mradi wowote wa Rust unaopatikana chini ya / programu, kupanua mavuno zaidi ya sifa za wingu katika chochote ambacho mazingira ya ujenzi yanafichua.
Matoleo haya ya baadaye pia yanajificha kwa ukali zaidi. Mbali na jina la mwenyeji la heksaidi 12 na /programu/node_modules huangalia, mzigo wa malipo hukagua usanidi wa sajili ya kifurushi kinachofanya kazi na njia ya saraka ya kazi na hutoka kimya kimya zinapoonyesha uchambuzi au muktadha wa kioo badala ya shabaha ya moja kwa moja. Athari ya pamoja ni mzigo wa malipo ambao haufanyi chochote kinachoonekana katika mazingira mengi ya ukaguzi na huendesha mkusanyiko wake kamili pale tu unapojihukumu kuwa kwenye seva mwenyeji halisi iliyo na kontena.
exfiltrationData iliyokusanywa huacha mwenyeji kwenye njia mbili. Kwanza, taa ya taa POST kwa fasta tovuti ya wavuti mkusanyaji, akiwa na jina la mwenyeji, UID ya nambari, saraka inayofanya kazi, na hadi KB 120 za data iliyokusanywa. Pili, data imekunjwa katika "maelezo ya moduli" bandia ya YAML na PUT kwa /api/moduli/ kwenye seva lengwa:
ecto_module: name: "<flag-or-chunk-0>" version: "1.0.0" power_level: "<chunk-1>" ship_deck: "<chunk-2>" cargo_hold: "<chunk-3>" Majina ya sehemu ya maelezo (kiwango_cha_nguvu, sitaha_ya_meli, mizigo_ya_kushikilia) ni mapambo — data iliyoibiwa huingia ndani ya thamani za kamba, ndiyo maana kifuatiliaji cha mtandao huona kile kinachoonekana kama upakiaji wa manifest wa usajili wa kifurushi kisicho na madhara badala ya utupaji wa data dhahiri. Njia ya beacon hubeba zaidi: POST mwili tovuti ya wavuti inajumuisha jina la mwenyeji, UID ya nambari, saraka ya kufanya kazi, na hadi KB 120 za kidonge kilichokusanywa, kwa hivyo hata kiashiria kimoja kilichofanikiwa hutoa picha kamili. tovuti ya wavuti ni huduma ya ukaguzi wa ombi bila malipo; kuitumia kama mkusanyaji kunamaanisha kuwa mwendeshaji hahitaji kamwe kupokea miundombinu yake mwenyewe kwa ajili ya chaneli hiyo, na maombi yaliyorekodiwa yanaendelea kubaki kwenye pipa la huduma.
Dhihirisho PUT anafuata orodha ya kurudi nyuma inayoanza na kadhaa 127.0.0.1/lochost bandari na kisha huangukia katika anwani tatu za umma katika `154.57.164.0/24` masafa, yakisimama kwenye sehemu ya kwanza inayojibu kwa hali ya 2xx. Uagizaji wa localhost-first unaendana na maelezo ya "verdaccio testing" (sajili ya ndani kwenye loopback), lakini marudio ya IP ya umma yanamaanisha kuwa data huondoka kwenye seva mwenyeji wakati wowote loopback isiposikiliza — yaani, kwenye mashine yoyote ambayo si kifaa cha majaribio cha mwandishi mwenyewe.
Timeline
Kundi linaonyesha ukuaji wa uwezo unaoongezeka badala ya tone moja. Tunalipanga kwa tabia inayoonekana, si kwa kuchapisha saa ya ukutani:
| Hatua | Vifurushi / Matoleo | Tabia |
|---|---|---|
| Mbio za mapema | coral-wraith 9999.0.x | Nambari za toleo zilizoongezeka zinaendana na jaribio la kuchanganyikiwa kwa utegemezi; hesabu ya muda wa kusakinisha na exfil |
| Mbegu | coral-wraith 1.0.0 | baada ya kusakinisha hukusanya faili za id/env/flag; PUT moja kwa 154[.]57[.]164[.]71:30782, alama ECT-472839 |
| Kurudia kwa haraka | coral-wraith 1.0.1 → 6.0.0 | Mamia ya matoleo katika saa; mzigo wa malipo unapata isAppWorker() lango, kitambulisho cha IMDSv2, kitambulisho kamili get-secret-value pivot, ukaguzi wa mazingira ya sajili/njia, na alama mbili za kuzama |
| Majina sambamba | ecto-corsair-whisper-6f3b9 1.0.14–1.0.18 | Mzigo sawa wa lango; webhook.site orodha ya beacon na orodha ya sehemu mbadala za mwisho nyingi |
| Variants | ecto-rust-read-f3a9c1 1.0.1–1.0.2 | Huongeza alama za ziada za sinki ECT-987654, ECT-654321, ECT-839201 |
| Variants | ecto-corsair-flag-x9m4 1.0.0, ecto-nightly-spirit 1.1.0 | Mzigo wa lango sawa, C2 sawa na taa |
Sifa kuu ya kundi hili ni kasi yake ya uchapishaji: badala ya kifurushi kimoja na toleo moja, jina lile lile huchapishwa tena na tena mfululizo, kila moja likitoa toleo dogo kwenye la mwisho, pamoja na ndugu wachache wenye majina tofauti wanaobeba mzigo sawa. Ndani ya whisper familia msimbo umegawanyika katika alama mbili za vidole zilizo karibu — seti moja ikikwamisha ugunduzi mbili muhimu, zingine tatu (shimo la ziada la kusoma faili) — lakini zote mbili huamua mzigo sawa; tofauti ni kuteleza kwa msimbo, si uma wa kitabia. Matoleo ya whisper zaidi ya kiwango kilichochambuliwa (hadi angalau 1.0.25 wakati wa kuandika) zilizingatiwa moja kwa moja kwenye sajili, na matumbawe-wraith jina liliendelea kupanda ngazi yake ya toleo juu ya dirisha lile lile.
Viashiria vya maelewano
Viashiria vyote vilivyo hapa chini vilitolewa kutoka chanzo cha kifurushi kwenye diski. Viashiria vya mtandao vimebadilishwa.
Mtandao
| Kiashiria | Wajibu |
|---|---|
hxxp://154[.]57[.]164[.]71:30782 | Lengo la C2 PUT (coral-wraith) |
hxxp://154[.]57[.]164[.]80:30543 | Rudi nyuma ya C2 PUT (ecto-*) |
hxxp://154[.]57[.]164[.]82:31250 | Rudi nyuma ya C2 PUT (ecto-*) |
hxxp://154[.]57[.]164[.]71:31289 | Rudi nyuma ya C2 PUT (ecto-*) |
hxxps://webhook[.]site/602a4c72-7033-4e28-92ea-dc66e59206e5 | Mkusanyaji wa beacon |
169[.]254[.]169[.]254/latest/... | Usomaji wa kitambulisho cha IMDSv2 (upande lengwa, metadata ya AWS) |
Faili/tabia
| Kiashiria | Wajibu |
|---|---|
"postinstall": "node postinstall.js" | Sakinisha vekta |
ecto_module: YAML na power_level / ship_deck / cargo_hold funguo | Mchoro wa maelezo ya nje |
Alama za sinki ECT-472839, ECT-987654, ECT-654321, ECT-839201 | Sehemu ya njia ya C2 /api/modules/<marker> |
isAppWorker() lango: mwenyeji /^[0-9a-f]{12}$/, cwd ina /app/node_modules | Hali ya uanzishaji |
aws secretsmanager list-secrets juu ya us-east-1, eu-west-1, eu-central-1 | Uhesabuji wa siri |
HTB{...} chakavu cha regex | Mavuno ya kukamata bendera |
Hashe za faili (sha256, zilizonaswa wakati wa uchambuzi)
| File | sha256 |
|---|---|
coral-wraith/postinstall.js | ce5ff035cfdfed1d0015446424b352c27b66bcb77e9fdb0a51e4245199146824 |
ecto-corsair-whisper-6f3b9 1.0.18/postinstall.js | b58432acba376aa6976f0490d9a1c04257ccdbc856d8390260c50322d63e31c3 |
Tabia ya sifa na inayoonekana
Majina matano ya vifurushi yalichapishwa chini ya vishikio viwili vya akaunti ya npm, lakini vinashiriki miundombinu ya kutosha kuyachukulia kama kundi moja: sawa moduli_ya_ecto mpango wa manifest, sawa ECT-472839 alama ya sinki ya msingi, sawa tovuti ya wavuti Kitambulisho cha mkusanyaji, na sehemu za mwisho za C2 katika hali sawa Kipande cha mbegu (`korali-wraith') 154.57.164.0/24`., rahisi na isiyo na kizuizi) na familia ya ecto-iliyo na kizuizi hivyo husomwa kama marudio kwenye zana moja badala ya juhudi huru.
Vifurushi hivyo vinajielezea, katika matoleo ya baadaye, kama "Mzigo wa CTF kwa ajili ya majaribio ya mnyororo wa usambazaji wa verdaccio." Tunaionyesha lebo hiyo kama ukweli unaoonekana na hatuirudii tena kama matokeo kuhusu madhumuni. Kile ambacho msimbo hufanya hakina utata na hakitegemei jinsi inavyoandikwa: inasoma sifa za jukumu la IAM kutoka kwa huduma ya metadata ya mfano, inaorodhesha siri zinazosimamiwa katika maeneo matatu ya AWS, na hutuma matokeo kwa IP ya umma na mkusanyaji wa wavuti wa mtu wa tatu. Kifaa cha majaribio cha kurudi nyuma pekee hakitahitaji orodha ya kurudi nyuma ya IP ya umma, sifa za IMDS, au simu za Meneja wa Siri za eneo mtambuka. Kwa sababu utokaji na ufikiaji wa sifa ni halisi, matoleo yaliyofungwa yaliainishwa kuwa hasidi.
Lango la kontena pekee ndilo sifa inayoonekana zaidi kiutendaji. Ni kipimo cha kukwepa — kukaa kimya kwenye kompyuta za mkononi na katika visanduku vya mchanga vya uchambuzi — na kipimo cha kulenga, kurusha tu pale ambapo jukumu halisi la IAM na siri za moja kwa moja zina uwezekano mkubwa wa kuwepo. Wachambuzi wanaoendesha vifurushi hivi katika kisanduku cha mchanga cha kawaida hawangeona chochote; tabia hiyo hujitokeza tu chini ya jina la mwenyeji la mtindo wa Docker na njia ya kusakinisha ndani ya kontena.
Athari, mitindo na mwongozo kwa watetezi
Ufichuzi hapa ni uthibitisho wa wingu na ufichuzi wa siri ndani ya vyombo vya ujenzi na vya muda wa utekelezaji. Uthibitisho wa jukumu la IAM uliotolewa kutoka IMDS hubeba ruhusa yoyote ambayo jukumu hilo lina; meneja wa siri:OrodhaSiri (na ufuatiliaji wowote PataThamani ya Siri) hupanua hilo hadi kwenye siri za programu zilizohifadhiwa. Dumps zinazobadilika-badilika kimazingira mara nyingi hubeba tokeni za usajili, URL za hifadhidata, na funguo za API. Katika muktadha wa CI au chombo — hasa kile ambacho lango huchagua — usakinishaji mmoja wa mpito wa mojawapo ya vifurushi hivi unatosha kuvuja nyenzo hiyo.
Ectoplasm inafaa muundo tunaoendelea kuona: mizani ya malipo ya wakati wa kusakinisha ambayo hufikia metadata ya wingu na siri zinazosimamiwa badala ya faili za ndani, na ambazo hujificha kwenye moto katika mazingira yenye thamani kubwa pekee. Uchunguzi mbili wa kujilinda unafuata.
- Umbo linaweza kugunduliwaKiunganishi cha usakinishaji cha npm/PyPI ambacho grafu yake ya simu inafikia API ya siri za wingu (meneja wa siri wa aws, siri za gcloud, kitufe cha az) au anwani ya IMDS na sinki ya kutoka kwa mtandao ni muundo mwembamba na wa ishara ya juu — karibu hautokei kamwe katika hati halali ya mzunguko wa maisha. Uchambuzi wa mtiririko tuli inaweza kuiripoti bila kutegemea kikoa au IP yoyote maalum.
- Ugumu wa mazingira huifanya iwe hafifu. Kutekeleza IMDSv2 kwa kikomo cha kuruka cha 1 huzuia mzigo wa kazi kwenye kontena kufikia metadata ya mfano; kuainisha majukumu ya IAM kwa upendeleo mdogo hupunguza kipenyo cha mlipuko wa kitambulisho chochote kinachovuja; na kuendesha usakinishaji kwa kutumia –puuza hati katika CI huondoa vekta ya kufunga-ndoano kabisa kwa vifurushi ambavyo havihitaji.
Kwa watetezi, ukaguzi wa vitendo ni: tahadhari kuhusu miunganisho inayotoka kutoka kwa vyombo vya ujenzi/CI hadi IP za umma ambazo hazijaorodheshwa wakati wa npm kufunga; angalia ufikiaji wa IMDS unaotokana na hati za mzunguko wa maisha ya kifurushi; na tumia ndoano yoyote ya usakinishaji inayolenga CLI ya wingu kama ya kutiliwa shaka hadi ithibitishwe vinginevyo.
Maelezo mawili zaidi kuhusu kundi hili. Kwanza, kwa sababu uanzishaji umeelekezwa kwenye mazingira yaliyo kwenye kontena, kifurushi kinachoonekana kuwa kisicho na kazi kinapochunguzwa kwenye kituo cha kazi bado kinaweza kuwa hai katika uzalishaji — uhakiki unahitaji kutoa tena jina la mwenyeji wa kontena na hali ya njia, au kusoma chanzo moja kwa moja, badala ya kutegemea "Nilikisakinisha na hakuna kilichotokea." Pili, matumizi ya huduma ya ukaguzi wa ombi la umma kama mkusanyaji wa beacon inamaanisha kuwa baadhi ya data iliyochujwa inaweza kupatikana kwa majibu ya tukio: shirika linalopata moja ya vifurushi hivi kwenye mti wake wa utegemezi linaweza kufikiria kuhusu kile beacon iliyofanikiwa ingekuwa nacho kutoka kwa mantiki ya ukusanyaji wa mzigo, na linapaswa kuzungusha sifa zozote za jukumu la IAM, tokeni za usajili, na siri zilizosimamiwa ambazo zingeweza kufikiwa kutoka kwa mazingira yaliyoathiriwa ya ujenzi au wakati wa utekelezaji. Mzunguko wa hati miliki, si kuondolewa kwa kifurushi, ni urekebishaji wa uendeshaji mara tu usakinishaji unapoanza kutumika.





