Shai-Hulud, 2e partie : Quand le Worm son propre certificat de sécurité

May 13, 2026
5/13/2026
Lucie Cardiet
Responsable de la recherche sur les cybermenaces
Shai-Hulud, 2e partie : Quand le Worm son propre certificat de sécurité

Ce matin, TeamPCP a publié worm GitHub le code source complet du worm de chaîne logistique Shai-Hulud. Licence MIT. Deux dépôts. Quarante-quatre fourches en quelques heures, dont l'une a ajouté la prise en charge de FreeBSD avant même que la plupart des équipes de sécurité aient eu le temps de lire le titre.

Est-ce codé par vibration ? Oui. Est-ce que ça marche ? Laissez les résultats parler d'eux-mêmes. Modifiez les touches et C2 selon vos besoins. Avec toute notre affection, l'équipe PCP

J 'ai parlé de Shai-Hulud l'année dernière. Cet article traitait des mécanismes fondamentaux : comment le worm dans l'installation de paquets, change de moteur d'exécution pour éviter d'être détecté, collecte des identifiants, exfiltre des données via des dépôts GitHub publics et se propage en tirant parti de la confiance que la victime accorde déjà à l'écosystème.

Ces mécanismes sont toujours d'actualité. Mais la campagne menée en mai 2026 contre TanStack et plus de 170 autres paquets a révélé un aspect que l'article initial n'avait pas abordé. Le worm à faire passer ses paquets malveillants pour des paquets certifiés.

Capture d'écran du dépôt GitHub publié par TeamPCP

Quels ont été les changements apportés à la campagne TanStack ?

Lors de chacune des précédentes attaques de Shai-Hulud, le worm des jetons npm et publié des paquets malveillants sous le compte de la victime. Ces paquets semblaient légitimes, car ils provenaient d’un éditeur connu. C’est là que résidait la supercherie.

La campagne TanStack a ajouté une étape supplémentaire. Selon une étude publiée par Wiz, StepSecurity et Snyk, le worm un jeton OIDC de la mémoire du processus du runner GitHub Actions. Il a ensuite utilisé ce jeton pour obtenir un certificat de signature cryptographique auprès de l'autorité de certification Fulcio de Sigstore. Il s'est ensuite servi de ce certificat pour signer le paquet malveillant.

Résultat : le paquet malveillant était accompagné d'une attestation de provenance SLSA de niveau 3 valide. Il ne s'agissait pas d'une contrefaçon, mais d'une attestation légitime, délivrée par Sigstore à l'identité GitHub Actions de la victime.

Les identifiants volés ont été exfiltrés vers git-tanstack[.]com, un domaine sosie enregistré spécialement pour cette opération, ainsi que vers des points de terminaison de Session Network et un ensemble de dépôts GitHub utilisant le thème Dune. Pendant l'attaque, TeamPCP a laissé le message suivant sur ce domaine :

Message laissé par TeamPCP sur son domaine C2 git-tanstack[.]com pendant l'attaque en direct, en mai 2026. Source : Wiz.
(Le lien YouTube renvoie vers le clip « Hello » de Martin Solveig. Il ne s'agit pas d'une charge utile.)

Que sont les jetons OIDC et pourquoi sont-ils stockés dans la mémoire du runner ?

OIDC est l'acronyme d'OpenID Connect. Dans le contexte de GitHub Actions, cette technologie résout un problème spécifique lié à la gestion des identifiants : les pipelines CI/CD doivent s'authentifier auprès de services externes (registres npm, cloud , Sigstore) sans stocker de secrets à long terme dans le dépôt.

La solution consiste en un jeton à durée de vie limitée. Lorsqu'une tâche s'exécute, le fournisseur OIDC de GitHub émet un jeton qui représente l'identité spécifique de cette tâche : ce workflow, ce dépôt, cette validation, cet acteur. Le jeton est accessible au runner via une variable d'environnement et un endpoint local. Il expire quelques minutes après son émission.

L'hypothèse de sécurité repose sur le fait que le jeton est temporaire et limité à un contexte spécifique. Un pirate qui parvient à mettre la main sur les secrets stockés d'un développeur ne peut pas réutiliser un jeton issu d'une tâche précédente, car celui-ci a déjà expiré. Cette hypothèse est valable dans des conditions normales.

