Shai-Hulud Source Code Reveals Extensive Credential Theft and Supply-Chain Capabilities

Summary
Static analysis of a GitHub repository attributed to TeamPCP describes a modular framework for stealing credentials, exfiltrating data, and poisoning repositories and npm packages, including through developer-tool hooks and forged provenance.
Key points
- A repository that appeared on GitHub on May 12, 2026, contained what researchers describe as the complete Shai-Hulud framework source; GitHub reportedly removed it, though forks remained.
- The framework targets developer workstations and CI/CD environments, harvesting credentials from files, environment variables, cloud services, Kubernetes, Vault, and GitHub Actions runner memory.
- It encrypts collected data and sends it to a primary C2 domain or uses GitHub repositories as fallback dead drops.
- Stolen credentials can be used to poison GitHub branches and npm packages; the code also includes an OIDC-based npm publishing workflow and Sigstore provenance generation.
- Persistence mechanisms include VS Code folder-open tasks, Claude Code session hooks, and a daemon that can run a destructive command if a monitored GitHub token is revoked.
- The analysis describes obfuscation and a Russian-locale check, and provides indicators and checks for possible repository poisoning, malicious hooks, and exfiltration repositories.
Article Details
- Attack Vectors
- Harvesting credentials and secrets from files, shell environment variables, GitHub Actions runner memory, cloud metadata and APIs, Kubernetes, and HashiCorp Vault.
- Exfiltrating collected data over HTTPS to a C2 domain or through encrypted GitHub repository dead-drops.
- Poisoning GitHub repositories with IDE and AI coding assistant hooks that execute a payload when a repository is opened or a session starts.
- Poisoning npm packages using stolen publish tokens or GitHub Actions OIDC-based publishing, including forging Sigstore provenance.
- Maintaining persistence with a detached process and macOS LaunchAgent or Linux systemd user service; the token-monitor daemon can run a destructive handler if a stolen token is revoked.
- Avoiding execution when the system locale resolves to a Russian-language prefix.
- Defensive Notes
- Before revoking suspected stolen GitHub tokens, disable and remove the gh-token-monitor LaunchAgent or systemd user service to prevent its default destructive handler from running.
- Inspect user and project Claude Code settings for SessionStart hooks that execute setup.mjs, and inspect .vscode/tasks.json for folder-open tasks that launch the same loader.
- Review repository branches for commits authored by claude@users.noreply.github.com with the message chore: update dependencies, and check for unexpected .claude/setup.mjs, .vscode/setup.mjs, or .vscode/tasks.json files.
- Check GitHub accounts for repositories with the description Shai-Hulud: Here We Go Again and for evidence of the reported C2-rotation commit search string.
- If npm tokens may have been harvested, check packages for unexpected patch-version bumps and preinstall scripts, and remove affected versions.
- Review CI/CD pipelines, developer workstations, and cloud environments for the documented credential-harvesting and persistence mechanisms, including Runner.Worker memory extraction, metadata collection, and IDE hooks.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | git-tanstack[.]com | Reported primary C2 domain for HTTPS exfiltration. |
| IPV4 | 83[.]142[.]209[.]194 | C2 infrastructure associated with the activity, according to open-source reporting. |
| SHA256 | 2258284d65f63829bd67eaba01ef6f1ada2f593f9bbe41678b2df360bd90d3df | SHA-256 hash reported for the compiled setup.mjs payload. |
| SHA256 | 29ac906c8bd801dfe1cb39596197df49f80fff2270b3e7fbab52278c24e4f1a7 | SHA-256 hash listed for the framework's src/assets/python_util.py memory-reading utility. |
| SHA256 | 3f3f42d072bd36860ab7bd7fb5e10ac0d22c741c13c89505ccd6ec0ea572eea7 | SHA-256 hash listed for the framework's src/assets/workflow.yml artifact. |
| SHA256 | 619c56acf572df75b6004a6fc013c80900316a76099b241d64312da3a44f10b4 | SHA-256 hash listed for the framework's src/assets/DEADMAN_SWITCH.sh artifact. |
| SHA256 | 77d92efe7af3547f71fd41d4a884872d66b1be9499eaa637e91eac866911694d | SHA-256 hash listed for the framework's src/assets/config.mjs loader. |
| SHA256 | ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c | SHA-256 hash reported for the compiled router_init.js payload. |
| SHA256 | c55a10759f6f415a536940a75f42aa372878a51f8eb97468551eabf6d88ae492 | SHA-256 hash listed for the framework's embedded src/assets/verify_key.pub C2-verification key. |
| SHA256 | f2157f1cecbf3995aafad750e6e805c472cec466a53d17c2063f266ad2b3d625 | SHA-256 hash listed for the offensive framework's src/index.ts source file. |
| SHA256 | f7a1e56b6dbd42778fe349b8412ab9749c78fa2bf41ea90b1165615ddfee52e4 | SHA-256 hash listed for the framework's embedded src/assets/enc_key.pub exfiltration-encryption key. |
MITRE ATT&CK
T1003 · OS Credential Dumpingpython_util.py reads Runner.Worker process memory to extract GitHub Actions secrets.T1041 · Exfiltration Over C2 ChannelThe framework sends encrypted collected data over HTTPS to its reported C2 domain.T1059.004 · Unix ShellBASH_LOADER.sh and DEADMAN_SWITCH.sh are shell scripts used by the framework.T1059.006 · PythonPYTHON_LOADER.py and python_util.py are used to launch or perform framework functions.T1059.007 · JavaScriptThe framework's loaders and payload are implemented in JavaScript and TypeScript.T1102 · Web ServiceThe framework searches GitHub commits for a signed fallback C2 domain.T1195.001 · Compromise Software Dependencies and Development ToolsThe framework publishes modified npm packages, including through an OIDC-based publishing flow.T1195.002 · Compromise Software Supply ChainThe framework propagates through poisoned GitHub repository branches and backdoored npm packages.T1199 · Trusted RelationshipIt abuses GitHub Actions OIDC tokens to obtain an npm publish token.T1204.002 · Malicious FilePoisoned repositories use a VSCode folder-open task or Claude Code SessionStart hook to trigger the payload.T1485 · Data DestructionThe token-monitor daemon's default handler runs rm -rf ~/ if the monitored token is revoked.T1528 · Steal Application Access TokenThe framework collects GitHub CLI tokens and GitHub, npm, and Vault tokens.T1543.001 · Launch AgentOn macOS, the framework installs a LaunchAgent to monitor the stolen GitHub token.T1543.002 · Systemd ServiceOn Linux, the framework installs a systemd user service to monitor the stolen GitHub token.T1552.001 · Credentials In FilesThe framework scans sensitive filesystem paths for credentials and secrets.T1552.005 · Cloud Instance Metadata APIIts AWS provider queries EC2 IMDSv2 and ECS container metadata for credentials.T1552.007 · Container APIIts Kubernetes provider reads service-account tokens and retrieves secrets through the Kubernetes API.T1560.001 · Archive via UtilityThe sender gzip-compresses collected JSON data before encrypting it.T1567.001 · Exfiltration to Code RepositoryAs a fallback, the framework commits encrypted exfiltrated data to GitHub repositories.T1573.002 · Asymmetric CryptographyThe framework encrypts data with AES-256-GCM and protects the AES key with RSA-4096-OAEP.T1588.004 · Digital CertificatesThe npm publishing flow obtains a Fulcio certificate and generates Sigstore provenance for an attacker-controlled build.
Threat Actors
Malware
Products
Claude CodeClaude Code hook on SessionStart executing node .vscode/setup.mjsGitHub ActionsCredential and secret collection modules, each targeting a specific source: filesystem, shell environment, GitHub Actions runners, AWS, Kubernetes, HashiCorp VaultHashiCorp VaultCredential and secret collection modules, each targeting a specific source: filesystem, shell environment, GitHub Actions runners, AWS, Kubernetes, HashiCorp VaultKubernetesCredential and secret collection modules, each targeting a specific source: filesystem, shell environment, GitHub Actions runners, AWS, Kubernetes, HashiCorp VaultnpmThroughout early-to-mid 2026, the threat actor known as TeamPCP conducted a series of escalating supply chain attacks across the npm and PyPI ecosystems.SigstoreThe released source code showed evolving capabilities for persistence via AI agent integration and stealth by adding sigstore provenance to releasesVS Code.vscode/tasks.json