Executive Summary

Upwind is tracking an active software supply chain campaign impacting multiple npm packages commonly used across developer tooling, frontend frameworks, CI/CD pipelines, and cloud-native application environments. We identified malicious payloads designed specifically to target CI/CD systems, cloud identities, GitHub credentials, npm publishing workflows, developer machines, and AI developer tooling. The campaign includes install-time execution, credential harvesting, GitHub Actions abuse, npm propagation, persistence mechanisms, destructive anti-response behavior, remote access capabilities, and multiple evasion techniques aimed at modern CI/CD security controls. As of May 19, 2026, 04:00 UTC, we identified approximately 1,948 public GitHub repositories associated with attacker exfiltration activity using the repeated signature:

niagA oG eW ereH :duluH-iahS

which reverses to:

Shai-Hulud: Here We Go Again

The campaign appears active, and additional affected packages or payload variants may continue to emerge.

Confirmed Malicious Packages

PackageVersion
jest-canvas-mock2.5.3, 2.6.3, 2.7.3
echarts-for-react3.0.7, 3.1.7, 3.2.7
size-sensor1.0.4, 1.1.4, 1.2.4
jest-date-mock1.0.11, 1.1.11, 1.2.11
@antv/g-math3.2.0, 3.3.0
@antv/util3.4.11, 3.5.11
timeago.js4.1.2, 4.2.2
@antv/scale0.6.2, 0.7.2
@antv/matrix-util3.1.4, 3.2.4
@antv/path-util3.1.1, 3.2.1
@antv/g-canvas2.3.0, 2.4.0

Additional suspicious npm releases remain under investigation.

Technical Breakdown

The campaign uses multiple execution paths, but the payload behavior is consistent across the variants we analyzed. At a high level, the malware executes during package installation, determines whether it is running in a valuable developer or CI/CD environment, harvests credentials, validates GitHub and cloud access, exfiltrates data, establishes persistence, and attempts to propagate through stolen publishing credentials and compromised repositories. We identified multiple payload variants with different hashes, obfuscation layers, bootstrap paths, and delivery mechanisms. The differences appear intentional and likely designed to reduce the effectiveness of static detections and signature-based analysis.

Delivery Methods

We identified two primary delivery patterns.

Direct Install Hook

Some packages execute the malicious payload directly during installation:

"scripts": {
  "preinstall": "bun run index.js"
}

Copied

This causes arbitrary code execution during:

npm install

Copied

before the developer imports or uses the package.

Other packages use a stealthier delivery method through optionalDependencies:

"optionalDependencies": {
  "@antv/setup": "github:antvis/G2#dc3d62a2181beb9f326952a2d212900c94f2e13d"
}

Copied

The injected dependency then executes:

"prepare": "bun run index.js && exit 1"

Copied

The && exit 1 behavior makes the dependency appear to fail while allowing npm installation to continue normally. By the time npm prints the warning, the payload has already executed successfully. We identified malicious orphan commits pushed to the legitimate antvis/G2 GitHub repository shortly before package publication. These commits were used as payload delivery points for both @antv/setup and @sap/setup.

Payload Architecture

Across variants, the malware follows a consistent high-level execution flow:

npm install affected package
        ↓
preinstall / prepare hook executes
        ↓
bun run index.js
        ↓
environment and sandbox checks
        ↓
detached daemon process starts
        ↓
credential harvesting from env vars, files, GitHub CLI, and CI memory
        ↓
GitHub token validation and prioritization
        ↓
cloud, Kubernetes, Vault, npm, and SSH credential collection
        ↓
encrypted exfiltration to attacker infrastructure
        ↓
fallback exfiltration through GitHub repositories
        ↓
persistence through Claude / VS Code / system services
        ↓
possible npm propagation through stolen publish tokens

Copied

We observed several distinct payload binaries and obfuscation variants with similar functionality. The differences in payload size and hashes appear intentional and likely designed to reduce static signature effectiveness and complicate detection engineering.

Credential Harvesting

The malware collects credentials from several sources in parallel.

Environment Variables

The payload dumps the full environment and specifically targets high-value variables, including:

  • GITHUB_TOKEN
  • ACTIONS_ID_TOKEN_REQUEST_URL
  • ACTIONS_ID_TOKEN_REQUEST_TOKEN
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_SESSION_TOKEN
  • VAULT_TOKEN
  • KUBECONFIG

GitHub Actions OIDC material is especially sensitive because it may allow attackers to impersonate GitHub Actions workloads to cloud providers that trust GitHub federation.

Filesystem Secrets