Le worm fonctionne worm dans des conditions normales. Il exécute du code au sein même de la tâche Actions, au moment où le jeton est actif.

Comment fonctionne l'extraction dans la pratique

Le worm le ACTIONS_ID_TOKEN_REQUEST_TOKEN variable d'environnement du processus d'exécution et l'utilise pour demander un jeton OIDC auprès endpoint OIDC de GitHub. Il a ensuite soumet ce jeton à l'autorité de certification Fulcio de Sigstore, qui génère un certificat X.509 à durée de vie limitée associé à l'identité de la tâche GitHub Actions. Grâce à ce certificat et à une entrée dans le journal de transparence Rekor, le worm une signature cosign valide et une attestation de provenance SLSA pour le paquet qu'il s'apprête à publier.

Chaque étape correspond à un appel API légitime vers un service légitime. Le programme d'exécution dispose des autorisations nécessaires pour effectuer toutes ces opérations. C'est là tout le problème. Le code malveillant s'exécute au sein d'une tâche qui a obtenu ces autorisations grâce à la configuration de confiance du référentiel, et il les utilise exactement comme prévu.

Pourquoi la vérification de la provenance échoue

La vérification de la provenance SLSA a pour but de répondre à une question précise : cet artefact a-t-il été généré par le système de compilation prévu, à partir de la source attendue, sans aucune intervention non autorisée ? Le niveau de compilation 3 exige spécifiquement un environnement de compilation sécurisé qui empêche le processus de falsifier sa propre provenance.

La technique OIDC de Shai-Hulud contourne l'hypothèse de conception, mais pas le contrôle technique:

  • Le système de compilation n'est pas compromis.
  • endpoint OIDC n' endpoint pas compromis.
  • Le certificat Fulcio CA de Sigstore n'a pas été compromis.

Ce que l'attestation ne permet pas de mettre en évidence, c'est que le code exécuté au sein de la tâche n'était pas celui que le responsable de la maintenance avait prévu d'exécuter. Le worm via une dépendance installée plus tôt dans le pipeline.

Du point de vue de Sigstore, un exécuteur GitHub Actions légitime, fonctionnant sous l'identité d'un dépôt légitime, a signé un artefact légitime. L'attestation est exacte quant à ces faits. Elle ne précise pas comment la charge utile s'est retrouvée là.

Le certificat permet de vérifier l'identité du signataire. Il ne permet pas de vérifier ses intentions, ni ce qui s'exécutait par ailleurs dans le même processus.

Deux problèmes de détection, et non un seul

Dans son message initial, Shai-Hulud présentait cela comme un problème du type « tout semble normal »: les actions individuelles worm — installation de paquets, exécution de scripts, publication sur npm — sont toutes des opérations courantes qui ne génèrent aucune malware et ne déclenchent aucune violation de politique. Chaque étape ressemble à un travail de développement tout à fait normal.

La technique OIDC met en évidence un deuxième problème connexe : le mouvement lui-même n'est pas visible. L'extraction du jeton et l'appel de signature Sigstore constituent des mouvements latéraux à travers la couche d'identité de l'infrastructure de confiance CI/CD. Le worm un identifiant fédéré auprès de GitHub, le présente à Sigstore et reçoit un certificat qui autorise la publication sur npm sous la chaîne de provenance de la victime. Le mouvement traverse trois systèmes distincts : le fournisseur OIDC de GitHub, l'autorité de certification (CA) de Sigstore et le registre npm. Chaque système enregistre un événement d'authentification valide.

Cela fait donc trois journaux d'audit et trois authentifications réussies. L'entrée de journal qui manque est celle qui vous indiquerait que le code à l'origine de ces appels n'était pas censé être là.

Dans le cadre que j'utilise dans « Mind Your Attack Gaps », ces éléments correspondent à deux des trois principales lacunes de détection: « rien ne semble anormal » (lacune n° 1) et « les mouvements ne sont pas visibles » (lacune n° 3). La plupart des attaques par la chaîne d'approvisionnement en déclenchent une seule. Cette technique les déclenche toutes les deux simultanément, ce qui explique pourquoi elle a échappé aux analyses automatisées sur 170 paquets avant qu'un fournisseur ne la signale.

Ce que change le passage à l'open source

