Nasira ang mga npm Package ng Red Hat Cloud Services sa isang pag-atake na supply chain poisoning

iconMetaEra
I-share
Share IconShare IconShare IconShare IconShare IconShare IconCopy
AI summary iconSummary

expand icon
Isinulat sa on-chain news mula sa MetaEra na may nangyaring security breach sa ilang npm packages sa ilalim ng Red Hat Cloud Services organization. Tinuklasan ng sistemang MistEye ang 96 na masasamang bersyon sa loob ng 32 packages, kung saan tatlo ang sinuri nang detalyado. Ang masasamang code sa mga package tulad ng @redhat-cloud-services/frontend-components-config@6.11.3 ay nagpapatakbo habang ang pag-install ay nasa proseso sa pamamagitan ng preinstall hook. Ang malware, isang variant ng Shai-Hulud, ay naglalaman ng pagkukuha ng credentials at pagpapakalat sa CI/CD. Gumamit ang mga attacker ng ROT/Caesar shifts, AES-GCM, at B5 encryption upang itago ang payload, na kumakalat sa pamamagitan ng npm at GitHub workflows.

Konteksto

Kabila ng ilang araw, ang MistEye Security Monitoring System ay nakuha ang impormasyon tungkol sa anomalous na bersyon ng maraming npm packages sa ilalim ng Red Hat Cloud Services organization. Kasali sa insidente ang 32 npm packages at 96 bersyon sa ilalim ng organisasyon. Sa artikulong ito, pinili namin ang 3 lokal na sample para sa mas malalim na offline na pagsusuri: ang mga sample na ito ay hindi mga imitasyon ng namespace o typo-squatting packages, kundi totoong bersyon ng mga package na gumagamit ng @redhat-cloud-services scope; mula sa source code ng sample, napatotohanan na may naka-implant na maraming antas ng混淆 malicious loader na awtomatikong magpapatakbo sa panahon ng installation.

Matapos ang buong pagbabalik, maaaring patunayan: ang pangunahing load ng 3 na sample ay may kakayahan sa pagbabasa ng memorya ng GitHub Actions Runner, pagkuha ng mga kredensyal mula sa maraming cloud at lokal, pagpapadala sa GitHub API at dead-drop, pagpapaloob sa GitHub workflow, self-propagation sa npm, persistence sa Claude Code / VS Code / systemd / LaunchAgent, pagtutol sa Harden-Runner / StepSecurity, at pagdetekta ng EDR / security products. Batay sa sakop ng mga kakayahan, ang mga posibleng biktima ay kasama ang developer host, CI/CD Runner, build container, GitHub repository, GitHub Actions workflow, npm distribution pipeline, at cloud environment credentials; ang aktwal na sakop ay kailangang patunayan sa pamamagitan ng installation logs, repository audit, at platform-side telemetry.

Batay sa istruktura ng code, landas ng pagkalat, at kombinasyon ng kakayahan, ang malware na ito ay isang variant ng Shai-Hulud malware.

MistEye response

Ang MistEye ay isang sariling inimbento ng SlowMist na Web3 threat intelligence at dynamic security monitoring system na nagtatampok ng kakayahan sa security monitoring at intelligence aggregation upang magbigay ng real-time na babala sa panganib at proteksyon sa mga ari-arian para sa mga user.

Pagkatapos makakuha ng supply chain poisoning event na ito sa Red Hat Cloud Services npm package at ang kaugnay na masasamang sample, ang MistEye system ay nag-trigger ng mataas na antas ng alert at nag-sistemang pagsusuri sa pagkakabulok na istruktura, pag-decrypt ng payload, pagbabalik ng kakayahan, at IOC ng serbisyo.

