- Více kompromitovaných vydání Uživatel @7nohe/openapi-react-query-codegen vložil malware do projektů pomocí hooků založených na dotazech TanStack.
- Útočník zneužil únik z sandboxu binding.gyp a předinstalujte skripty pro spuštění obfuskovaného JavaScriptového datového zatížení během instalace npm.
- Užitečné zatížení shromažďuje rozsáhlé cloudové a vývojářské zkušenostia jejich exfiltrací do repozitářů GitHub ovládaných útočníkem.
- Ukradené žetony se pak používají k šířit malware do dalších balíčků npm a repozitářů GitHub, což otravuje širší dodavatelský řetězec JavaScriptu.
Pro týmy, které se spoléhají na TanStack Query jako svůj npm balíček pro správu stavu serveru v Reactu a dalších front-endových frameworkech, nedávný incident v dodavatelském řetězci ukazuje, jak rychle lze tuto důvěru podkopat. Oblíbený doprovodný nástroj, vytvořený speciálně pro generování typově bezpečných hooků TanStack Query ze schémat OpenAPI, byl nenápadně zneužit jako zbraň a vložen do registru npm se sofistikovaným malwarem.
Bezpečnostní experti popisují útok jako kampaň ve stylu TeamPCP , která znovu využívá mnoho teatrálních a technických vzorců z dřívějších incidentů. Tentokrát se však pozornost soustředí výhradně na vývojáře, kteří vytvářejí datovou vrstvu pomocí balíčku @7nohe/openapi-react-query-codegen, což je nástroj, který slibuje úsporu času automatickým generováním hooků TanStack Query namísto ručního psaní standardního kódu.
Jak se generátor kódu TanStack Query stal nástrojem pro doručování malwaru
Balíček, který je středem incidentu, @7nohe/openapi-react-query-codegen , je navržen tak, aby využíval specifikaci OpenAPI a generoval plně typované hooky kompatibilní s TanStack Query. S více než 150 000 staženími týdně se nachází v kritické části pro mnoho týmů, které standardizují TanStack Query pro orchestraci načítání, ukládání do mezipaměti a synchronizaci backendových dat ve svých frontendech založených na Reactu.
Podle pitvy se útočníkovi podařilo kompromitovat jak balíček npm, tak jeho repozitář GitHub . K narušení bezpečnosti došlo zneužitím zranitelnosti v jednom z pracovních postupů akcí GitHub projektu, což znamenalo, že škodlivé sestavení stále zdánlivě pocházela z legitimního CI pipeline a byla dodávána s platnými atestacemi původu. Tyto kryptografické atestace, které jsou obvykle silným signálem důvěryhodnosti pro uživatele npm, se staly zavádějícími, jakmile se samotný pracovní postup dostal pod nepřátelskou kontrolu.
Během krátkého časového úseku, zhruba dvaceti minut, útočník zveřejnil na npm deset infikovaných verzí balíčku, z nichž každá obsahovala kód určený ke spuštění během instalace a nabootování vícestupňového malwarového obsahu. Dotčené verze zahrnují několik menších verzí a patchů, které by nyní měly být považovány za nedůvěryhodné.
- @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
Všechny tyto varianty sdílejí stejný základní záměr: využít popularity balíčku mezi uživateli TanStack Query k zajištění spuštění kódu během instalace npm a následnému rozšíření širším dodavatelským řetězcem JavaScriptu.
Datový náklad „Trinitite“ a jeho triky spouštění během instalace
Malware se identifikuje ironicky. „Trinitite: Sponzorováno společností Preview 2 Effects“, odkaz na sklovitý materiál vytvořený jadernými testy. Dřívější interní názvy písma jako is_it_this_simple.js naznačují útočníkův ležérní přístup, ale základní technika je vším, jen ne zjednodušující.
Primární prováděcí hák se opírá o únik z sandboxu binding.gypV běžných projektech Node.js se binding.gyp používá ke konfiguraci nativních doplňků kompilovaných node-gyp, ale zde je zneužit jako zbraň. Když npm narazí na soubor binding.gyp, node-gyp vyhodnotí jeho conditions pole pomocí Pythonu. Útočník do tohoto pole vloží pečlivě sestavený výraz Pythonu a využije hierarchii tříd Pythonu k vymanění se z očekávané sandboxové zóny a spuštění libovolných příkazů shellu.
V kompromitovaném balíčku je výraz podmínek silně zahalen pomocí Unicode a hexadecimální escape kódyPo dekódování prochází interní Pythonovou __subclasses__ strom k nalezení catch_warnings třída, používá to jako pivot k dosažení __builtins__, importuje os modul a nakonec volá os.system() spustit hlavní datovou část pomocí Node. type pole v souboru binding.gyp je hexadecimálně kódováno jako none, takže se nepokouší o žádné skutečné nativní sestavení; konfigurace existuje čistě proto, aby do ní propašoval jediný příkaz shellu.
Tento přístup znamená, že balíček může spustit škodlivý kód během instalace i když neexistuje žádný explicitní preinstall skript definovaný v package.json. Ne všechny infikované verze se však spoléhají na tento přesný trik. Dvě předběžné verze používají přímočařejší předinstalační hooky: jedna spouští Node skript s názvem nu.js přímo, zatímco jiný načítá běhové prostředí Bun přes wget potrubím do bash a poté spustí příhodně pojmenovaný is_it_this_simple.jsNovější verze kombinují obě metody a dodávají škodlivý soubor binding.gyp. a a preinstall záznam odkazující na stejný hlavní datový obsah JavaScriptu kvůli redundanci.
Vrstvy obfuskace a obcházení sandboxu v hlavním datovém obsahu JavaScriptu
Jakmile se spustí první hook, útok se přesměruje do velkého JavaScriptového souboru s názvem 3FWCvzduYZg.js , který je umístěn v kořenovém adresáři balíčku npm. Skript o velikosti zhruba 5.4 MB a minimalizovaný na jeden řádek je navržen tak, aby byl na první pohled co nejneprůhlednější, a další analýza ukazuje, že je chráněn několika různými vrstvami šifrování a obfuskace.
Vnější vrstva se skládá z Celočíselné pole s 1.6 miliony prvků, dešifrovaný jednoduchým XOR s konstantou 29. Toto dešifrování vede k sekundárnímu skriptu, jehož úkolem je tiše načíst běhové prostředí Bun a uložit ho pod dočasným názvem souboru s trinnyyyy-XXXXX vzor v dočasném adresáři systému a poté pomocí Bun spustit skutečné jádro. Samotné jádro je zabaleno do šifrování AES-128-GCM a poté prochází vlastními šiframi nad standardními technikami obfuskace JavaScriptu, včetně těch, které se používají v populárních nástrojích, jako je obfuscator.io.
Plně rozbalený, tento hluboce vrstvený datový soubor odhaluje kombinaci funkcí: nástroj pro sběr přihlašovacích údajů zaměřený na širokou škálu cloudových a vývojářských platforem, červovou komponentu schopnou šířit infekci na nové cíle a destruktivní příkazový kanál. Než se cokoli z toho aktivuje, skript provede řadu kontrol prostředí, aby se vyhnul sandboxům a bezpečnostním nástrojům, a tiše ukončí svou činnost, pokud jsou splněny určité varovné podmínky.
Mezi kontrolami jsou indikátory lokalizace, prostředí a souborového systému běžně spojovaný s výzkumným prostředím. Malware se aktivuje, pokud je systémová lokalita ruská, pokud jsou přítomny adresáře patřící k produktům pro zabezpečení koncových bodů, jako jsou CrowdStrike, SentinelOne nebo Carbon Black, pokud aktuální pracovní adresář odpovídá cestám používaným známými nástroji pro skenování dodavatelského řetězce nebo pokud proměnné prostředí obsahují falešné přihlašovací údaje používané bezpečnostními skenery. Také se podívá na GITHUB_REPOSITORY_OWNER a přítomnost nástrojů pro zabezpečení, jako je například StepSecurity harden-runner, vyhýbaje se účtům GitHub, o kterých je známo, že patří bezpečnostním výzkumníkům.
Co malware krade z vývojových prostředí založených na dotazech TanStack
Jakmile jsou kontroly prostředí úspěšné, malware začne shromažďovat přihlašovací údaje širokou sítí. Zatímco původní balíček je koncipován jako pomocník pro uživatele TanStack Query, skutečná cílová plocha sahá daleko za hranice jedné knihovny a dotýká se téměř každé vrstvy nástrojů a cloudového stacku moderního vývojáře JavaScriptu.
Na straně vývojáře datová část vyhledává Osobní přístupové tokeny GitHubu v různých formátech, včetně klasických tokenů začínajících na gho or ghp a novější jemnozrnné tokeny začínající github_pat_Na běžcích akcí GitHub také požaduje tokeny OpenID Connect prostřednictvím dokumentovaného ACTIONS_ID_TOKEN_REQUEST_TOKEN a ACTIONS_ID_TOKEN_REQUEST_URL proměnné prostředí, což útočníkovi umožňuje předpokládat identity pracovní zátěže, nikoli pouze statické tajné kódy.
Skript se poté obrátí k registrům běžného jazyka. Čte Tokeny npm, PyPI a RubyGems z konfiguračních souborů, jako například ~/.npmrc, vyhledává další lokální projektové .npmrc soubory a pokusy o ověření nalezených tokenů nosičů npm voláním metody /-/whoami koncový bod ve veřejném registru. Podobné vzorce se používají pro PyPI a RubyGems, kde se těží ověřovací data a ověřuje se, že každý token může úspěšně komunikovat s příslušným registrem před jeho exfiltrací.
Cloudová stopa je ještě větší. Na Amazon Web Services malware vyjmenovává proměnné prostředí, jako například AWS_ACCESS_KEY_ID a AWS_SECRET_ACCESS_KEY, analyzuje ~/.aws/credentials a ~/.aws/configa dotazuje se služby metadat instancí EC2 na adrese 169.254.169.254, přičemž preferuje IMDSv2, ale v případě potřeby se vrací k původnímu. U kontejnerových úloh komunikuje s koncovým bodem metadat ECS na adrese 169.254.170.2Veškeré obnovené přihlašovací údaje nebo dočasné tokeny jsou testovány. sts:GetCallerIdentity k potvrzení platnosti před zařazením do fronty k exfiltraci.
Srovnatelná logika existuje i u jiných poskytovatelů cloudových služeb. Skript může shromažďovat Přihlašovací údaje klienta Azure a spravované identity, počítaje v to AZURE_CLIENT_ID, AZURE_CLIENT_SECRET a AZURE_TENANT_IDa poté po ověření přistupuje k Azure Key Vault, Azure Resource Manager a Microsoft Graph. V případě Google Cloudu vyhledává GOOGLE_APPLICATION_CREDENTIALS soubory, dotazuje se serveru metadat GCP na adrese metadata.google.internal a pokud je to možné, použije výsledné tokeny k volání Google Secret Manageru. Na seznamu jsou také nasazení HashiCorp Vault: datová část hledá adresy a tokeny Vaultu prostřednictvím proměnných prostředí a souborů tokenů a poté prozkoumává HTTP API Vaultu, aby vyjmenovala dostupné tajné klíče.
Kromě cloudového IAM provádí malware rozsáhlé prohledávání souborového systému s využitím více než 150 glob vzorůHledá soukromé klíče SSH, konfigurace Dockeru, .env soubory, úložiště přihlašovacích údajů Git, .npmrc a .pypirc soubory, přihlašovací údaje Terraformu a cargo, soubory historie shellu, data kryptoměnových peněženek a konfigurační adresáře pro široce používané aplikace pro zasílání zpráv, jako jsou Signal, Telegram Desktop, Discord, Slack a Element. Kontroluje také konfigurační soubory VPN ze služeb, jako jsou NordVPN, ProtonVPN, CyberGhost, PIA a další, spolu s tokeny a doménami pro správce binárních repozitářů, jako je JFrog Artifactory.
Únik dat prostřednictvím repozitářů GitHubu a commity „meow meow meow“
Poté, co malware shromáždí všechna tato tajná data, potřebuje místo, kam je odeslat. Útočníci se místo použití pevné domény pro příkazy a řízení, kterou by bylo možné snadno zablokovat, spoléhají na veřejné repozitáře GitHub jako kanál pro únik dat , čímž prolínají ukradená data s běžným tokom vývojářského provozu.
Účelová část nejprve prohledá historii commitů na GitHubu a vyhledá zprávy odpovídající specifickému vzoru, který vkládá zašifrovaný token na viditelném místě, a to pomocí fráze, která uživatele napomíná za jeho zrušení. Jakmile je takový commit nalezen, malware vložený token dešifruje a pomocí přidruženého účtu vytvoří nové úložiště, kde budou uložena ukradená data. Tato indirection znamená, že přihlašovací údaje odebrané od jedné oběti jsou uloženy v úložištích, která technicky vlastní jiný uživatel GitHubu, což ztěžuje vysledování sítě kompromitovaných úložišť k identitě jediného útočníka.
Nově vytvořené repozitáře mají rozmarná, automaticky generovaná jména složený ze dvou postav ze série Touhou Project a náhodného čísla, což vede k kombinacím jako cirno-marisa-74291 or reimu-kogasa-12048Jejich popisy jsou nastaveny na stejnou frázi „Trinitite: Sponzorováno společností Preview 2 Effects“, která je vidět v datové části, což poskytuje jeden z mála jasných ukazatelů pro obránce, kteří se snaží tyto repozitáře identifikovat ve velkém měřítku.
Ukradené přihlašovací údaje jsou ukládány jako šifrované soubory JSON uvnitř results/ adresář s použitím názvů souborů začínajících na doubletrinnys- následované čítačem a časovým razítkem. Každý soubor obsahuje envelope pole obsahující zašifrovaný datový balíček a key pole obsahující samotný šifrovací klíč, dále zabalené pomocí veřejného klíče RSA útočníka. Na první pohled vypadají jako libovolné zašifrované objekty blob. Pouze někdo s odpovídajícím soukromým klíčem může proces obrátit, takže i když jsou repozitáře nalezeny, skutečná tajemství zůstávají pro třetí strany neprůhlednáZprávy commitu jsou obvykle krátké a lehkovážné, s opakovaně používanými řetězci jako „meow meow meow“.
Šíření červů do jiných npm balíčků a projektů GitHubu
Jedním z nejvíce znepokojivých aspektů kampaně Trinitite je její schopnost znovu použít ukradené tokeny k ohrožení dalších balíčků a repozitářů . Malware se chová jako červ, který systematicky hledá způsoby, jak se šířit, místo aby se omezil na původní generátor kódu TanStack Query.
S platným npm tokenem v ruce datová část dotazuje npm API, aby vyjmenovala všechny tokeny spojené s účtem a vybrala nejprivilegovanější publikační token. Poté prohledá všechny balíčky vlastněné daným správcem, stáhne existující tarball pro každý z nich a do obsahu balíčku vloží stejný escape soubor binding.gyp sandbox a hlavní datový soubor. Po úpravách publikuje novou verzi do npm pod jménem legitimního správce, čímž efektivně promění důvěryhodné balíčky v nové vektory infekce . Podobné chování je implementováno pro PyPI a RubyGems prostřednictvím jejich příslušných upload endpointů, přičemž kontroly certifikátů TLS jsou v odchozích požadavcích zakázány, aby se předešlo problémům s pinningem na straně klienta.
S repozitáři GitHub se zachází srovnatelně. Když malware získá token GitHub s dostatečným rozsahem, vypíše všechny dostupné repozitáře a větve a přeskočí několik známých automatizačních větví, například ty s předponou . release/, dependabot/, renovate/ or copilot/Pro zbývající větve commituje sadu pečlivě vybraných souborů, které slouží jak jako zadní vrátka, tak jako propojení s moderními vývojářskými nástroji.
Mezi nimi jsou konfigurační soubory VS Code a Claude s backdoory, počítaje v to .vscode/tasks.json, .claude/settings.json a skripty jako setup.mjs které se spustí, když vývojář otevře projekt v určitých editorech s podporou umělé inteligence. Malware také uvolní falešný .github/workflows/codeql.yml pracovní postup, který se maskuje jako bezpečnostní sken a zároveň poskytuje další kanál pro spuštění kódu uvnitř CI. Další soubory jsou zaměřeny na další editory a nástroje, jako jsou Gemini, Cursor a různí asistenti kódu, což útočníkovi pomáhá udržovat perzistenci všude, kde vývojáři skutečně pracují.
Každý z těchto commitů je vytvořen pod github-actions identita, se zprávami, které vypadají jako běžná údržba, jako například „úkol: aktualizovat závislosti“ a označením upoutávky skip-checks:true proklouznout povinným kontrolám. Pro zaneprázdněný tým, který na první pohled prohledává protokoly commitů, si tyto změny může snadno zaměnit za neškodné aktualizace automatizace.
Indikátory kompromitace pro týmy používající nástroje TanStack Query
Pro organizace, které se spoléhají na TanStack Query a integrovaly @7nohe/openapi-react-query-codegen do svého pracovního postupu, začíná identifikace potenciálního ohrožení indikátory na úrovni verze a souboru, které nyní zdůraznilo několik zdrojů. Tyto indicie mohou pomoci přesně určit, které projekty mohly spustit kompromitovaný kód během instalačních kroků.
Jakékoli použití dotčených verzí @7nohe/openapi-react-query-codegen uvedených výše by mělo být považováno za podezřelé, zejména pokud byly sestavení prováděna na sdílené infrastruktuře CI nebo na noteboocích vývojářů s přístupem k citlivým přihlašovacím údajům. Bezpečnostním týmům se doporučuje auditovat soubory lockfile, historii package.json a protokoly sestavení, aby se potvrdilo, zda byly tyto verze někdy staženy do produkčního nebo testovacího prostředí.
Na disku je klíčovým znakem kompromitace přítomnost souboru 3FWCvzduYZg.js v kořenovém adresáři balíčku . Vyšetřovatelé katalogizovali několik SHA-256 hashů spojených s různými obfuskovanými sestaveními tohoto skriptu, přičemž všechny souvisejí se stejnou základní funkcionalitou:
- 8e5d1af68ca340ae0c6e8132cb00c686ec2d60502c1994d94ce353d1472ad5a3
- b49afb7dba04cd99b357ce7c652c823a3707f28e130bd5c6645851a7adc030d6
- 59370c67b54a0ccaedd265e2356f04540b2fba1e1845300ef6de4d5437d99380
- 778d6f0058045d6a2ab9a7e1d3e3be8e7e6b4d9cc217d13949bf1dfbab759a7c
- b24d121667f21f492cb9db34fbfd515d5922a8dd30b9c45215c7220abbb10ca8
- e1f1162ece9a6e6ea21a20399cbf31c563a8149d433a68711f4223870c203d5a
- b6012b2ff87f08f93ee53921c48db907ddbcf5461b03bb988083b01a36886237
- 709af2fdeb50324229e94c44c679a0fab18bd8e17d3864405989c526cbb63ad8
Kromě toho mnoho infikovaných hostitelů vytváří dočasné adresáře s názvy začínajícími na trinnyyyy- následovaný krátkým řetězcem náhodných alfanumerických znaků v dočasné složce systému. I když tento vzorec sám o sobě nedokazuje kompromitaci, v kombinaci s podezřelým souborem binding.gyp a jedním ze známých hashů datových částí výrazně zvyšuje pravděpodobnost, že se v daném systému spustil malware Trinitite.
Někteří dodavatelé bezpečnostních programů již tyto indikátory začlenili do svých detekčních kanálů. Například platformy zaměřené na vývojářské nástroje a bezpečnost dodavatelského řetězce nyní označují jakýkoli repozitář nebo projekt, který importuje postižené verze, jako kritický problém s malwarem a často jej hodnotí maximální úrovní závažnosti, aby bylo možné okamžitě provést vyšetřování. Týmy se vyzývají, aby spouštěly opakované kontroly napříč svými organizacemi, zejména v prostředích, kde je TanStack Query ústředním bodem architektury aplikací a nástroje pro generování kódu se široce používají.
Objevují se specializované nástroje a open-source utility, které se nacházejí před npm, yarn, pnpm a souvisejícími správci balíčků a před instalací kontrolují verze balíčků oproti vybraným informačním zdrojům. Cílem je zachytit škodlivé nebo podezřelé balíčky, zejména ty spojené s incidenty, jako je tento, ještě předtím, než se dostanou do systému. node_modules, čímž se snižuje riziko, že by kompromitovaná pomocná knihovna mohla nepřímo odhalit Aplikace založené na dotazech TanStack a s nimi spojenou infrastrukturu.
Pro vývojové týmy tento incident ukazuje, jak se zdánlivě neškodný balíček – takový, který jednoduše generuje typované hooky pro TanStack Query ze specifikace OpenAPI – může stát silným útočným vektorem, když je jeho CI pipeline a distribuční kanál narušen. Obranná opatření nyní musí přesahovat kontrolu hlavních závislostí aplikace a zahrnovat generátory, CLI a automatizační skripty, které tiše utvářejí, jak se tyto závislosti denně používají.