🎯 Contexte

Article publié le 19 mai 2026 par Snyk (blog.snyk.io), rédigé par Liran Tal. Il documente une attaque de supply chain active sur le registre npm, ciblant l’écosystème de visualisation de données @antv (suite originaire d’Alibaba).

🔥 Incident

Le 19 mai 2026 entre 01:39 et 02:06 UTC, le groupe TeamPCP (alias : DeadCatx3, PCPcat) a publié 637 versions malveillantes sur 323 packages npm en deux vagues automatisées de 22 minutes. Le vecteur initial est la compromission du compte npm atool, qui maintient 547 packages représentant environ 16 millions de téléchargements hebdomadaires.

Packages les plus téléchargés affectés :

  • size-sensor (4,2M/mois)
  • echarts-for-react (3,8M/mois)
  • @antv/scale (2,2M/mois)
  • timeago.js (1,15M/mois)
  • @antv/g6 (1M+/mois)
  • @antv/g2, @antv/x6, @antv/l7, @antv/s2, @antv/f2, @antv/g, @antv/g2plot, @antv/graphin, @antv/data-set, canvas-nest.js

⚙️ Mécanisme d’attaque (7 étapes)

  1. Compromission du compte maintainer atool sur npm
  2. Publication automatisée de versions malveillantes contenant un payload Bun JS obfusqué de 498 Ko (index.js) et un hook preinstall: bun run index.js dans package.json
  3. Injection d’un commit orphelin dans le dépôt légitime antvis/G2 via fork supprimé, avec forgeage de l’identité d’un vrai mainteneur (huiyu.zjt@ant.com), permettant d’obtenir des attestations SLSA Build Level 3 valides via Sigstore (Fulcio/Rekor) en abusant de tokens OIDC GitHub Actions volés
  4. Collecte de credentials : plus de 80 variables d’environnement et 100+ chemins de fichiers ciblés (AWS, GCP, Azure, GitHub PAT/OIDC, npm tokens, Kubernetes, Vault, bases de données, Stripe, Slack, SSH keys). Lecture mémoire via /proc/{pid}/mem dans GitHub Actions
  5. Exfiltration chiffrée AES-256-GCM + RSA-OAEP vers deux canaux : C2 primaire https://t.m-kosche.com:443/api/public/otel/v1/traces (déguisé en OpenTelemetry) et dead-drop GitHub (dépôts aux noms thème Dune)
  6. Persistance : hook Claude Code (.claude/settings.json), tâche VS Code (.vscode/tasks.json), daemon OS (~/.local/share/kitty/cat.py) enregistré en service systemd/LaunchAgent, moniteur de tokens (~/.local/bin/gh-token-monitor.sh)
  7. Propagation en ver : utilisation des tokens npm bypass_2fa volés pour republier d’autres packages ; injection de workflow GitHub Actions (chore/add-codeql-static-analysis) exfiltrant toJSON(secrets)

📊 Campagne Shai-Hulud (depuis septembre 2025)

Vague Date Cible Échelle Technique signature
Wave 1 Sep 2025 npm (large) ~4 packages Premier ver npm auto-propagant
Wave 2 (SHA1-Hulud) Nov 2025 Zapier, Posthog, Postman 600+ packages Container breakout, wiper
Wave 3 (Mini, SAP) Avr 2026 SAP CAP-JS, MBT 4 packages Hook Claude Code SessionStart
Wave 4 (TanStack) 11 mai 2026 @tanstack/* 84 versions/42 packages Provenance SLSA valide via OIDC
Wave 5 (AntV) 19 mai 2026 @antv/* + 310 autres 637 versions/323 packages Compte maintainer compromis, C2 étendu

📋 Type d’article

Analyse technique et rapport d’incident détaillé, visant à documenter l’attaque, fournir des IoCs, des indicateurs de persistance et des étapes de remédiation pour les équipes de sécurité et développeurs affectés.

🧠 TTPs et IOCs détectés

Acteurs de menace

TTP

  • T1195.001 — Supply Chain Compromise: Compromise Software Dependencies and Development Tools (Initial Access)
  • T1078 — Valid Accounts (Initial Access)
  • T1059.007 — Command and Scripting Interpreter: JavaScript (Execution)
  • T1543 — Create or Modify System Process (Persistence)
  • T1053 — Scheduled Task/Job (Persistence)
  • T1552.001 — Unsecured Credentials: Credentials In Files (Credential Access)
  • T1552.004 — Unsecured Credentials: Private Keys (Credential Access)
  • T1552.007 — Unsecured Credentials: Container API (Credential Access)
  • T1003 — OS Credential Dumping (Credential Access)
  • T1041 — Exfiltration Over C2 Channel (Exfiltration)
  • T1567.001 — Exfiltration Over Web Service: Exfiltration to Code Repository (Exfiltration)
  • T1027 — Obfuscated Files or Information (Defense Evasion)
  • T1553 — Subvert Trust Controls (Defense Evasion)
  • T1071.001 — Application Layer Protocol: Web Protocols (Command and Control)
  • T1102 — Web Service (Command and Control)
  • T1496 — Resource Hijacking (Impact)
  • T1584.001 — Compromise Infrastructure: Domains (Resource Development)
  • T1608.003 — Stage Capabilities: Install Digital Certificate (Resource Development)

IOC

  • IPv4 : 169.254.169.254AbuseIPDB · VT · ThreatFox
  • IPv4 : 169.254.170.2AbuseIPDB · VT · ThreatFox
  • Domaines : t.m-kosche.comVT · URLhaus · ThreatFox
  • URLs : https://t.m-kosche.com:443/api/public/otel/v1/tracesURLhaus
  • SHA256 : a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1cVT · MalwareBazaar
  • Emails : huiyu.zjt@ant.com
  • Fichiers : index.js
  • Fichiers : cat.py
  • Fichiers : gh-token-monitor.sh
  • Fichiers : codeql.yml
  • Fichiers : format-results.txt
  • Chemins : ~/.local/share/kitty/cat.py
  • Chemins : ~/.local/bin/gh-token-monitor.sh
  • Chemins : ~/.config/systemd/user/kitty-monitor.service
  • Chemins : ~/Library/LaunchAgents/com.user.kitty-monitor.plist
  • Chemins : .claude/settings.json
  • Chemins : .vscode/tasks.json
  • Chemins : .github/workflows/codeql.yml
  • Chemins : .claude/setup.mjs

Malware / Outils

  • Mini Shai-Hulud payload (stealer)
  • Bun JS obfuscated payload (loader)

🟢 Indice de vérification factuelle : 72/100 (haute)

  • ⬜ snyk.io — source non référencée (0pts)
  • ✅ 19755 chars — texte complet (fulltext extrait) (15pts)
  • ✅ 19 IOCs dont des hashes (15pts)
  • ✅ 2/5 IOCs confirmés (AbuseIPDB, MalwareBazaar, ThreatFox, URLhaus, VirusTotal) (12pts)
  • ✅ 18 TTPs MITRE identifiées (15pts)
  • ✅ date extraite du HTML source (10pts)
  • ✅ acteur(s) identifié(s) : TeamPCP (5pts)
  • ⬜ pas de CVE à vérifier (0pts)

IOCs confirmés externellement :

  • a68dd1e6a6e35ec3… (sha256) → VT (7/76 détections)
  • t.m-kosche.com (domain) → VT (17/92 détections)

🔗 Source originale : https://snyk.io/fr/blog/mini-shai-hulud-antv-npm-supply-chain-attack/