The malware scans developer and CI systems for SSH keys, .npmrc tokens, AWS, GCP, and Azure credentials, Kubernetes configs, Docker credentials, Terraform credentials, Vault configs, Git credentials, .env files, shell history, cryptocurrency wallets, messaging application artifacts, and AI tooling credentials. Notably, the malware targets Claude-related configuration files:

~/.claude.json
~/.claude/mcp.json

Copied

This suggests the attackers understand that AI developer tools increasingly store sensitive API keys, MCP server configurations, and third-party service credentials.

GitHub CLI Tokens

The malware invokes the GitHub CLI to retrieve authenticated GitHub session tokens, then validates them through the GitHub API.

Password Manager and Secret Store Collection

We identified collection logic targeting multiple password managers and secret stores. The malware attempts to extract data from 1Password, Bitwarden, Pass, and Gopass, including full vault contents where the required access material is available. It also targets HashiCorp Vault through multiple authentication paths, including environment tokens, token files, Kubernetes service account JWTs, and AWS IAM-based auth. Once authenticated, the malware attempts to enumerate KV mounts and dump KV v1 and KV v2 secrets.

Cloud and Kubernetes Secret Dumping

The malware does not stop at local credential files. We identified AWS collection logic that attempts to validate credentials with STS, enumerate Secrets Manager secrets, and retrieve SSM Parameter Store values with decryption across multiple AWS regions. Kubernetes collection logic targets both in-cluster service account tokens and workstation kubeconfigs, lists namespaces, and attempts to dump secrets from user namespaces. This makes the campaign especially dangerous in CI/CD and cloud-native environments where a single runner or developer workstation may hold access to multiple production systems.

GitHub Token Validation and Abuse

We identified logic that actively validates discovered GitHub tokens through:

https://api.github.com/user
https://api.github.com/user/orgs

Copied

The malware checks whether tokens are valid, what scopes they have, whether they belong to personal or organization accounts, and whether they include repo or workflow permissions. Tokens with repository and workflow access are prioritized because they can be used for repository modification, workflow manipulation, exfiltration through GitHub commits, backdooring repositories, and malware propagation.

GitHub Actions Memory Dumping

One of the more advanced capabilities identified is GitHub Actions memory dumping. When running inside Linux GitHub Actions environments, the malware attempts to locate the Runner.Worker process, read /proc/<pid>/maps, dump readable memory regions from /proc/<pid>/mem, and extract GitHub Actions secrets and runner tokens from memory. We also identified cross-platform memory dumping logic for Linux, macOS, and Windows using platform-specific APIs. This behavior is important because it attempts to recover secrets that may already be loaded into memory, bypassing normal secret masking protections.

Exfiltration Architecture

The primary exfiltration channel uses HTTPS POST requests to attacker-controlled infrastructure disguised as an OpenTelemetry endpoint:

https://t.m-kosche.com/api/public/otel/v1/traces

Copied

The path resembles legitimate telemetry ingestion traffic, which may help it blend into environments where observability traffic is expected. The malware also spoofs the User-Agent:

python-requests/2.31.0

Copied

even though the payload executes through JavaScript/Bun. When direct C2 exfiltration is skipped or unavailable, the malware falls back to GitHub-based exfiltration by committing stolen data into attacker-created repositories as JSON files.

Persistence Through Developer Tooling

We identified persistence mechanisms targeting developer workflows. The malware copies itself into Claude or Codex-related directories and modifies developer tool configuration files so it re-executes when a Claude Code session starts, a repository is opened, or VS Code tasks are triggered. Observed persistence artifacts include:

~/.claude/package/index.js
.claude/settings.json
.vscode/tasks.json

Copied

This means removing the original npm package may not be enough. The malware can survive through modified developer tooling configuration.

Repository Backdooring

When valid GitHub tokens are available, the malware can inject files directly into victim repositories. Observed injected files include:

.claude/index.js
.claude/setup.mjs
.claude/settings.json
.vscode/tasks.json

Copied

Anyone who later clones or opens the infected repository with supported tooling may re-trigger the payload.

GitHub Actions Secret-Dumping Workflow

We identified injected GitHub Actions workflow logic designed to dump repository secrets into an artifact. The workflow is deployed under a path such as:

.github/workflows/codeql.yml

Copied

and uses a workflow name designed to blend in:

Run Copilot

Copied

The workflow writes toJSON(secrets) into an artifact named:

format-results

Copied

