Shai-Hulud Goes Open Source | Datadog Security Labs

Shai-Hulud Goes Open Source | Datadog Security Labs
A GitHub repository briefly exposed the complete source code for the Shai-Hulud framework attributed to TeamPCP, revealing a modular toolkit for credential harvesting, supply chain poisoning, encrypted exfiltration, persistence, and AI development workflow abuse. The source also shows stealth and resilience features such as Sigstore provenance forgery, RSA-signed fallback C2 resolution, and destructive deadman-switch behavior tied to GitHub token revocation. #ShaiHulud #TeamPCP #GitHub #Sigstore #OpenSearch #ClaudeCode

Keypoints

  • The exposed GitHub repository contained what appears to be the full source code of the Shai-Hulud offensive framework linked to TeamPCP.
  • The toolkit is modular and includes loaders, collectors, dispatchers, senders, and mutators for credential theft, propagation, and exfiltration.
  • It targets developer workstations, CI/CD pipelines, GitHub Actions runners, AWS, Kubernetes, HashiCorp Vault, and package ecosystems such as npm and PyPI.
  • The framework reads secrets from files, environment variables, process memory, cloud metadata services, Kubernetes APIs, and GitHub tokens.
  • Data is encrypted with AES-256-GCM and RSA-4096-OAEP before being sent to a C2 domain, GitHub repositories, or fallback dead-drop infrastructure.
  • Persistence is achieved through malicious VSCode tasks, Claude Code SessionStart hooks, and a token-monitoring daemon that can trigger destructive cleanup.
  • The source reveals anti-analysis and stealth features including obfuscation, per-build string scrambling, signed fallback domain discovery, and forged Sigstore provenance.

MITRE Techniques

  • [T1195.002 ] Compromise Software Supply Chain – Poisoned npm packages and GitHub repository branches were used for propagation and compromise (‘npm package poisoning, GitHub repo branch poisoning’).
  • [T1195.001 ] Compromise Software Dependencies – OIDC-based npm publishing and forged provenance were used to alter trusted dependencies (‘OIDC-based npm publishing with forged provenance’).
  • [T1199 ] Trusted Relationship – GitHub Actions OIDC tokens were abused to obtain trusted publishing access (‘GitHub Actions OIDC token abuse for npm publish’).
  • [T1059.004 ] Unix Shell – Bash scripts handled bootstrapping and destructive monitoring logic (‘BASH_LOADER.sh, DEADMAN_SWITCH.sh’).
  • [T1059.006 ] Python – Python was used for the loader and for memory-reading secret extraction (‘PYTHON_LOADER.py, python_util.py (memory reader)’).
  • [T1059.007 ] JavaScript – TypeScript/Bun JavaScript payloads implemented the framework and loaders (‘config.mjs, compiled payloads, entire TypeScript framework’).
  • [T1204.002 ] User Execution: Malicious File – Malicious VSCode and Claude Code hooks triggered execution when a repo was opened or a session started (‘runOn: “folderOpen”, Claude Code SessionStart hook’).
  • [T1543.001 ] Launch Agent – A macOS LaunchAgent provided persistence for the token-monitoring daemon (‘com.user.gh-token-monitor persistence’).
  • [T1543.002 ] Systemd Service – A Linux systemd user service maintained persistence on Linux hosts (‘gh-token-monitor.service persistence’).
  • [T1552.001 ] Credentials in Files – Over 100 sensitive file paths were scanned for secrets across Linux, macOS, and Windows-style locations (‘100+ file paths scanned across 3 OS families’).
  • [T1552.005 ] Cloud Instance Metadata Service – Cloud credentials were collected from AWS IMDSv2 and ECS metadata (‘AWS IMDSv2, ECS container metadata’).
  • [T1552.007 ] Container API – Kubernetes service account tokens and secrets were pulled from in-cluster APIs (‘Kubernetes service account tokens, secrets API’).
  • [T1003 ] OS Credential Dumping – Process memory was read from /proc//mem to extract secrets from Runner.Worker (‘reading of Runner.Worker’).
  • [T1528 ] Steal Application Access Token – GitHub CLI tokens, GitHub PATs, npm tokens, and Vault tokens were harvested (‘gh auth token, GitHub PATs, npm tokens, Vault tokens’).
  • [T1560.001 ] Archive via Utility – Collected data was gzip-compressed before encryption and exfiltration (‘gzip compression before encryption’).
  • [T1041 ] Exfiltration Over C2 Channel – Encrypted data was sent via HTTPS POST to the primary C2 domain (‘HTTPS POST to git-tanstack[.]com’).
  • [T1567.001 ] Exfiltration to Code Repository – Encrypted payloads were committed to GitHub repositories as dead-drops (‘Encrypted commits to GitHub repos’).
  • [T1573.002 ] Asymmetric Cryptography – AES-256-GCM was combined with RSA-4096 for hybrid encryption and key wrapping (‘RSA-4096 + AES-256-GCM hybrid encryption’).
  • [T1102 ] Web Service – GitHub commit search was used as a signed dead-drop mechanism for fallback C2 resolution (‘GitHub commit search as signed C2 dead-drop’).
  • [T1485 ] Data Destruction – A deadman-switch handler could delete the victim’s home directory (‘rm -rf ~/ deadman switch’).
  • [T1588.004 ] Digital Certificates – Fulcio certificates and Rekor entries were abused to create forged provenance for poisoned packages (‘Fulcio certificate abuse for provenance forgery’).

Indicators of Compromise

  • [Domain ] Primary C2/exfiltration endpoint – git-tanstack[.]com, and a GitHub-search-derived fallback domain
  • [IP Address ] C2 infrastructure referenced in prior reporting – 83.142.209[.]194
  • [File Names ] Payloads and loaders observed in the framework – router_init.js, setup.mjs, opensearch_init.js, and python_util.py
  • [Shell Scripts ] Persistence and bootstrapping components – BASH_LOADER.sh, DEADMAN_SWITCH.sh, and config.mjs
  • [GitHub Strings ] C2 search and exfiltration markers – thebeautifulmarchoftime, IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner, and Shai-Hulud: Here We Go Again
  • [Persistence Artifacts ] Host-based persistence paths and service names – ~/.config/systemd/user/gh-token-monitor.service, ~/Library/LaunchAgents/com.user.gh-token-monitor.plist, and tmp.ts018051808.lock
  • [Public Key Files ] Embedded RSA keys used for encryption and verification – src/assets/enc_key.pub and src/assets/verify_key.pub
  • [SHA-256 Hashes ] Source repository file hashes for detection – src/index.ts (f2157f1cecbf3995aafad750e6e805c472cec466a53d17c2063f266ad2b3d625) and router_init.js (ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c)


Read more: https://securitylabs.datadoghq.com/articles/shai-hulud-open-source-framework-static-analysis/