- Više kompromitovanih izdanja Iz @7nohe/openapi-react-query-codegen ubrizgali su zlonamjerni softver u projekte koristeći TanStack Query-bazirane hooks-ove.
- Napadač je zloupotrebio binding.gyp sandbox escape i prethodno instalirati skripte za izvršavanje obfusiranog JavaScript sadržaja tokom instalacije npm-a.
- Korisni teret prikuplja opsežne cloud i developerske akreditacije, prebacujući ih u GitHub repozitorije koje kontroliraju napadači.
- Ukradeni tokeni se zatim koriste za proširili zlonamjerni softver na više npm paketa i GitHub repozitorija, što truje širi lanac snabdijevanja JavaScriptom.
Za timove koji se oslanjaju na TanStack Query kao svoj glavni npm paket za upravljanje stanjem servera u Reactu i drugim front-end frameworkovima, nedavni incident u lancu snabdijevanja pokazuje koliko brzo to povjerenje može biti narušeno. Popularni prateći alat, izgrađen posebno za generiranje TanStack Query hookova sigurnih po tipu iz OpenAPI shema, tiho je pretvoren u oružje i ubačen u npm registar sa sofisticiranim ugrađenim malware paketom.
Sigurnosni istraživači opisuju napad kao kampanju u stilu TeamPCP-a koja ponovo koristi mnoge teatralnosti i tehničke obrasce viđene u ranijim incidentima. Međutim, ovaj put fokus je isključivo na programerima koji grade svoj sloj podataka koristeći paket @7nohe/openapi-react-query-codegen, uslužni program koji obećava uštedu vremena automatskim generiranjem TanStack Query hooks-ova umjesto ručnog pisanja standardnog koda.
Kako je generator koda TanStack Query postao sredstvo za isporuku zlonamjernog softvera
Paket koji je u središtu incidenta, @7nohe/openapi-react-query-codegen , dizajniran je da prihvati OpenAPI specifikaciju i emitira potpuno tipizirane hooks-ove kompatibilne s TanStack Queryjem. Sa preko 150,000 sedmičnih preuzimanja, nalazi se na kritičnom putu za mnoge timove koji standardiziraju TanStack Query kako bi orkestrirali dohvaćanje, keširanje i sinhronizaciju backend podataka u svojim React-baziranim frontendovima.
Prema obdukciji, napadač je uspio kompromitovati i npm paket i njegov GitHub repozitorij . Proboj je postignut iskorištavanjem ranjivosti u jednom od radnih procesa GitHub Actions projekta, što je značilo da su zlonamjerne verzije i dalje izgledale kao da dolaze iz legitimnog CI cjevovoda i isporučene su s važećim potvrdama o porijeklu. Te kriptografske potvrde, koje su obično snažan signal povjerenja za npm korisnike, postale su obmanjujuće kada je sam radni proces bio pod neprijateljskom kontrolom.
U uskom vremenskom okviru od oko dvadeset minuta, napadač je objavio deset zaraženih verzija paketa na npm-u, od kojih je svaka sadržavala kod dizajniran za izvršavanje tokom instalacije i pokretanje višefaznog malware payload-a. Zaražena izdanja obuhvataju nekoliko manjih verzija i zakrpa, a sve ih sada treba tretirati kao nepouzdane.
- @7nohe/openapi-react-query-codegen@0.5.4
- @7nohe/openapi-react-query-codegen@0.5.5
- @7nohe/openapi-react-query-codegen@1.6.3
- @7nohe/openapi-react-query-codegen@1.6.4
- @7nohe/openapi-react-query-codegen@2.2.1
- @7nohe/openapi-react-query-codegen@2.2.2
- @7nohe/openapi-react-query-codegen@3.0.3
- @7nohe/openapi-react-query-codegen@3.0.4
- @7nohe/openapi-react-query-codegen@0.0.0-365d4eb738d3146583431948d3ba6e27a32556be
- @7nohe/openapi-react-query-codegen@0.0.0-ec7876d6c917dad516ba69bbfafc948b834bf0ab
Sve ove varijante dijele istu osnovnu namjeru: iskoristiti popularnost paketa među korisnicima TanStack Queryja kako bi se postiglo izvršavanje koda tokom instalacije npm-a, a zatim proširiti kroz širi lanac snabdijevanja JavaScripta.
Korisni teret „Trinitite“ i njegovi trikovi izvršavanja tokom instalacije
Zlonamjerni softver se identificira ironičnom etiketom „Trinitite: Sponzorirano od strane Preview 2 Effects“, referenca na staklasti materijal formiran nuklearnim testovima. Raniji interni nazivi u pismu poput is_it_this_simple.js nagovještavaju ležeran stav napadača, ali osnovna tehnika je sve samo ne jednostavna.
Primarna izvršna kuka ovisi o binding.gyp sandbox escapeU normalnim Node.js projektima, binding.gyp se koristi za konfigurisanje izvornih dodataka koje kompajlira node-gyp, ali ovdje je iskorišćen kao oružje. Kada npm naiđe na datoteku binding.gyp, node-gyp evaluira njenu conditions polje koristeći Python. Napadač ubacuje pažljivo konstruisan Python izraz u to polje, iskorištavajući Pythonovu hijerarhiju klasa kako bi izašao iz očekivanog sandboxa i pokrenuo proizvoljne shell naredbe.
U kompromitovanom paketu, izraz uslova je u velikoj mjeri zamućen sa Unicode i heksadecimalni izlaziNakon dekodiranja, prolazi kroz Python-ove interne __subclasses__ drvo za lociranje catch_warnings razred, koristi to kao oslonac za postizanje __builtins__, uvozi os modul i konačno poziva os.system() za pokretanje glavnog korisnog tereta pomoću Node-a. type polje u binding.gyp datoteci je heksadecimalno kodirano kao none, tako da se ne pokušava nikakva prava izvorna izgradnja; konfiguracija postoji isključivo da bi se prokrijumčarila jedna shell naredba.
Ovaj pristup znači da paket može izvršavanje zlonamjernog koda tokom instalacije čak i ako nema eksplicitnog preinstall skripta definirana u package.json. Međutim, ne oslanjaju se sve zaražene verzije na ovaj trik. Dvije preliminarne verzije koriste jednostavnije preinstalacijske hooks-ove: jedna izvršava Node skriptu pod nazivom nu.js direktno, dok drugi dohvaća Bun runtime putem wget preusmjereno na bash a zatim pokreće prikladno nazvano is_it_this_simple.jsKasnije verzije kombiniraju obje metode, isporučujući zlonamjerni binding.gyp. i a preinstall unos koji upućuje na isti glavni JavaScript korisni teret radi redundancije.
Slojevi obfuskacije i izbjegavanje sandboxa u glavnom JavaScript korisnom teretu
Nakon što se početni hook aktivira, napad se preusmjerava na veliku JavaScript datoteku pod nazivom 3FWCvzduYZg.js , koja se nalazi u korijenu npm paketa. Sa otprilike 5.4 MB i minimiziranom na jednu liniju, skripta je dizajnirana da bude što je moguće netransparentnija na prvi pogled, a daljnja analiza pokazuje da je zaštićena s nekoliko različitih slojeva šifriranja i obfuskacije.
Najudaljeniji sloj se sastoji od Niz cijelih brojeva od 1.6 miliona elemenata, dešifrirano jednostavnim XOR-om u odnosu na konstantu 29. To dešifriranje daje sekundarni skript čiji je zadatak da tiho preuzme Bun runtime, spremajući ga pod privremenim imenom datoteke sa trinnyyyy-XXXXX obrazac u privremenom direktoriju sistema, a zatim koristiti Bun za izvršavanje pravog osnovnog sadržaja. Sam osnovni sadržaj je omotan AES-128-GCM enkripcijom, a zatim propušten kroz prilagođene šifre pored standardnih tehnika obfuskacije JavaScripta, uključujući one koje se vide u popularnim alatima poput obfuscator.io.
Potpuno raspakiran, ovaj duboko slojevit korisni sadržaj otkriva mješavinu mogućnosti: sakupljač vjerodajnica koji cilja širok raspon cloud i developerskih platformi, komponentu crva sposobnu za širenje infekcije na nove ciljeve i destruktivni komandni kanal. Prije nego što se bilo šta od toga aktivira, skripta vrši niz provjera okruženja kako bi izbjegla sandboxove i sigurnosne alate, tiho izlazeći ako su ispunjeni određeni indikativni uvjeti.
Među provjerama su indikatori lokalizacije, okruženja i datotečnog sistema obično se povezuje s istraživačkim okruženjima. Zlonamjerni softver se aktivira ako je sistemska lokalizacija ruska, ako su prisutni direktoriji koji pripadaju proizvodima za sigurnost krajnjih tačaka kao što su CrowdStrike, SentinelOne ili Carbon Black, ako se trenutni radni direktorij podudara s putanjama koje koriste poznati alati za skeniranje lanca snabdijevanja ili ako varijable okruženja sadrže lažne akreditive koje koriste sigurnosni skeneri. Također pregledava GITHUB_REPOSITORY_OWNER i prisustvo alata za osiguranje sigurnosti kao što je StepSecurity-jev harden-runner, izbjegavajući GitHub račune za koje se zna da pripadaju sigurnosnim istraživačima.
Šta zlonamjerni softver krade iz razvojnih okruženja zasnovanih na TanStack upitima
Nakon što prođu provjere okruženja, zlonamjerni softver počinje prikupljati podatke o identitetu širokom mrežom. Dok je originalni paket predstavljen kao pomoć korisnicima TanStack Queryja, stvarna ciljna površina doseže daleko izvan jedne biblioteke, dotičući gotovo svaki sloj modernog alatnog lanca i cloud steka JavaScript programera.
Na strani programera, korisni teret skenira GitHub lični tokeni za pristup u više formata, uključujući klasične tokene koji počinju sa gho or ghp i novije sitnozrnate tokene koji počinju sa github_pat_Na GitHub Actions runnerima, također zahtijeva OpenID Connect tokene putem dokumentiranog ACTIONS_ID_TOKEN_REQUEST_TOKEN i ACTIONS_ID_TOKEN_REQUEST_URL varijable okruženja, dajući napadaču put da preuzme identitete radnog opterećenja, a ne samo statičke tajne.
Skripta se zatim okreće registrima uobičajenog jezika. Čita npm, PyPI i RubyGems tokeni iz konfiguracijskih datoteka kao što su ~/.npmrc, skenira dodatne lokalne podatke za projekat .npmrc datoteke i pokušava validirati otkrivene npm nosioce tokena pozivanjem funkcije /-/whoami krajnja tačka na javnom registru. Slični obrasci se koriste za PyPI i RubyGems, rudarenjem podataka za autentifikaciju i potvrđivanjem da svaki token može uspješno komunicirati s odgovarajućim registrom prije njegovog izvlačenja.
Otisak u oblaku je još veći. Na Amazon Web Services, zlonamjerni softver nabraja varijable okruženja kao što su AWS_ACCESS_KEY_ID i AWS_SECRET_ACCESS_KEY, analizira ~/.aws/credentials i ~/.aws/configi šalje upite EC2 Instance Metadata Serviceu na 169.254.169.254, preferirajući IMDSv2, ali se vraćajući po potrebi. Za opterećenja kontejnera, komunicira s krajnjom tačkom metapodataka ECS-a na 169.254.170.2Svi podaci o akreditivima ili privremeni tokeni koje oporavi se testiraju. sts:GetCallerIdentity kako bi se potvrdila validnost prije nego što se stavi u red za izbacivanje.
Slična logika je prisutna i za druge pružatelje usluga u oblaku. Skripta može prikupljati Azure klijentski akreditivi i upravljani identiteti, uključujući AZURE_CLIENT_ID, AZURE_CLIENT_SECRET i AZURE_TENANT_ID, a zatim pristupiti Azure Key Vaultu, Azure Resource Manageru i Microsoft Graphu nakon autentifikacije. Za Google Cloud, traži GOOGLE_APPLICATION_CREDENTIALS datoteke, upituje GCP server metapodataka na metadata.google.internal i, kada je to moguće, koristi rezultirajuće tokene za pozivanje Google Secret Managera. Implementacije HashiCorp Vaulta su također na listi: korisni teret traži Vault adrese i tokene putem varijabli okruženja i tokenskih datoteka, a zatim ispituje Vaultov HTTP API kako bi nabrojao dostupne tajne.
Pored cloud IAM-a, zlonamjerni softver izvodi opsežne pregled datotečnog sistema korištenjem preko 150 glob obrazacaTraži SSH privatne ključeve, Docker konfiguracije, .env datoteke, pohrane Git vjerodajnica, .npmrc i .pypirc datoteke, Terraform i cargo vjerodajnice, datoteke historije ljuske, podaci o kripto novčaniku i konfiguracijski direktoriji za široko korištene aplikacije za razmjenu poruka poput Signala, Telegram Desktopa, Discorda, Slacka i Elementa. Također provjerava VPN konfiguracijske datoteke iz servisa uključujući NordVPN, ProtonVPN, CyberGhost, PIA i druge, zajedno s tokenima i domenama za upravitelje binarnih repozitorija kao što je JFrog Artifactory.
Izvlačenje podataka putem GitHub repozitorija i "mijau mijau mijau" commitova
Nakon što prikupi sve ove tajne, zlonamjernom softveru je potrebno mjesto za njihovo slanje. Umjesto korištenja fiksne komandno-kontrolne domene koja se može lako blokirati, napadači se oslanjaju na javne GitHub repozitorije kao kanal za izvlačenje podataka , miješajući ukradene podatke u normalan tok saobraćaja programera.
Korisni teret prvo pretražuje historiju javnih potvrda (commit) na GitHub-u za poruke koje odgovaraju određenom obrascu koji ugrađuje šifrirani token na vidljivom mjestu, koristeći frazu koja grdi korisnike zbog njegovog opoziva. Nakon što se pronađe takva potvrda, zlonamjerni softver dešifrira ugrađeni token i koristi pridruženi račun za kreiranje novog repozitorija u kojem će se pohraniti ukradeni podaci. Ova indirekcije znači da se akreditivi uzeti od jedne žrtve pohranjuju u repozitorije koje tehnički posjeduje drugi korisnik GitHub-a, što otežava praćenje mreže kompromitovanih repozitorija do identiteta jednog napadača.
Novokreirani repozitoriji imaju hirovita, automatski generirana imena sastavljen od dva lika iz serije Touhou Project i slučajnog broja, što rezultira kombinacijama poput cirno-marisa-74291 or reimu-kogasa-12048Njihovi opisi su postavljeni na istu frazu "Trinitite: Sponzorirano od strane Preview 2 Effects" koja se vidi u korisnom teretu, što pruža jedan od rijetkih jasnih markera za branitelje koji pokušavaju identificirati ove repozitorije u velikom broju.
Ukradeni akreditivi se prenose kao šifrirane JSON datoteke unutar results/ direktorij, koristeći nazive datoteka koji počinju sa doubletrinnys- nakon čega slijede brojač i vremenska oznaka. Svaka datoteka sadrži envelope polje koje sadrži šifrirani paket podataka i key polje koje sadrži sam ključ za šifriranje, dodatno umotano pomoću napadačevog javnog RSA ključa. Na prvi pogled, ovo izgleda kao proizvoljna šifrirana blob-a. Samo neko sa odgovarajućim privatnim ključem može preokrenuti proces, tako da čak i ako se pronađu repozitoriji, stvarne tajne ostaju nevidljive trećim stranamaPoruke commita su obično kratke i neozbiljne, s nizovima znakova poput „mijau mijau mijau“ koji se koriste više puta.
Širenje nalik crvu u druge npm pakete i GitHub projekte
Jedan od najzabrinjavajućih aspekata Trinitite kampanje je njena sposobnost ponovne upotrebe ukradenih tokena za kompromitovanje dodatnih paketa i repozitorija . Umjesto da se ograniči na originalni paket generatora koda TanStack Query, zlonamjerni softver se ponaša kao crv, sistematski tražeći načine za širenje.
S važećim npm tokenom u ruci, korisni teret (payload) upituje npm API kako bi nabrojao sve tokene povezane s računom, odabirući najprivilegiraniji token za objavljivanje. Zatim vrši pretragu za svaki paket u vlasništvu tog održavatelja, preuzima postojeću tarball datoteku za svaki i ubrizgava isti binding.gyp sandbox escape i glavnu datoteku korisnog tereta u sadržaj paketa. Nakon modifikacija, objavljuje novu verziju na npm-u pod imenom legitimnog održavatelja, efektivno pretvarajući pouzdane pakete u nove vektore infekcije . Slično ponašanje je implementirano za PyPI i RubyGems putem njihovih odgovarajućih krajnjih tačaka za otpremanje, s onemogućenim provjerama TLS certifikata u odlaznim zahtjevima kako bi se izbjegli problemi s pinningom na strani klijenta.
GitHub repozitoriji se tretiraju na sličan način. Kada zlonamjerni softver dobije GitHub token sa dovoljnim opsegom, on navodi svaki dostupni repozitorij i granu, preskačući nekoliko poznatih grana automatizacije, kao što su one sa prefiksom release/, dependabot/, renovate/ or copilot/Za preostale grane, commituje skup pažljivo odabranih datoteka koje služe i kao backdoor-ovi i kao udice za moderne alate za razvoj.
Među njima su Zatajene VS Code i Claude konfiguracijske datoteke, uključujući .vscode/tasks.json, .claude/settings.json i skripte poput setup.mjs koji se izvršavaju kada programer otvori projekat u određenim editorima uz pomoć vještačke inteligencije. Zlonamjerni softver također izbacuje lažni .github/workflows/codeql.yml tok rada koji se maskira kao sigurnosno skeniranje, a istovremeno pruža još jedan kanal za izvršavanje koda unutar CI-ja. Dodatne datoteke su usmjerene na druge uređivače i alate, kao što su Gemini, Cursor i razni asistenti koda, pomažući napadaču da održi postojanost gdje god programeri zapravo rade.
Svaki od ovih commitova je napisan pod github-actions identitet, s porukama koje izgledaju kao rutinsko održavanje poput „zadatak: ažuriranje zavisnosti“ i označavanje najave skip-checks:true promaknuti obaveznim provjerama. Zauzetom timu koji na prvi pogled pregleda zapise o promjenama, ove promjene se lako mogu zamijeniti za bezopasna ažuriranja automatizacije.
Pokazatelji kompromitovanja za timove koji koriste TanStack alate za upite
Za organizacije koje se oslanjaju na TanStack Query i koje su integrirale @7nohe/openapi-react-query-codegen u svoj radni proces, identifikacija potencijalne izloženosti počinje s indikatorima na nivou verzije i datoteke koje su sada istakli višestruki izvori. Ovi tragovi mogu pomoći u utvrđivanju koji su projekti možda pokrenuli kompromitovani kod tokom koraka instalacije.
Bilo kakva upotreba pogođenih verzija @7nohe/openapi-react-query-codegen navedenih ranije treba se tretirati kao sumnjiva, posebno ako su izgradnje izvršene na dijeljenoj CI infrastrukturi ili laptopima programera s pristupom osjetljivim podacima. Sigurnosnim timovima se savjetuje da revidiraju lockfiles, historiju package.json i logove izgradnje kako bi potvrdili da li su ta izdanja ikada ubačena u produkcijsko ili pripremno okruženje.
Na disku, ključni znak kompromitacije je prisustvo datoteke 3FWCvzduYZg.js u korijenskom direktorijumu paketa . Istražitelji su katalogizirali nekoliko SHA-256 heševa povezanih s različitim obfusciranim verzijama ovog skripta, a svi su povezani s istom osnovnom funkcionalnošću:
- 8e5d1af68ca340ae0c6e8132cb00c686ec2d60502c1994d94ce353d1472ad5a3
- b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6
- 59370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380
- 778d6f0058045d6a2ab9a7e1d3e3be8e7e6b4d9cc217d13949bf1dfbab759a7c
- b24d121667f21f492cb9db34fbfd515d5922a8dd30b9c45215c7220abbb10ca8
- e1f1162ece9a6e6ea21a20399cbf31c563a8149d433a68711f4223870c203d5a
- b6012b2ff87f08f93ee53921c48db907ddbcf5461b03bb988083b01a36886237
- 709af2fdeb50324229e94c44c679a0fab18bd8e17d3864405989c526cbb63ad8
Osim toga, mnogi zaraženi hostovi kreiraju privremene direktorije s imenima koja počinju sa trinnyyyy- nakon čega slijedi kratki niz nasumičnih alfanumeričkih znakova u privremenoj mapi sistema. Iako ovaj obrazac sam po sebi ne dokazuje kompromitaciju, u kombinaciji sa sumnjivom datotekom binding.gyp i jednim od poznatih heševa korisnog tereta, značajno povećava vjerovatnoću da se zlonamjerni softver Trinitite izvršio na tom sistemu.
Neki dobavljači sigurnosnih rješenja već su uključili ove indikatore u svoje feedove za detekciju. Na primjer, platforme fokusirane na alate za razvojne programere i sigurnost lanca snabdijevanja sada označavaju svaki repozitorij ili projekat koji uvozi pogođene verzije kao kritičan problem sa zlonamjernim softverom , često ga ocjenjujući na maksimalnom nivou ozbiljnosti kako bi se podstakla hitna istraga. Timovi se podstiču da pokrenu ponovna skeniranja u svojim organizacijama, posebno u okruženjima gdje je TanStack Query ključan za arhitekturu aplikacija i gdje se alati za generisanje koda široko koriste.
Pojavljuju se specijalizirani alati i open-source programi koji se nalaze ispred npm-a, yarn-a, pnpm-a i srodnih upravitelja paketa, provjeravajući verzije paketa u odnosu na odabrane obavještajne podatke prije instalacije. Ideja je presresti zlonamjerne ili sumnjive pakete, posebno one povezane s incidentima poput ovog, prije nego što uopće stignu u... node_modules, smanjujući rizik koji kompromitovana pomoćna biblioteka može indirektno izložiti Aplikacije zasnovane na upitima TanStack-a i njihovu pripadajuću infrastrukturu.
Za razvojne timove, ovaj incident pokazuje kako naizgled bezopasan paket za praktičnost - onaj koji jednostavno generira tipizirane hooke-ove za TanStack Query iz OpenAPI specifikacije - može postati snažan vektor napada kada se njegov CI cjevovod i distribucijski kanal naruše. Odbrambene mjere sada moraju ići dalje od provjere glavnih ovisnosti aplikacije i uključivati generatore, CLI-jeve i skripte za automatizaciju koje tiho oblikuju način na koji se te ovisnosti koriste svaki dan.