The workflow also uses pinned action references that appear to be attacker-controlled forks rather than official GitHub Actions. The newer analysis also shows a two-stage inject-and-cleanup process: the malware can commit the workflow, wait for it to run, download the artifact, delete the workflow run, and force-reset the branch back to its original state. This is designed to collect secrets while removing evidence from repository history.

Remote Access Trojan Behavior

We identified an additional persistence capability using a kitty-monitor service. This component installs a Python script at:

~/.local/share/kitty/cat.py

Copied

and registers it as a persistent background service. The service searches GitHub commits for the keyword:

firedalazer

Copied

When a signed command is found, it verifies the payload with an attacker-controlled RSA key, downloads code from the referenced URL, and executes it. This gives the attacker a long-term command channel that can survive npm package removal and does not require a traditional C2 domain to remain active. We also identified a second GitHub dead-drop resolver keyword:

thebeautifulmarchoftime

Copied

used to discover alternate C2 infrastructure through signed GitHub commit messages.

Docker Privilege Escalation and Security Tool Neutralization

We identified Docker-aware behavior intended to weaken CI/CD defenses. In Docker-enabled GitHub Actions environments, the malware can query the Docker socket, identify containers associated with security tooling such as StepSecurity Harden-Runner, and attempt to terminate them. Additional logic uses a privileged container with a host bind mount to write a sudoers file granting passwordless sudo to the runner user. The malware can then poison /etc/hosts to block StepSecurity domains such as agent.stepsecurity.io, api.stepsecurity.io, and app.stepsecurity.io, preventing monitoring infrastructure from receiving telemetry.

npm Propagation Behavior

The malware includes npm worm-like propagation logic. We identified two propagation paths. In the PAT-based path, when a .npmrc or npm token with publishing permissions is found, the malware can inject itself into packages, add a postinstall hook, add a malicious optional dependency, and republish poisoned packages. In the OIDC-based path, when GitHub Actions OIDC material is available, the malware can exchange the OIDC token for npm publishing access, inject @sap/setup, bump the minor version, and publish a new compromised release. One observed propagation dependency was:

@sap/setup

Copied

pointing to:

github:antvis/G2#1916faa365f2788b6e193514872d51a242876569

Copied

This can turn one compromised developer or CI environment into a new distribution point for downstream compromise.

Destructive and Extortion Behavior

Some variants include destructive anti-response behavior. We identified a token-monitoring service that checks whether stolen GitHub tokens remain valid. If a token is revoked or certain package-state canaries change, the malware may execute destructive commands against the victim’s home directory. The payload includes the hardcoded message:

IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner

Copied

This means defenders should be careful during response. If persistence artifacts are present, persistence components should be removed before revoking affected GitHub tokens.

Security Tool Evasion

The attackers appear to be actively designing around common CI/CD security tools and incident response workflows.

Observed evasion and anti-analysis techniques include:

  • StepSecurity Harden-Runner detection
  • References to:
    • agent.stepsecurity.io
    • api.stepsecurity.io
    • app.stepsecurity.io
  • Docker-based security tool neutralization
  • Decoy GitHub token detection
  • Daemonized detached execution
  • Singleton lock files
  • Signal handler suppression
  • Multiple obfuscation variants
  • Payload hash variation across samples
  • Encrypted C2 configuration details
  • OpenTelemetry-style network camouflage
  • GitHub-based fallback exfiltration infrastructure
  • Russian locale bypass logic

The Russian locale bypass is especially notable because the malware skips execution when certain Russian locale indicators are present. This pattern is commonly observed in malware families attempting to avoid activity in specific jurisdictions and may provide attribution-relevant signals.

Designed to Spread, Persist, and Fight Back

What makes this campaign stand out is how defender-aware it is.

The malware does not simply execute and steal credentials. It checks where it is running, looks for security tooling, validates whether stolen tokens are valuable, varies payload hashes, encrypts sensitive strings, hides traffic behind telemetry-like endpoints, persists through developer tools, uses GitHub itself as both an exfiltration and command channel, and attempts to erase evidence after abusing GitHub Actions workflows. 

We identified capabilities targeting nearly every layer of the modern developer pipeline, including CI/CD systems, GitHub Actions runners, npm publishing workflows, cloud credentials, Kubernetes secrets, local developer environments, AI developer tooling such as Claude Code, password managers, Vault, AWS Secrets Manager, SSM Parameter Store, and containerized CI/CD infrastructure. This was not typical smash-and-grab npm malware. It behaved more like a modern intrusion framework delivered through trusted package installation workflows – designed not only to steal secrets, but to persist, propagate, evade defenders, and turn compromised developer environments into new distribution points.

GitHub Became the Exfiltration Infrastructure

