Supply Chain Campaign Targets SAP npm Packages with Credential-Stealing Malware

Detect and mitigate malicious npm packages linked to the recent Shai-Hulud-style campaign - Mini Shai Hulud.

Update 1520 UTC, 30 April 2026: Two additional packages were trojanized today:

NPM Package: intercom-client@7.0.5

PyPI package lightning@2.6.2 and 2.6.3

Both packages appear to contain the same malicious functionality previously seen in the SAP operation. Analysis is ongoing.

Update 2140 UTC, 20 April 2026: Lightning and intercom-client payload analysis

Analysis of the malicious payloads shows an evolution in both exfiltration and credential harvesting techniques. In addition to earlier GitHub-based exfiltration, the malware now leverages dedicated infrastructure, primarily the domain zero.masscan.cloud, while also implementing a dynamic fallback mechanism.

The fallback retrieves configuration data from GitHub by searching for commits containing a specific keyword (“beautifulcastle”), which embeds a base64-encoded payload pointing to an exfiltration endpoint (currently resolving to 94.154.172[.]43/v1/telemetry. This approach allows attackers to update exfiltration infrastructure without publishing new malicious package versions.

The payload found in the intercom-client package further expands capabilities by actively scanning for secrets in Kubernetes environments and HashiCorp Vault. It queries Kubernetes service endpoints and Vault configurations, using extensive regex-based matching to extract credentials such as AWS keys, GitHub and npm tokens, database connection strings, private keys, and API secrets (e.g., Stripe, Slack, Twilio). This indicates a strong focus on cloud-native environments and CI/CD pipelines, significantly increasing the potential impact of the compromise through automated large-scale credential harvesting.

Update 1745 UTC, 29 April 2026: TeamPCP attribution confirmed and new functionality documented.

A new supply chain operation from TeamPCP calling itself “Mini Shai Hulud” compromised SAP-related npm packages by injecting malicious preinstall scripts that execute during dependency installation. The campaign leverages a multi-stage payload to harvest developer and CI/CD secrets across GitHub, npm, and major cloud providers, and exfiltrates the data via attacker-controlled GitHub repositories. It also contains code designed to propagate via compromised tokens. TeamPCP is very likely responsible for this campaign, based on a shared RSA public key and overlaps in encoding routines and region guardrails.

What happened?

Malicious versions of legitimate SAP ecosystem packages (e.g., `@cap-js/sqlite`, `@cap-js/postgres`) were created by modifying them to include a `preinstall` script that executes `setup.mjs` automatically during `npm install`. This script downloads the Bun runtime and executes an obfuscated payload (`execution.js`), enabling attacker-controlled code execution prior to package installation completion. 

When executed, the second-stage payload is a credential stealer and propagation framework designed to target both developer environments and CI/CD pipelines. It collects sensitive data including GitHub tokens, npm credentials, cloud secrets (AWS, Azure, GCP), Kubernetes tokens, and GitHub Actions secrets—leveraging advanced techniques such as extracting secrets from runner memory. Exfiltration occurs via public GitHub repositories, where it posts encrypted payloads. Additionally, the malware includes propagation logic to infect additional repositories and package distributions.

During its initial setup, the malware performs a system check to determine if the compromised machine is configured for the Russian language. It does this by inspecting both the system's date/time locale settings and its environment language variables. If any of these values begin with 'ru', the payload abruptly terminates itself, ensuring no data is exfiltrated from Russian-speaking systems.

Compromised users by hours, UTC timezone

While we estimate this campaign is currently active, the volume of compromised users and attacker-created exfiltration repositories appears significantly lower than that of Shai-Hulud or Shai-Hulud 2.0.

Compromised repositories by hours, UTC timezone

Notable Updates

This operation broadly follows the same methods used in previous TeamPCP operations, but contains a number of notable evolutions.

Github Exfiltration

In the Bitwarden operation, the malware would attempt to exfiltrate the encrypted blob of secrets to GitHub only if the primary exfiltration mechanism to a C&C domain failed. In this operation, exfiltration to GitHub is the primary and only way to exfiltrate secrets. The mechanisms are substantially similar, using the same naming scheme (word1-word2-number) and the same repo description “"Checkmarx Configuration Storage" The biggest change is that the SAP operation uses the GraphQL API, rather than the REST API, which was used in the Bitwarden operation.

Fallback to GitHub Poisoning

If the credential collection is not able to identify a gh[op]_ (PAT/OAuth) token and GITHUB_REPOSITORY is set it will attempt to poison that GitHub repository. It does this only if ghs_ or ghs_old tokens are present (and no GitHub PAT tokens are). The below files are placed in the repo, in an attempt to infect users who open the repo in Claude Code or VSCode:

PathContentPurposeHashes
.claude/execution.jsSelf-copy of the running payload via Bun.mainPayload for Claude Code usersIdentical to the initial execution.js
.claude/setup.mjsThe dropper Dropper that downloads Bun and executes the payloadIdentical to the initial setup.mjs
.claude/settings.jsonClaude Code hooks configuration Claude Code SessionStart hook — runs node .vscode/setup.mjs on every session

SHA256: 14eb4ce01dd4307759887ff819359b70d7d9ff709ecde039a5abc1aac325b128  SHA1: ff7ed7a0fa1c43eed01809d076feedbaed464fc7   MD5: 00ca0c04d247ef09f2b2acc452029345

.vscode/tasks.jsonVS Code task configurationVS Code task "Environment Setup" — runs node .claude/setup.mjs on folder open (runOn: folderOpen)

SHA256: 927387d0cfac1118df4b383decc2ea6ba49c9d2f98b47098bcbcba1efc026e1f  SHA1: 7b0278216ac31ec18eca9eb8bc1c1261a1b26f6c  MD5: dbb9b09957113463bbeb420c2c4108b5

.vscode/setup.mjsSame dropper as .claude/setup.mjs Dropper for VS Code execution pathIdentical to the initial setup.mjs

Browser Credential Theft

The SAP operation adds the ability to steal credentials from multiple browsers (Chrome, Safari, Edge, Brave, Chromium) and exfiltrate any passwords found there. This feature was not present in any of the previous operations.

Exfiltration Fallback Mechanism

Consistent with previous Shai-Hulud attacks, this new variant utilizes a fallback mechanism to exfiltrate secrets from environments lacking local GitHub (GH) tokens or credentials. If local credential harvesting fails, the malware actively searches GitHub for commits beginning with a specific signature phrase: "OhNoWhatsGoingOnWithGitHub".

This phrase is the default commit message the malware uses when exfiltrating data. Appended to this phrase is a double-base64 encoded GitHub token:

"message": "OhNoWhatsGoingOnWithGitHub:WjJodlh[Redacted]" 

Once located, the malware extracts and validates this token to facilitate further data exfiltration. Consequently, even if your organization has not created any new repositories, your secrets may still be compromised and routed to an entirely unrelated, attacker-controlled repository.

Attribution

Wiz assesses with high confidence that this is the work of the same TeamPCP operators that have previously compromised multiple libraries. This assessment is due to a shared RSA public key used to encrypt the exfiltrated secrets. This means that the same private key would decrypt the payloads, limiting the accessibility of the exfiltrated data to TeamPCP. 

Additional commonalities:

  • The malware has an early check for the system language and if it is found to be “ru” the malware exits and does not exfiltrate any secrets. This was previously present in the Checkmarx and Bitwarden compromises.

  • The package uses the same npm install hook to start execution that was used in the Bitwarden CLI compromise.

  • GitHub based exfiltration to Dune themed repos was the fallback C2 method for the Bitwarden CLI operation, but is now the primary option.

While this operation contains references to the Shai-Hulud operations from the fall of 2025, we cannot definitively link them or say they are a separate actor.

Affected Packages 

npm packages:

  • @cap-js/sqlite – v2.2.2

  • @cap-js/postgres – v2.2.2

  • @cap-js/db-service – v2.10.1

  • mbt – v1.2.48

Indicators of compromise

@cap-js/postgres 2.2.2

FileHash
Tarball (3,409,213 bytes)SHA256: 1d9e4ece8e13c8eaf94cb858470d1bd8f81bb58f62583552303774fa1579edee
Tarball (3,409,213 bytes)SHA1: e80824a19f48d778a746571bb15279b5679fd61c
Tarball (3,409,213 bytes)MD5: e32eaf0c3cde9616831a1e92d42b0058
execution.js (11,723,748 bytes)SHA256: eb6eb4154b03ec73218727dc643d26f4e14dfda2438112926bb5daf37ae8bcdb
execution.js (11,723,748 bytes)SHA1: ca4a5bb85778ffcd2153ace88fe2d882c8ceeb23
execution.js (11,723,748 bytes)MD5: b523a69b27064d1715d1f0aaffcfae63

@cap-js/db-service 2.10.1

FileHash
Tarball (3,490,641 bytes)SHA256: 258257560fe2f1c2cc3924eae40718c829085b52ae3436b4e46d2565f6996271
Tarball (3,490,641 bytes)SHA1: 4b04304f6d51392e3f43856c94ca95800518a694
Tarball (3,490,641 bytes)MD5: d468f16eafccbc54a994f3d675ace8ae
execution.jsIdentical to @cap-js/postgres 2.2.2

@cap-js/sqlite 2.2.2

FileHash
Tarball (3,395,651 bytes)SHA256: a1da198bb4e883d077a0e13351bf2c3acdea10497152292e873d79d4f7420211
Tarball (3,395,651 bytes)SHA1: 7b6a28e92149637e5d7c7f4a2d3e54acd507c929
Tarball (3,395,651 bytes)MD5: 8cd683f78735c9bfc32600c73d3d9abe
execution.js (11,729,871 bytes)SHA256: 6f933d00b7d05678eb43c90963a80b8947c4ae6830182f89df31da9f568fea95
execution.js (11,729,871 bytes)SHA1: bc95cc5dda788295aa0c9456791520599ef99526
execution.js (11,729,871 bytes)MD5: 6fb87d243b011b5445f379f80e1a6b4d

mbt 1.2.48

FileHash
Tarball (3,373,788 bytes)SHA256: 86282ebcd3bebf50f087f2c6b00c62caa667cdcb53558033d85acd39e3d88b41
Tarball (3,373,788 bytes)SHA1: 0af7415d65753f6aede8c9c0f39be478666b9c12
Tarball (3,373,788 bytes)MD5: 04d8a99447b16f6839fff3b978f88d7e
execution.js (11,678,349 bytes)SHA256: 80a3d2877813968ef847ae73b5eeeb70b9435254e74d7f07d8cf4057f0a710ac
execution.js (11,678,349 bytes)SHA1: 6bc859aaee1f8885eec2a3016226e877e5adba08
execution.js (11,678,349 bytes)MD5: 45dc9c02f82b4370ca92785282d43a86

Shared Dropper (all 4 packages)

FileHash
setup.mjs (4,549 bytes)SHA256: 4066781fa830224c8bbcc3aa005a396657f9c8f9016f9a64ad44a9d7f5f45e34
setup.mjs (4,549 bytes)SHA1: 307d0fa7407d40e67d14e9d5a4c61ac5b4f20431
setup.mjs (4,549 bytes)MD5: 35baf8316645372eea40b91d48acb067

What steps should security teams take?

  • Immediately identify exposure: Search environments, lockfiles, artifact stores, and CI logs for affected package versions and malicious files (setup.mjs, execution.js).

  • Rotate all credentials: If exposure is suspected, rotate GitHub tokens, npm tokens, cloud credentials, Kubernetes tokens, and CI/CD secrets, this malware targets all of them.

  • Audit GitHub activity: Look for suspicious commits, newly created repositories, or indicators such as the propagation keyword and unusual commit authors.

References

Continua a leggere

Richiedi una demo personalizzata

Pronti a vedere Wiz in azione?

"La migliore esperienza utente che abbia mai visto offre piena visibilità ai carichi di lavoro cloud."
David EstlickCISO (CISO)
"Wiz fornisce un unico pannello di controllo per vedere cosa sta succedendo nei nostri ambienti cloud."
Adam FletcherResponsabile della sicurezza
"Sappiamo che se Wiz identifica qualcosa come critico, in realtà lo è."
Greg PoniatowskiResponsabile della gestione delle minacce e delle vulnerabilità