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

· Original article ↗

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

TypeIndicatorContext
DOMAINgit-tanstack[.]comReported primary C2 domain for HTTPS exfiltration.
IPV483[.]142[.]209[.]194C2 infrastructure associated with the activity, according to open-source reporting.
SHA2562258284d65f63829bd67eaba01ef6f1ada2f593f9bbe41678b2df360bd90d3dfSHA-256 hash reported for the compiled setup.mjs payload.
SHA25629ac906c8bd801dfe1cb39596197df49f80fff2270b3e7fbab52278c24e4f1a7SHA-256 hash listed for the framework's src/assets/python_util.py memory-reading utility.
SHA2563f3f42d072bd36860ab7bd7fb5e10ac0d22c741c13c89505ccd6ec0ea572eea7SHA-256 hash listed for the framework's src/assets/workflow.yml artifact.
SHA256619c56acf572df75b6004a6fc013c80900316a76099b241d64312da3a44f10b4SHA-256 hash listed for the framework's src/assets/DEADMAN_SWITCH.sh artifact.
SHA25677d92efe7af3547f71fd41d4a884872d66b1be9499eaa637e91eac866911694dSHA-256 hash listed for the framework's src/assets/config.mjs loader.
SHA256ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266cSHA-256 hash reported for the compiled router_init.js payload.
SHA256c55a10759f6f415a536940a75f42aa372878a51f8eb97468551eabf6d88ae492SHA-256 hash listed for the framework's embedded src/assets/verify_key.pub C2-verification key.
SHA256f2157f1cecbf3995aafad750e6e805c472cec466a53d17c2063f266ad2b3d625SHA-256 hash listed for the offensive framework's src/index.ts source file.
SHA256f7a1e56b6dbd42778fe349b8412ab9749c78fa2bf41ea90b1165615ddfee52e4SHA-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

Industries

Related Articles