We identified approximately 1,948 public GitHub repositories associated with attacker exfiltration activity as of May 19, 2026, 04:00 UTC. These repositories appear to have been created automatically using stolen GitHub credentials and share the same description string:

niagA oG eW ereH :duluH-iahS

Copied

We identified several compromised GitHub accounts associated with this activity, including early victim activity dating back to May 16. Observed victim activity included earliest known victim activity on May 16, SAP-linked activity on May 18, rapid repository creation bursts on May 19, and automated creation of dozens of repositories within minutes from individual accounts. This indicates the campaign was already active before the most visible npm package publications and had begun using stolen GitHub accounts as exfiltration infrastructure.

Linked SAP Package Activity

We identified a linked attack involving:

@cap-js/[email protected]

Copied

The package appears to have been published using a compromised cap-npm npm account associated with SAP’s Cloud Application Programming Model ecosystem.

Key Findings

  • @cap-js/[email protected] was published on May 18, 2026.
  • The package appears to have been published directly using a stolen npm personal access token (PAT).
  • The release did not follow the normal GitHub Actions OIDC publishing flow used by legitimate releases.
  • The malicious version was later yanked.
  • A clean @cap-js/[email protected] was published at 12:36:23 UTC through GitHub Actions OIDC.
  • SAP’s open source security team account was added as maintainer during recovery.
  • No corresponding GitHub Actions run was identified for 1.4.1, while legitimate releases from 1.3.0 onward consistently used OIDC.

The use of a PAT instead of OIDC is a strong indicator that the cap-npm publishing account was compromised and abused directly.

The malware also hardcoded @cap-js/[email protected] as a dead-man-switch canary. If the package was removed or deprecated, the malware could trigger destructive behavior on infected systems.

This strongly suggests the attackers were monitoring defender response and using package state as a signal for whether victims had detected the compromise.The later a2ed1d59 commit appears to be a post-remediation workflow improvement, not a failed recovery attempt.

Campaign Timeline

TimeEvent
2026-05-16 06:10 UTCEarliest confirmed GitHub exfil victim activity observed
2026-05-18 11:49 UTC@cap-js/[email protected] published via compromised cap-npm PAT, bypassing OIDC
2026-05-18 12:25 UTCSAP-linked GitHub exfil repositories begin appearing
2026-05-18 12:36 UTCClean @cap-js/[email protected] published via GitHub Actions OIDC
2026-05-18 12:47 UTCSAP adds workflow_dispatch trigger in post-remediation commit a2ed1d59
2026-05-19 01:25 UTCMalicious orphan commit 1916faa3… pushed to antvis/G2
2026-05-19 01:47 UTCMalicious orphan commit dc3d62a2… pushed to antvis/G2
2026-05-19 01:49 UTC[email protected] published
2026-05-19 01:56 UTC[email protected] published
2026-05-19 03:41 UTCRapid exfil repository creation observed from victim account
2026-05-19 04:00 UTCApproximately 1,948 GitHub exfil repositories identified

Indicators of Compromise (IOCs)

Indicators of Compromise (IOCs)