(https://enterprise.misteye.io/threat-intelligence/SM-2026-378450)

Overview ng Attack Chain

Ang teknikal na pagsusuri sa artikulong ito ay batay lamang sa lokal, offline, at static na pagsusuri, na naglalayong i-unpack, idecode, at i-verify ang pagkakawala ng pagkakagulo sa 3 npm tgz samples.

Ang mga sample na sakop ng pagpapatotoo ay sumusunod:

@redhat-cloud-services/frontend-components-config

Bersyon: 6.11.3

tgz SHA-256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

@redhat-cloud-services/types

Bersyon: 3.6.1

tgz SHA-256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

@redhat-cloud-services/rule-components

Bersyon: 4.7.2

tgz SHA-256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

Ang tatlong sample ay may magkakaparehong entry point ng pag-atake: ang lahat ng package.json ay may scripts.preinstall = "node index.js". Ibig sabihin nito, kahit anong developer host o CI/CD environment ang mag-install ng mga bersyon na ito, ang root directory na index.js ay awtomatikong i-execute sa panahon ng installation, nang walang kailangang mag-import o i-run ang business code nang eksplisito.

Ang tatlong sample ay nagbabahagi ng iisang pangunahing masamang payload, ngunit may iba’t ibang parametrong panlabas. Ibig sabihin, ang tatlong sample ay gumagamit ng iba’t ibang halaga ng ROT/Caesar shift at iba’t ibang AES-GCM key/iv/tag; ang ganitong pagkakaiba ay nagiging mahirap gamitin ang mga static feature na batay sa hash ng panlabas na balot, fixed key, o fixed shift para sa cross-sample reuse. Gayunpaman, ang Bun runtime bootloader at ang pangunahing masamang payload ay may magkakaparehong hash: ang isa ay isang startup helper module para sa paghahanda ng Bun runtime environment, habang ang isa pa ay ang tunay na naglalaman ng masamang functionality. Ipinapakilala ng artikulong ito ang dalawang ito bilang "Bun Runtime Bootloader (variable name _b)" at "Pangunahing Masamang Payload (variable name _p)".

Ang nakarehistradong serye ng pag-atake ay sumusunod:

Technical Analysis

1. Entry: npm lifecycle script hijacking

Ang lahat ng tatlong sample ay nagtriggers ng chain ng pag-atake sa pamamagitan ng preinstall lifecycle hook sa package.json:

"scripts": {

"preinstall": "node index.js"

}

Ang preinstall ay awtomatikong masisigla sa panahon ng npm installation. Para sa karaniwang frontend components, type definitions, o package ng rule components, karaniwang hindi kailangang patakbuhin ang isang malaking JavaScript file sa root directory sa panahon ng installation; ito ang pinakadirektang signal ng anomaliya.

Ang mga ebidensya sa antas ng sample ay sumusunod:

@redhat-cloud-services/frontend-components-config@6.11.3

  • main: lib/index.js
  • mga file na field: ["/lib", "/bin"]
  • Root directory index.js SHA-256: 545a1838c66e1771f58d84a17b3e1841e5eeab91a73f4ccc59c9492450a6d9c0

@redhat-cloud-services/types@3.6.1

  • main: index.d.ts
  • 字段 files: Hindi itinakda
  • Root directory index.js SHA-256: b86c5ae9e95bd841a595440faa3eb6317441e746f241ae8fd641ab59ed1d1966

@redhat-cloud-services/rule-components@4.7.2

  • main: index.js
  • 字段 files: Hindi itinakda
  • Root directory index.js SHA-256: 1a30a9abe20bab121aaa75ed040565af14e6cdfb745609ee0e7b94a2d814fb9c

Sa kanilang mga files field, ang frontend-components-config@6.11.3 ay naglalayong tanging "/lib" at "/bin", ngunit may karagdagang index.js sa root ng tarball na tinatawag ng preinstall. Ang anomaliyang ito ay nakikita lamang sa sample na ito; ang types@3.6.1 at rule-components@4.7.2 ay hindi nagtatatakda ng files field, kaya hindi ito ipinapalawig sa lahat ng sample.

2. Unang antas: Array ng mga numero + ROT/Caesar pagpapalit ng mga letra

Ang root directory ng tatlong sample ay ang index.js, na isang napakalaking single-line JavaScript file, may magkakaparehong istruktura, at ang pangunahang bahagi ay isang try { eval(...) } catch (...) wrapper:

Ang wrapper ay una ay nagpapabalik sa malaking array ng mga numero gamit ang String.fromCharCode upang makuha ang string, pagkatapos ay nagpapagalaw ng ROT/Caesar sa mga titik ng Ingles sa string, at huling ipinapasa ang decoded result sa eval para i-execute. Ang pag-handle ng error ay naglalabas lamang ng prefix na wrapper: upang mabawasan ang pagkakakita ng malalaking error kapag nabigo ang installation.

Ang mga panlabas na displacement values at Stage 2 hash ng tatlong sample ay sumusunod:

frontend-components-config@6.11.3

index.js na laki: 4,294,798 bytes

ROT/Caesar shift: 10

Stage 2 SHA-256: b19c2fd48535c8c40aeb3e627ce92775f33ef9292611767bb1236c238e6f90cc

types@3.6.1

index.js laki: 4,135,588 bytes

ROT/Caesar shift: 4

Stage 2 SHA-256: 9c0425aa6e6d7792ac38d24f3e7245f42fcaa553ddfeb6bd97677017f10c3b75

rule-components@4.7.2

index.js laki: 4,294,336 bytes

ROT/Caesar shift: 11

Stage 2 SHA-256: d590bd375d95e4ac072b7ebc1fc4489bcaf5f20a939e92486267aa398bcf1e5d

3. Pangalawang layer: AES-128-GCM decryption ng Bun bootloader at core payload

Ang Stage 2 code na natuklasan sa ROT/Caesar decryption ay ginagamit ang Node.js crypto.createDecipheriv upang i-decrypt ang AES-128-GCM (Advanced Encryption Standard - Galois/Counter Mode) at nagtatag ng authentication tag sa pamamagitan ng setAuthTag. Ang layunin ng decryption ay ang dalawang susunod na komponente—ang Bun runtime bootstrapper at ang pangunahing malicious payload.

Kung saan, ang Bun Runtime Bootstrapper ang responsable sa pagdetekta, pagpapakita, o paghahanda ng Bun runtime environment upang makapagpapatuloy ang susunod na code sa pamamagitan ng Bun; ang pangunahing masamang load naman ay ang pangunahing bahagi ng attack chain, na naglalaman ng mga pangunahing masamang kakayahan tulad ng pagkuha ng mga kredensyal, pagpropaganda sa GitHub/npm, pagpapanatili, pagtutol sa pagprotekta, at pag-dekripta ng mga nakapirming yaman.

Gumamit ang bawat isa sa tatlong sample ng iba’t ibang AES-128-GCM key, initial vector, at authentication tag upang i-encrypt ang dalawang komponente, ngunit ang SHA-256 ng bawat isa sa tatlong Bun runtime bootloaders ay ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6, habang ang SHA-256 ng bawat isa sa tatlong core malicious payload ay 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35. Ipinapakita nito na ang mga attacker ay nagpalit ng mga panlabas na parameter sa iba’t ibang npm packages, ngunit ginamit muli ang parehong set ng core malicious components.

Pagkatapos ng dekriptasyon, isusulat ng Stage 2 ang pangunahing masamang load sa /tmp, ipapalabas ito sa pamamagitan ng Bun, at pagkatapos ay ihihiwalay ang pansamantalang file. Ang tunay na lohika na muling isinaayos mula sa tatlong sample ay sumusunod:

Kaya, ang verifiable temporary file pattern sa tatlong sample ay:

/tmp/p.js

Ang laki ng booter ng Bun ay 898 bytes, at ang tatlong sample hash ay ganap na magkakatulad:

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

Ang Bun Runtime Bootstrapper ay naglalaman ng mga lohika tulad ng child_process.execSync, fs.existsSync, fs.mkdtempSync, fs.chmodSync, os.platform(), os.arch(), at getBunPath() upang matukoy o ihanda ang Bun runtime environment. Ibig sabihin, ang Stage 2 ay hindi simpleng nag-aassumption na ang sistemang global na Bun ay naka-install; sa mga path na hindi Bun runtime, una itong lalabas ng Bun Runtime Bootstrapper, at pagkatapos ay gamitin ang getBunPath() upang i-trigger ang Bun para isapuso ang pangunahing malisious payload.

4. Ikatlong antas: obfuscator.io string table

Ang pangunahang masamang load na nalabas ay hindi direktang mababasa na plain text JavaScript, kundi patuloy na pinaghihiwalay gamit ang obfuscator.io-style na pagkakalat ng mga string. Ang antas na ito ay naglalagay ng maraming string sa isang array at ginagamit ang runtime index at rotation logic upang muling ibalik, na nagiging sanhi na hindi makapag-retrieve ang mga analyst ng mga susunod na mahahalagang API, path, at pangalan ng konfigurasyon bago mabuo ang pagkakalat ng mga string.

5. Ikaapat na antas: B5 Custom String Encryption

Pagkatapos i-recover ang string table ng obfuscator.io, nananatili pa ang isang layer ng B5 custom string encryption sa core malicious payload. Kumpirmado ang mga parameter sumusunod:

  • KDF: PBKDF2 (Password-Based Key Derivation Function 2)
  • Hash function: SHA-256
  • Bilang ng iterasyon: 200000
  • haba ng key: 32 bytes
  • Bilang ng mga round ng decryption: 3
  • password: ba2c6ddb3672bdd6a611e6850b4f700b52aed3dab2f1b3d5f8c839d4a157a709
  • salt: 5b26508dc0f1075a7c0b4d8aa464487e

Ang resulta pagkatapos ng pag-decrypt ay:

Sa loob nito, maaaring makita ang maraming mahahalagang malinaw na string pagkatapos ng B5 decryption. Dapat tandaan, ang ilang mga string ay orihinal na nasa obfuscator.io string table, at tanging pagkatapos ng dalawang hakbang na “string table replacement + B5 decryption” lamang sila ay diretso na grepable:

6. Karagdagang embedded layer: AES-256-GCM + gzip

Ang loob ng pangunahing masamang load ay naglalaman din ng mga embedded resource na encrypted gamit ang AES-256-GCM at compressed gamit ang gzip. Ang proseso ng pagbabalik ay gumagamit ng:

Ang mga nakalutas na pangunahing embedded resource ay nahahati sa tatlong kategorya ayon sa kanilang pag-andar:

Cross-platform memory reading:

Ginagamit ang mga yaman na ito upang basahin ang memory ng mga nagpapatakbo na proseso. Ang mga key at token sa karaniwang file ay maaaring makita sa pamamagitan ng paghahanap sa file, ngunit ang CI/CD Runner o mga development tool ay nag-iimbak ng ilang sensitibong halaga sa memory habang nagpapatakbo. Ikinakasal sa mga script na pagbasa ng memory para sa Linux, Windows, at macOS upang makakuha ng mga pansamantalang secret na lumalabas sa memory ng proseso sa iba’t ibang sistema.

Persistent configuration:

Ginagamit ang mga resource na ito upang “iwanan ang backdoor trigger points.” Ibig sabihin, kahit na natapos na ang orihinal na proseso ng npm installation, gustong patakbuhin muli ng attacker ang masasamang code habang buksan ng developer ang proyekto, i-start ang editor, pumasok sa sesyon ng Claude Code, o pagkatapos ng system reboot. Kaya, tinutukoy ng mga resource na ito ang project-level configuration at user-level autostart mechanisms: mas nakakatago ang project-level configuration, habang mas angkop ang system-level services para sa pangmatagalang pagpapatakbo.

C2 at Pagpapalaganap:

Ang mga embedded resource na ito ay ginagamit para sa pagkontrol ng chain at paghahatid ng repository secrets. Pagkatapos ng dekripto ni YZ, ito ay GitHub commit search monitor na magpapalabas nang periodic na paghahanap sa commit message na may anyong firedalazer ., at pagkatapos ay i-verify ang signature bago i-download at i-execute ang remote Python content; ang zZ naman, pagkatapos ng dekripto, ay isang template ng GitHub Actions workflow na tinatawag na Run Copilot na mag-aayos ng ${{ toJSON(secrets) }} sa format-results.txt at i-upload bilang artifact. Ang unang isa ay nagbibigay ng chain para sa pagkuha/at pagsasagawa ng mga susunod na gawain, habang ang pangalawa ay nagbibigay ng template para sa paghahatid ng repository secrets gamit ang GitHub Actions artifact; ang aktwal na pag-inject ng workflow, pag-antay sa pagpapatakbo, at pag-download ng artifact ay natatapos ng kasamang GitHub API logic sa pangunahing payload.

Pagsusuri ng Kakayahan ng Pangunahing Masamang Load

Pagkatapos ng maraming antas ng pagpapalawig, ang huling inilabas at pinagana ng sample ay ang pangunahing masamang load. Ang lahat ng sumusunod na pagsusuri ay nakatuon sa pangunahing module ng masamang load, na hihiwalay ayon sa limang yugto: pagkuha ng data, pagpapadala sa labas, pagpapalaganap, pagpapanatili, at pagtutol.

1. Pagbasa sa memorya ng GitHub Actions Runner:

Ang sample ay naglalaman ng mga script para sa pagbabasa ng memorya sa mga platform na Linux, Windows, at macOS, na may kakayahang mag-dump sa lahat ng platform. Ang implementasyon sa Linux ay ginagawa sa pamamagitan ng pagbabasa ng /proc//maps at /proc//mem ng target process:

Ang aktibong logika para sa pangunahing mapanirang load ay nakatuon sa GitHub Actions Linux runner: kapag ang GITHUB_ACTIONS === "true" at ang RUNNER_OS === "Linux", ang code ay naghahanap ng Runner.Worker process at nag-dump ng memorya, pagkatapos ay kinukuha ang mga "masked secrets" sa anyong "":{"value":"","isSecret":true}. Ang mga aktibong landas ng pagkuha na napatunayan sa tatlong sample ay nakatuon sa Linux runner, ngunit ang mga script para sa lahat ng tatlong platform ay naka-embed na.

2. Multi-cloud at pagkuha ng lokal na kredensyal ng developer:

Ang pangunahang masamang load ay naglalaman ng sistematikong module para sa pagkolekta ng mga kredensyal, na kumakapit sa mga cloud provider, CI environment, lokal na konfigurasyon ng developer, GitHub CLI, password manager, at mga file ng wallet.

Mga layunin ng pagkolekta ng mga kredensyal ng cloud provider:

Ang AWS module ay naglalaman din ng mga lohika kaugnay ng ECS/IMDS (Instance Metadata Service)/STS WebIdentity.

Ang pagkolekta ng lokal na kredensyal ng developer ay nakakapalupit sa mga sumusunod na layunin:

Ang lohika ng password manager ay implemementado sa source code bilang array ng runCommand(command, args), hindi bilang string concatenation ng shell.

Ang module na ito para sa pagkolekta ng mga kredensyal ay nakakapalibot sa isang malawak na target mula sa cloud platform hanggang sa lokal ng developer; ang mga nakolektang sensitibong data ay ipinapadala sa pamamagitan ng mga mekanismo na nakalista sa ibaba.

3. GitHub API at dead-drop:

Ang pangunahang malikhaing load ay gumagamit ng GitHub API bilang pangunahing channel para sa paglabas ng data. Ang mga kahilingan ay nagpapakita ng User-Agent bilang python-requests/2.31.0, at pagkatapos ay maaaring magpapatunay ng token gamit ang x-oauth-scopes (kailangan ng repo, public_repo, o workflow) bago magpapatupad ng paglabas: lumikha ng repository (ang description ay palaging Miasma: The Spreading Blight), at isusulat ang nakuha na data na base64-encoded sa pamamagitan ng PUT /repos///contents/results/.

Dagdag pa, ang payload ay nagpapatupad ng mekanismo na batay sa GitHub commit search para sa dead-drop, kung saan ang C2 commands ay kinukuha sa pamamagitan ng paghahanap ng marker "thebeautifulmarchoftime" (o "thebeautifulsnadsoftime"):

magkaroon ng result = await X9("thebeautifulmarchoftime ", xZ);

Ang embedded resource YZ.bin ay isang independiyenteng GitHub commit monitor na nag-poll sa bawat 3600 segundo para hanapin ang commit message na may format na firedalazer . Pagkatapos makapasa ang signature verification, i-download at i-execute ang remote Python content. Ito ay bumubuo ng isang independiyenteng susunod na control link na hiwalay sa pangunahing exfiltration channel.

Ang source code ay naglalaman din ng isang HTTP POST sender configuration na may target endpoint na api.anthropic.com at v1/api. Ang field na noop ng configuration ay itinakda bilang true, na nangangahulugan na hindi ito magpapadala ng aktwal na network request kung hindi ito binago ng panlabas. Kaya, ang static analysis ay maaaring patunayan lamang ang pagkakaroon ng code structure, hindi ang pagkakaroon ng aktibong Anthropic API data exfiltration.

4. GitHub repository at workflow infection:

Ang pangunahang masamang load ay maaaring i-operate ang git objects ng repository gamit ang GitHub REST / GraphQL API:

Ang masamang workflow na binuo ay nagpapahinggil ng id-token: write permission sa pangalan ng release, at gumagamit ng OIDC (OpenID Connect) path upang palitan ang npm publishing token. Ang mga environment variable at interface ng OIDC path ay ACTIONS_ID_TOKEN_REQUEST_TOKEN at ACTIONS_ID_TOKEN_REQUEST_URL, na may audience na nakaset sa npm:registry.npmjs.org. Mula sa antas ng source code, maaaring patunayan na ang payload ay may kakayahang magdagdag ng workflow sa GitHub repository at gamitin ang OIDC / npm trusted publishing upang makakuha ng publishing permissions.

Bukod sa paraan ng pag-inject ng workflow sa pamamagitan ng git refs na nabanggit, ang payload ay naglalaman din ng isang mas nakatagong mekanismo para sa paghahatid ng mga lihim: ang isang GitHub Actions workflow na nakapagtatagpong sarili bilang Run Copilot ay sumulat ng ${{ toJSON(secrets) }} sa format-results.txt at i-upload ang artifact. Sa pagkakaiba sa direkting pagsulat ng mga lihim sa nilalaman ng repository, mas nagtatampok ang paraang ito ng paghahatid ng data sa pamamagitan ng output ng workflow, at ang karaniwang pagsusuri sa code diff ay maaaring hindi direktang makakita ng huling inilabas na nilalaman ng mga lihim.

5. Jalankan workflow ng Copilot sa pamamagitan ng artifact para i-transfer ang secrets:

Ang embedded resource zZ.bin ay isang GitHub Actions workflow na nakakapalito bilang Copilot, na sumusulat ng ${{ toJSON(secrets) }} sa format-results.txt at iina-upload bilang artifact.

Ang mga kagawaran ng GitHub API ay kasama ang: paglikha/pag-update ng temporary branch → pagsulat ng workflow blob → paghintay sa workflow run → pag-download ng artifact zip → pagbasa ng format-results.txt → pagtanggal ng workflow run at temporary branch. Ang mga kahalagahan sa paghahanap ay kasama ang Run Copilot, VARIABLE_STORE, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml.

6. npm self-propagation:

Ang pangunahang masamang load ay may dalawang hiwalay na path para sa pagpapalabas/pagpapalaganap sa npm.

Lugar ng npm token: Ang payload ay naglalayong listahin ang mga npm token ng kasalukuyang user sa pamamagitan ng GET /-/npm/v1/tokens, at filtarin ang mga token na may bypass_2fa === true at may pahintulot na package write, at gamitin ang mga token na ito para sa automated publishing. Ang bypass_2fa ay isang field ng token metadata, hindi isang parameter ng publish body.

GitHub Actions OIDC path: Basahin ang mga environment variable na ACTIONS_ID_TOKEN_REQUEST_TOKEN at ACTIONS_ID_TOKEN_REQUEST_URL, hingin ang OIDC token na may audience na npm:registry.npmjs.org, at palitan ang npm OIDC token sa pamamagitan ng npm OIDC token exchange interface para sa mga pahintulot sa pagpapalabas.

Ang proseso para ma-contaminate ang tarball ay: unpackage → isulat ang masasamang index.js → baguhin ang package.json:

Dito hihiwalay ang dalawang uri ng entry point: Ang tatlong lokal na nai-upload na sample ay gumagamit ng preinstall: "node index.js"—sa panahong ito, ang pag-install ng kapaligiran ay hindi nangangailangan ng Bun na i-install muna, at mas lihim ang paggamit ng Node.js bilang unang entry point; habang sa pagpapalaganap sa iba pang mga package, isinusulat ang preinstall: "bun run index.js" at idinadagdag ang bun bilang dependency—dahil ang susunod na lohika ng pangunahing masamang load ay nakadepende sa mga API na ibinibigay ng Bun runtime (tulad ng Bun.gunzipSync at Bun.file), kailangan siguraduhin sa mga skenaryo ng pagpapalaganap na ang target na kapaligiran ay may Bun.

7. Mechanismo ng pagpapanatili:

Ang pangunahang masamang load ay naglalaman ng apat na paraan ng pagpapanatili, na kumakapit sa direktoryo ng proyekto at system-level autostart.

Claude Code SessionStart hook: I-embed ang resource na S8.bin sa .claude/settings.json upang awtomatikong i-execute ang node .claude/setup.mjs bawat pag-start ng sesyon ng Claude Code. Ang masamang payload ay isinusulat din sa .claude/setup.mjs at .claude/index.js (ang path ay nabubuo sa pamamagitan ng ".claude/" + M0, kung saan ang M0 = "index.js").

VS Code folderOpen task: I-embed ang resource na EZ.bin sa folderOpen task sa .vscode/tasks.json, at awtomatikong i-execute ang parehong iskrip kapag binuksan ang infected project folder. Isusulat din ang .vscode/setup.mjs.

kitty-monitor (systemd / LaunchAgent): Ibinabahagi ang embedded resource na RZ.bin upang i-install ang persistent service, na nakalagay sa /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service (Linux), at ~/Library/LaunchAgents/com.user.kitty-monitor.plist (macOS). Lumikha ang malicious payload ng direktoryo na /tmp/kitty-, isinulat ang YZ.bin (GitHub commit monitor) sa cat.py, at i-install ito sa pamamagitan ng RZ.bin.

gh-token-monitor (systemd / LaunchAgent): Ibinagsak ang resource na jZ.bin upang i-install ang serbisyo ng pagmamonitor ng GitHub token, na nakalagay sa mga direktoryo na /.local/bin/gh-token-monitor.sh at /.config/gh-token-monitor/ at ang mga kaugnay na path ng systemd / LaunchAgent. Ang monitor na ito ay nagmamonitor kung ang GitHub token ay bumabalik ng 40x status code at kung ang metadata ng npm package na @cap-js/openapi@1.4.1 ay may anomali, at magpapatakbo ng handler kapag nangyari ang trigger:

Ibig sabihin nito na kapag nakikita ng monitor na ang GitHub API ay bumabalik ng 40x status code, tulad ng pagkakawala, pagkabigo, o anomalous na pahintulot ng token, magpapatakbo ang masasamang iskrip ng ipinapadala na handler. Ang handler na muling nabuo mula sa tatlong sample sa artikulong ito ay ang rm -rf ~/; rm -rf ~/Documents. Sa pag-aayos, huwag agad na mag-revoke ng token sa host na posibleng patuloy na nagpapatakbo ng payload—una, i-isolate ang host, linisin ang mga persistent item at mga proseso na nasa pagpapatakbo, at pagkatapos ay palitan ang mga credential mula sa malinis na kapaligiran.

8. Harden-Runner / StepSecurity Laban:

Ang pangunahang masamang load ay may nakabuilt-in na deteksyon at pagpapabagsak na lohika para sa StepSecurity Harden-Runner, na naglalakbay sa mga sumusunod na hakbang upang i-bypass ang CI/CD protection:

  1. Suriin kung available ang Docker socket /var/run/docker.sock;
  2. I-lista ang mga Docker container na may match sa pangalan o imahe na may keyword na harden-runner / stepsecurity;
  3. Ipinaputol ang tugmaan na container sa pamamagitan ng POST /containers//kill;
  4. Lumikha ng privileged alpine container, at i-replace ang sudoers na runner ALL=(ALL) NOPASSWD:ALL;
  5. Isulat ang hindi wastong paglutas ng mga domain na may kaugnayan sa StepSecurity sa /etc/hosts;
  6. Overwrite /etc/resolv.conf with 8.8.8.8 and 1.1.1.1.

Ang logic na ito ay nagpapakita na ang sample ay espesyal na inaayos para sa mga CI/CD environment na protektado ng StepSecurity.

9. EDR / Pagdudukot ng mga produkto sa seguridad, pagtataya ng kaligiran at pag-iwas:

Ang pangunahang masamang load ay nagtataya ng mga pangalan ng proseso at path ng pag-install ng iba’t ibang EDR (Endpoint Detection and Response) / security products:

Ang payload ay naglalaman din ng lohika para sa pag-iwas sa rehiyon: masusubaybayan ang mga environment variable na LC_ALL, LC_MESSAGES, LANGUAGE, LANG; kung ang mga ito ay maliit na letra at nagsisimula sa ru, iiiwasan ang pagpapatakbo. Suportado ang pagkilala sa CI environment para sa GitHub Actions, GitLab CI, Travis CI, CircleCI, Jenkins, AWS CodeBuild, Buildkite, AppVeyor, Bitbucket, Drone, TeamCity, Cirrus CI atbp. Ang mga marka ng estado na ginagamit sa runtime ay kasama ang tmp.0987654321.lock, __IS_DAEMON (marka para sa detached daemon sub-process), SKIP_DOMAIN (iwasan ang domain sender path), /tmp/kitty-*, cat.py at /var/tmp/.gh_update_state.

Pagsusuri ng epekto

Mula sa kakayahan sa source code, ang epekto ng tatlong sample na ito ay hindi limitado sa isang beses na pagpapatakbo sa panahon ng npm installation. Ang tunay na panganib nito ay maaaring ihiwalay sa apat na antas:

Sa antas ng developer host. Ang sample ay kukunin ang mga environment variable, .npmrc, .pypirc, SSH key, Docker configuration, .env, GitHub CLI token, data ng password manager, at wallet files, at magpapanatili ng kakayahang mag-trigger muli sa pamamagitan ng Claude Code, VS Code, systemd user service, o macOS LaunchAgent.

Sa antas ng CI/CD Runner. Ang sample ay makakakilala sa GitHub Actions Linux runner, babasahin ang memorya ng proseso na Runner.Worker at maaaring kunin ang mga masked secrets; kasama rin ang mga logika laban sa StepSecurity Harden-Runner na nagtatangkang sirain o iwasan ang mga komponente ng CI/CD protection.

Sa antas ng GitHub organization at repository. Ang sample ay maaaring gumamit ng GitHub API upang lumikha ng repository, isulat sa contents/results/, i-operate ang git refs/blobs/trees/commits, mag-inject ng masamang workflow, at gamitin ang Run Copilot workflow + artifact upang i-transfer ang mga secrets.

Sa antas ng pagkalat ng npm ecosystem. Ang sample ay maaaring piliin ang npm token na may package write permission at bypass_2fa === true, o maaaring gamitin ang GitHub Actions OIDC / npm trusted publishing path upang makakuha ng kakayahang mag-publish; pagkatapos ay i-download ang target tarball, isulat ang masamang loader, baguhin ang preinstall, idagdag ang Bun dependency, i-increase ang patch version, at ipublish, upang makabuo ng sariling-propagating chain sa npm.

Summary

Ang mga ebidensya ng source code ng tatlong sample ay nagpapakita na ang masamang pakete ay hindi isang simpleng script ng pagkuha ng impormasyon sa panahon ng pag-install, kundi isang kombinasyon ng maraming yugto ng loader at isang kompletong implant: ang panlabas na bahagi ay randomizad ayon sa pakete, samantalang ang Bun runtime launcher at ang pangunahing masamang load ay pareho; ang pangunahing implant ay nakapalibot sa pagkuha ng credentials, pagkuha ng CI secret, pagpropaganda sa GitHub/npm, persistence, at pagtutol sa pagprotekta.

Disenyo ng entry na may mataas na pagkakatago. Ang mga attacker ay hindi nagpapalit ng masamang lohika sa business code, kundi naglalagay ng confusion loader sa npm lifecycle scripts. Ang loader ay pangunahing responsable sa pag-decrypt at pagpapatakbo ng embedded payload, na nagiging sanhi na mahirap makita ang totoong kakayahan sa pamamagitan ng pagsusuri lamang sa source code ng business.

Multilayered deobfuscation chain. Ang malicious payload ay nakaluluto sa limang layer: digital array + ROT letter substitution, AES-128-GCM encryption, obfuscator.io obfuscation, B5 proprietary string encryption, at AES-256-GCM + gzip embedding layer. Ang bawat layer ay may sariling key o parameter na maaaring magbago sa iba’t ibang package, na nagpapahirap sa bulk detection batay sa static features.

Kumpletong kakayahan sa pag-atake sa antas ng organisasyon. Ang implant na ito ay may kakayahang basahin ang memorya ng GitHub Actions Runner, kumuha ng mga kredensyal mula sa maraming cloud at lokal, ipasa ang GitHub API at dead-drop, infektahan ang GitHub repository at workflow, mag-propaganda sa npm, at magkaroon ng persistence at pagtutol sa pagtutol. Batay sa istruktura ng source code, mayroon na itong mga code path na maaaring mag-trigger mula sa isang puntos ng pag-install patungo sa pagkalat sa repository, CI/CD, at chain ng npm publication; ang tunay na sakop ng kalat ay kailangang patunayan sa pamamagitan ng installation logs, audit ng repository, at telemetry mula sa platform.

Mula sa ebidensya ng source code, matutukoy na ang tatlong sample ay awtomatikong sinimulan sa pamamagitan ng preinstall at pinagana ang parehong pangunahing implant. Gayunpaman, hindi maaaring patunayan lamang sa tatlong sample ng tgz kung paano natamo ang orihinal na pagsisikap sa totoong pangyayari.

Mga rekomendasyon para sa pagtrato

  1. Suriin at alisin ang masasamang bersyon sa mga dependensya ng proyekto, lockfile, cache ng private registry, at cache ng pagbuo.
  2. Suriin kung may mga sumusunod sa installation log: preinstall, node index.js, bun run, /tmp/p*.js, tmp.0987654321.lock.
  3. Huwag agad mawalan ng bisa ng token sa isang biktima na host na posibleng pa rin ay nagpapatakbo ng payload. I-rekomenda na muna i-isolate ang biktima na host, linisin ang mga nagpapatakbo na proseso at mga persistent item, at pagkatapos ay palitan ang mga token na may kaugnayan sa GitHub, npm, cloud credentials, Kubernetes, Vault, SSH, Docker registry, at password manager mula sa isang malinis na kapaligiran.
  4. Suriin ang huling branch, commit, workflow, artifact, at bagong repository sa GitHub, na may pansin sa mga susi salita tulad ng Run Copilot, format-results, chore/add-codeql-static-analysis, .github/workflows/codeql.yml, at OIDC_PACKAGES.
  5. Suriin kung may mga bagong idinagdag o binago sa direktoryo ng proyekto: .claude/settings.json, .claude/setup.mjs, .vscode/tasks.json, .vscode/setup.mjs.
  6. Suriin ang user-level persistence: /.local/share/kitty/cat.py, /.config/systemd/user/kitty-monitor.service, ~/Library/LaunchAgents/com.user.kitty-monitor.plist, mga file kaugnay ng gh-token-monitor.
  7. Suriin ang npm publish history upang matiyak kung may mga hindi awtorisadong patch version publication; samantala, ayusin ang npm token metadata, na may pansin sa mga token na may kakayahang bypass ang 2FA (Two-Factor Authentication) at may package write permission.
  8. I-audit ang integridad ng mga downstream product na binuo sa kontaminadong kapaligiran.

IOC

Malicious file

filename: redhat-cloud-services-frontend-components-config-6.11.3.tgz MD5: 633ad8849a59e2bfb7a0fe589e816a07 SHA1: 675294612f455fe6a9acb195f0cbe3687d8e2e34 SHA256: 0c9c67ec40d5f23efa1ec3470d0ac88b4993ccc0e92be913fc29a337dfc4f060

filename: redhat-cloud-services-types-3.6.1.tgz MD5: 9e6c5af01438b52c9a411686c1f1b8ff SHA1: 88d098c8d96e9ae17550e9798c3b62c420464b8c SHA256: d543bb3cdf1569c2b3d38c8a4081ed746cfe78bf3236c2302704d79ab7fa9558

filename: redhat-cloud-services-rule-components-4.7.2.tgz MD5: f1ffdbf5e639899f26a6ebab2eec408d SHA1: f3c5c21274045ae02fef11e931de6dcf8462a067 SHA256: aaf00d06baa3c679b82452c50014e9824b8874e9ca2d150f19095f8de19ba90f

SHA256

ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6

0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35

Malicious dependency

npm:@redhat-cloud-services/topological-inventory-client@3.0.10

npm:@redhat-cloud-services/topological-inventory-client@3.0.11

npm:@redhat-cloud-services/topological-inventory-client@3.0.13

npm:@redhat-cloud-services/compliance-client@4.0.3

npm:@redhat-cloud-services/compliance-client@4.0.4

npm:@redhat-cloud-services/compliance-client@4.0.6

npm:@redhat-cloud-services/rbac-client@9.0.3

npm:@redhat-cloud-services/rbac-client@9.0.4

npm:@redhat-cloud-services/rbac-client@9.0.6

npm:@redhat-cloud-services/insights-client@4.0.4

npm:@redhat-cloud-services/insights-client@4.0.5

npm:@redhat-cloud-services/insights-client@4.0.7

npm:@redhat-cloud-services/frontend-components@7.7.2

npm:@redhat-cloud-services/frontend-components@7.7.3

npm:@redhat-cloud-services/frontend-components@7.7.5

npm:@redhat-cloud-services/frontend-components-utilities@7.4.1

npm:@redhat-cloud-services/frontend-components-utilities@7.4.2

npm:@redhat-cloud-services/frontend-components-utilities@7.4.4

npm:@redhat-cloud-services/remediations-client@4.0.4

npm:@redhat-cloud-services/remediations-client@4.0.5

npm:@redhat-cloud-services/remediations-client@4.0.7

npm:@redhat-cloud-services/frontend-components-notifications@6.9.2

npm:@redhat-cloud-services/frontend-components-notifications@6.9.3

npm:@redhat-cloud-services/frontend-components-notifications@6.9.5

npm:@redhat-cloud-services/patch-client@4.0.4

npm:@redhat-cloud-services/patch-client@4.0.5

npm:@redhat-cloud-services/patch-client@4.0.7

npm:@redhat-cloud-services/host-inventory-client@5.0.3

npm:@redhat-cloud-services/host-inventory-client@5.0.4

npm:@redhat-cloud-services/host-inventory-client@5.0.6

npm:@redhat-cloud-services/rule-components@4.7.2

npm:@redhat-cloud-services/rule-components@4.7.3

npm:@redhat-cloud-services/rule-components@4.7.5

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.2

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.4

npm:@redhat-cloud-services/frontend-components-advisor-components@3.8.6

npm:@redhat-cloud-services/notifications-client@6.1.4

npm:@redhat-cloud-services/notifications-client@6.1.5

npm:@redhat-cloud-services/notifications-client@6.1.7

npm:@redhat-cloud-services/sources-client@3.0.10

npm:@redhat-cloud-services/sources-client@3.0.11

npm:@redhat-cloud-services/sources-client@3.0.13

npm:@redhat-cloud-services/integrations-client@6.0.4

npm:@redhat-cloud-services/integrations-client@6.0.5

npm:@redhat-cloud-services/integrations-client@6.0.7

npm:@redhat-cloud-services/frontend-components-config@6.11.3

npm:@redhat-cloud-services/frontend-components-config@6.11.4

npm:@redhat-cloud-services/frontend-components-config@6.11.6

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.2

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.3

npm:@redhat-cloud-services/frontend-components-config-utilities@4.11.5

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.1

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.2

npm:@redhat-cloud-services/hcc-pf-mcp@0.6.4

npm:@redhat-cloud-services/frontend-components-remediations@4.9.2

npm:@redhat-cloud-services/frontend-components-remediations@4.9.3

npm:@redhat-cloud-services/frontend-components-remediations@4.9.5

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.1

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.2

npm:@redhat-cloud-services/eslint-config-redhat-cloud-services@3.2.4

npm:@redhat-cloud-services/javascript-clients-shared@2.0.8

npm:@redhat-cloud-services/javascript-clients-shared@2.0.9

npm:@redhat-cloud-services/javascript-clients-shared@2.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.11

npm:@redhat-cloud-services/quickstarts-client@4.0.12

npm:@redhat-cloud-services/quickstarts-client@4.0.14

npm:@redhat-cloud-services/config-manager-client@5.0.4

npm:@redhat-cloud-services/config-manager-client@5.0.5

npm:@redhat-cloud-services/config-manager-client@5.0.7

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.1

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.2

npm:@redhat-cloud-services/hcc-feo-mcp@0.3.4

npm:@redhat-cloud-services/entitlements-client@4.0.11

npm:@redhat-cloud-services/entitlements-client@4.0.12

npm:@redhat-cloud-services/entitlements-client@4.0.14

npm:@redhat-cloud-services/tsc-transform-imports@1.2.2

npm:@redhat-cloud-services/tsc-transform-imports@1.2.4

npm:@redhat-cloud-services/tsc-transform-imports@1.2.6

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.1

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.2

npm:@redhat-cloud-services/hcc-kessel-mcp@0.3.4

npm:@redhat-cloud-services/frontend-components-testing@1.2.1

npm:@redhat-cloud-services/frontend-components-testing@1.2.2

npm:@redhat-cloud-services/frontend-components-testing@1.2.4

npm:@redhat-cloud-services/types@3.6.1

npm:@redhat-cloud-services/types@3.6.2

npm:@redhat-cloud-services/types@3.6.4

npm:@redhat-cloud-services/chrome@2.3.1

npm:@redhat-cloud-services/chrome@2.3.2

npm:@redhat-cloud-services/chrome@2.3.4

npm:@redhat-cloud-services/frontend-components-translations@4.4.1

npm:@redhat-cloud-services/frontend-components-translations@4.4.2

npm:@redhat-cloud-services/frontend-components-translations@4.4.4

npm:@redhat-cloud-services/vulnerabilities-client@2.1.8

npm:@redhat-cloud-services/vulnerabilities-client@2.1.9

npm:@redhat-cloud-services/vulnerabilities-client@2.1.11

Disclaimer: Ang information sa page na ito ay maaaring nakuha mula sa mga third party at hindi necessary na nagre-reflect sa mga pananaw o opinyon ng KuCoin. Ibinigay ang content na ito para sa mga pangkalahatang informational purpose lang, nang walang anumang representation o warranty ng anumang uri, at hindi rin ito dapat ipakahulugan bilang financial o investment advice. Hindi mananagot ang KuCoin para sa anumang error o omission, o para sa anumang outcome na magreresulta mula sa paggamit ng information na ito. Maaaring maging risky ang mga investment sa mga digital asset. Pakisuri nang maigi ang mga risk ng isang produkto at ang risk tolerance mo batay sa iyong sariling kalagayang pinansyal. Para sa higit pang information, mag-refer sa aming Terms ng Paggamit at Disclosure ng Risk.