Jusqu'à aujourd'hui, la technique d'extraction OIDC était attribuée à un seul groupe. Tous les incidents impliquant cette technique remontaient à TeamPCP. Les analyses criminalistiques menées par Wiz, Ox Security et ReversingLabs ont permis de détecter leurs indicateurs spécifiques : les domaines C2, les noms de fichiers de charge utile, ainsi que les schémas d'exfiltration vers Session Network et les référentiels liés à Dune.

L'ouverture du code source rompt ce modèle de confinement. Tout acteur qui crée une branche du dépôt dispose alors de la capacité d'extraction OIDC. Les indicateurs spécifiques varient selon chaque variante. La technique reste la même.

La branche dérivée de FreeBSD, ajoutée quelques heures seulement après la mise en ligne des dépôts, illustre bien la rapidité avec laquelle les choses évoluent. Le worm s'exécute worm sur des plateformes où l'original n'avait jamais été testé. PyPI est une cible confirmée de la campagne de mai 2026. RubyGems et Maven sont les prochains candidats évidents. Les 401 versions de paquets malveillants publiées sur 170 paquets en l'espace de cinq heures le 11 mai ont établi une référence. Les acteurs dérivés utilisant cette boîte à outils ne seront pas en reste.

Message publié sur le compte TeamPCP de X : « C'est l'année de la chaîne d'approvisionnement. Vous allez avoir du pain sur la planche pendant très longtemps. » - 31 mars 2026

À quoi ressemble la détection

La vérification des artefacts ne permet pas de détecter ce problème. L'attestation est valide. La signature est valide. Le paquet est fonctionnellement correct. Les utilisateurs en aval qui vérifient la provenance SLSA avant l'installation verront que la vérification est réussie.

Ces signaux sont d'ordre comportemental et apparaissent avant la publication du paquet malveillant. En soi, endpoint pas inhabituel endpoint un exécuteur CI demande un jeton OIDC et appelle endpoint Fulcio de Sigstore. Cependant, le fait qu'un exécuteur effectue cette opération tout en établissant des connexions sortantes vers un hôte inconnu au cours de la même exécution de tâche constitue une séquence qui mérite d'être examinée. Une publication de paquet survenant après une activité réseau anormale au cours de la même session d'exécuteur est la chaîne d'événements à surveiller.

Le message initial mentionnait les signaux comportementaux suivants: un jeton GitHub créant des dépôts en nombre inhabituel, un exécuteur CI accédant à cloud au-delà du périmètre de la tâche qui lui avait été attribuée, et une cloud appelant des services qu’elle n’avait jamais utilisés auparavant. Les nouveaux éléments identifiés sont une requête OIDC, un appel à l’API Sigstore et une publication npm au sein de la même tâche, qui a également généré des connexions sortantes inhabituelles.

Chaque action est légitime. C'est leur combinaison qui ne l'est pas.

Pourquoi la cohérence entre les environnements est-elle importante dans ce contexte ?

Vectra AI surveille les schémas comportementaux à travers les systèmes d'identité, les réseaux et cloud . Dans les incidents liés à la chaîne logistique, les signaux pertinents se trouvent rarement dans un seul journal. Ils résident dans la corrélation : qu'a fait ce processus avant sa publication ? Quels hôtes externes sont apparus dans le trafic réseau de cette tâche qui n'étaient pas présents lors des cinquante dernières exécutions ? Quelle cloud ce processus a-t-il appelée qu'il n'avait jamais appelée auparavant ?

Le problème de détection posé par Shai-Hulud n'est pas un problème de signature. C'est un problème de contexte. Ce contexte s'étend sur trois journaux d'audit et une trace réseau. Lorsque ces éléments sont mis en corrélation, l'empreinte comportementale worm devient visible avant même que le paquet malveillant n'atteigne un destinataire en aval.

--

Le phénomène plus général, à savoir la circulation latérale des identifiants d'identité fédérée à travers l'infrastructure de confiance CI/CD pour l'authentification auprès des services en aval, est ce que j'appelle la lacune « le mouvement n'est pas visible » (Lacune 3) dans l' ebook Mind Your Attack Gaps. Le chapitre 3 examine en détail ce modèle de mouvement inter-environnements, en prenant comme étude de cas principale la vague de la chaîne d'approvisionnement OAuth. La technique OIDC Shai-Hulud pose le même problème structurel au sein du pipeline de build plutôt qu'au niveau de la couche SaaS.

--

Sources primaires :

Foire aux questions