TypeValueNotes
C2 Domaint.m-kosche.comBlock at egress
C2 URLhttps://t.m-kosche.com/api/public/otel/v1/tracesSpoofed OpenTelemetry endpoint
C2 Port443HTTPS
User-Agentpython-requests/2.31.0Spoofed from JS/Bun process
GitHub APIhttps://api.github.comUsed for token validation and fallback exfil
Exfil Repo SignatureniagA oG eW ereH :duluH-iahSReversed Shai-Hulud message
Total Exfil Repos1,948+As of 2026-05-19 04:00 UTC
Threat Actor GitHubAlexzjt / huiyu.zjtAssociated with malicious commits
Commit MessageNew PackageUsed on malicious commits
GitHub Commitdc3d62a2181beb9f326952a2d212900c94f2e13d@antv/setup entry point
GitHub Commit1916faa365f2788b6e193514872d51a242876569@sap/setup propagation payload
PID Lock File$TMPDIR/tmp.0987654321.lockActive infection marker
Env Marker__DAEMONIZED=1Detached process marker
Payload RuntimebunInstalled as dependency
Payload Fileindex.js~486 KB obfuscated payload
Persistence Script~/.local/bin/gh-token-monitor.shToken monitor / wipe trigger
Persistence Dir~/.config/gh-token-monitor/Stores stolen token and handler
macOS Persistence~/Library/LaunchAgents/com.user.gh-token-monitor.plistToken monitor service
Linux Persistence~/.config/systemd/user/gh-token-monitor.serviceToken monitor service
Claude Hook Payload~/.claude/package/index.jsMalware copy
RAT Script~/.local/share/kitty/cat.pykitty-monitor RAT
RAT State File/var/tmp/.gh_update_stateTracks executed commands
RAT macOS Persistence~/Library/LaunchAgents/com.user.kitty-monitor.plistRAT persistence
RAT Linux Persistence~/.config/systemd/user/kitty-monitor.serviceRAT persistence
RAT C2 KeywordfiredalazerGitHub commit search keyword
Alt C2 KeywordthebeautifulmarchoftimeGitHub commit search keyword
Injected Workflow Path.github/workflows/codeql.ymlFake CodeQL workflow path
Injected Workflow NameRun CopilotSuspicious workflow name
Injected Workflow Branchchore/add-codeql-static-analysisTemporary branch used for workflow injection
Injected Workflow Commitfix: ciBlending commit message
Actions Artifactformat-resultsSecret dump artifact
Pinned Checkoutactions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83ddAttacker fork
Pinned Upload Artifactactions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024fAttacker fork
Alternate Scriptrouter_runtime.jsAlternate bootstrap path
Alternate Scriptai_init.jsAlternate bootstrap path
Encryption Key49d3f75bfb90c9708c7db7f16d60e6e76e4fcddd14c98c5bde68f8fb4ab903edPayload string encryption
Encryption Salt8d91f1541f7c152a84e6b640b0f278a9Payload string encryption

Recommendations

Organizations should immediately:

  • Avoid installing or upgrading affected package versions.
  • Review package installation logs for suspicious preinstall, postinstall, or prepare execution.
  • Investigate unexpected bun execution during npm package installation.
  • Block outbound traffic to t.m-kosche.com.
  • Search GitHub for repositories containing the signature niagA oG eW ereH :duluH-iahS.
  • Inspect repositories for injected .claude, .vscode, and suspicious GitHub Actions workflow files.
  • Audit GitHub Actions workflows for unauthorized secret-dumping behavior or unexpected workflow changes.
  • Review npm publishing history for unexpected releases or modified package metadata.
  • Rotate exposed cloud credentials, GitHub tokens, npm publishing tokens, SSH keys, Vault tokens, and AI tooling credentials.
  • Audit Kubernetes, Helm, Terraform, Docker, Vault, password manager, AWS Secrets Manager, and SSM exposure.
  • Inspect developer workstations and CI/CD runners for persistence artifacts, detached bun processes, and unauthorized background services.
  • Review Docker-enabled CI/CD environments for suspicious privileged container activity or tampering with security tooling.

Important: if gh-token-monitor persistence is present, remove the persistence components before revoking GitHub tokens to avoid triggering destructive behavior on infected systems.

Host Cleanup

Check and remove the following artifacts where present:

~/.local/bin/gh-token-monitor.sh
~/.config/gh-token-monitor/
~/Library/LaunchAgents/com.user.gh-token-monitor.plist
~/.config/systemd/user/gh-token-monitor.service
~/.claude/package/index.js
.claude/settings.json
.vscode/tasks.json
$TMPDIR/tmp.0987654321.lock
~/.local/share/kitty/cat.py
/var/tmp/.gh_update_state
~/Library/LaunchAgents/com.user.kitty-monitor.plist
~/.config/systemd/user/kitty-monitor.service

Copied

How Upwind Can Help

Upwind helps organizations detect and investigate supply chain attacks at runtime, where malicious package behavior actually executes. In this campaign, the malware abused package installation workflows, spawned detached processes, harvested credentials from developer and CI/CD environments, accessed GitHub and cloud identities, communicated with attacker infrastructure, attempted to neutralize security tooling, and persisted through developer workflows. Much of this behavior may not be visible from static dependency scanning alone.

Upwind can help identify suspicious install-time execution such as preinstall and prepare lifecycle abuse, unexpected bun execution during package installation, credential access targeting .npmrc, .env, SSH keys, kubeconfigs, cloud credential stores, Vault tokens, GitHub Actions material, password managers, and containerized CI/CD secrets, suspicious GitHub workflow changes, unexpected outbound communication to attacker-controlled infrastructure, runtime persistence behavior, Docker socket abuse, security tool tampering, and potential propagation from compromised CI/CD runners or developer environments.

By correlating runtime process activity, network behavior, identity context, cloud access, package execution, and workload telemetry, Upwind helps security teams determine whether an affected package was merely present or actually executed, which credentials may have been exposed, what systems were impacted, and where containment should begin.