Une nouvelle faille de sécurité dans la chaîne d'approvisionnement npm vise l'écosystème des développeurs SAP.
Les paquets concernés que nous avons recensés jusqu'à présent sont les suivants :
@cap-js/sqlite - v2.2.2@cap-js/postgres - v2.2.2@cap-js/db-service - v2.10.1mbt@1.2.48
Le schéma est familier, mais présente tout de même une petite différence : un paquet de confiance reçoit un nouveau preinstall hook, le hook exécute un nouveau setup.mjs fichier, et ce chargeur télécharge le moteur d'exécution JavaScript Bun afin d'exécuter une charge utile volumineuse et obscurcie nommée execution.js.
La charge utile est un programme de vol d'identifiants et un cadre de propagation de 11,7 Mo. Elle recueille les identifiants des développeurs locaux, les jetons GitHub et npm, les secrets GitHub Actions, ainsi que cloud provenant d'AWS, d'Azure, de GCP et de Kubernetes. Elle exfiltre ensuite les résultats chiffrés via des dépôts GitHub publics.
Le logiciel malveillant nomme ces référentiels à l'aide d'une description codée en dur :
Un mini Shai-Hulud est apparu
Ce qui s'est passé
Les paquets compromis exploitent le cycle de vie de npm. D'après ce que nous avons pu constater jusqu'à présent, package.json a été modifié pour ajouter :
"scripts": {
"preinstall": "node setup.mjs"
}Cela signifie que le code malveillant s'exécute automatiquement pendant npm install, avant même que l'installation ne soit terminée.
Le paquet malveillant ajoute deux fichiers :
setup.mjsexecution.js
Le code du package standard ressemble toujours à celui d'un package SAP authentique. Dans le @cap-js/sqlite@2.2.2 Dans l'exemple, les fichiers normaux correspondent parfaitement @cap-js/sqlite@2.2.1 octet par octet. Le compromis réside dans le hook d'installation et les fichiers de charge utile ajoutés.
Point d'entrée probable
Une piste avancée par le public suggère une cause probable : un jeton npm exposé lors des compilations de pull requests via CircleCI.
Cela correspond à ce que nous avons constaté dans cloud. Le 29 avril, un projet de PR éphémère intitulé fonctionnalité : optimisation de la vitesse a été ouvert à partir de gruposbftechrecruiter/harkonnen-navigator-149. La PR clôturée en quelques minutes et la branche a ensuite fait l'objet d'un push forcé, laissant le diff GitHub actuel vide.
CircleCI a tout de même conservé l'essentiel. Une PR sur pull/1223 commit validé a959014aa7b7fc37a9b5730c951776e7db2920a6, qui a ajouté un chargeur de pains à bin/config.mjs, a ajouté une charge utile obscurcie à l'adresse bin/mbt.js, et j'ai modifié la commande de test comme suit :
node ./bin/config.mjs && node ./bin/mbtCe test a été exécuté dans le cadre d'une PR au cours de laquelle CircleCI a répertorié des secrets de projet anonymisés, notamment CLOUD, CLOUD, les jetons OIDC de CircleCI, les identifiants Docker Hub, les identifiants Cloud et d'autres variables liées à la publication.
Les journaux ont également révélé des avertissements d'Octokit concernant POST-https://api.github.com/user/repos, ce qui correspond au comportement d'exfiltration du logiciel malveillant sur GitHub.
Cela fait de la PR CircleCI PR la principale piste dans le cadre du vol initial d'identifiants.
Comment fonctionne le logiciel malveillant
La première étape, setup.mjs, est un programme de démarrage de Bun. Il vérifie le système d'exploitation et l'architecture, puis télécharge Bun 1.3.13 le télécharge depuis GitHub si nécessaire, extrait le fichier binaire et utilise Bun pour l'exécuter execution.js.
const BUN_VERSION = '1.3.13';
const ENTRY_SCRIPT = 'execution.js';
const url = `https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/${asset}.zip`;
execFileSync(binPath, [entryScriptPath], { stdio: 'inherit', cwd: SCRIPT_DIR });La deuxième étape, execution.js, est une seule et même charge utile volumineuse et obscurcie. Elle utilise une couche de brouillage de chaînes personnalisée nommée ctf-scramble-v2, vérifie s'il s'exécute en environnement CI, se ferme si les paramètres régionaux sont réglés sur le russe et se lance en mode démon sur les machines hors CI.
Ce qu'il vole
La charge utile est conçue pour cibler à la fois les ordinateurs portables des développeurs et les serveurs CI/CD.
Il vise à recueillir :
- Les jetons GitHub, y compris les données générées par
jeton d'authentification gh - jetons npm provenant de
.npmrc - variables d'environnement
- Secrets GitHub Actions
- Identité AWS STS, secrets Secrets Manager et paramètres SSM
- Abonnements Azure, noms de Key Vault et valeurs des secrets Key Vault
- Identifiant du projet GCP et valeurs de Secret Manager
- Jeton de compte de service Kubernetes
- Fichiers de configuration Claude, fichiers de configuration MCP, bases de données de jetons GCP, caches de jetons Azure, fichiers de configuration Signal, portefeuilles Electrum et fichiers de configuration VPN
Le chemin d'accès à GitHub Actions est particulièrement préoccupant. La charge utile comprend un utilitaire Python intégré qui recherche /proc pour le Coureur.Ouvrier processus, lit sa mémoire et extrait les structures secrètes masquées du programme d'exécution.
Mots-clés relatifs à l'exfiltration et à la propagation sur GitHub
Le logiciel malveillant utilise GitHub comme canal d'exfiltration.
Le nouveau mot-clé de propagation est :
Oh non, qu'est-ce qui se passe avec GitHub ?Le logiciel malveillant recherche cette chaîne de caractères dans les commits GitHub et utilise les messages de commit correspondants comme point de dépôt de données. Les messages de commit correspondant à OhNoWhatsGoingOnWithGitHub:<base64> sont convertis en jetons GitHub et leur accès au dépôt est vérifié.
Lorsque le logiciel malveillant parvient à créer un dépôt, il utilise des noms aléatoires inspirés de Dune et définit la description du dépôt comme suit :
Un mini Shai-Hulud est apparuet enregistre les fichiers de résultats cryptés dans le répertoire :
results/results-<timestamp>-<counter>.jsonLes données sont compressées et chiffrées avant leur enregistrement à l'aide de l'algorithme AES-256-GCM, la clé AES étant protégée par une clé RSA intégrée.

Logique de propagation
La charge utile contient la logique nécessaire à sa diffusion dans les processus de développement et de mise en production.
Dans les échantillons analysés, le logiciel malveillant recherche les automatisations de publication GitHub Actions liées à cap-js/cds-dbs. S'il détecte un workflow de publication dans ce contexte de dépôt, il peut modifier une archive tar du paquet en :
- copier la charge utile actuelle dans
execution.js - écriture
setup.mjs - réglage
scripts.preinstall = "node setup.mjs" - incrémenter la version du correctif
- recompresser l'archive
Il tente également d'utiliser des jetons GitHub Actions volés pour pousser des fichiers dans des dépôts :
.vscode/tasks.json.vscode/setup.mjs.claude/execution.js.claude/setup.mjs.claude/settings.json
Ces commits utilisent :
tâche : mise à jour des dépendancesavec l'auteur :
claude <claude@users.noreply.github.com>SAP en ligne de mire
Les paquets ciblés s'intègrent dans les processus de développement SAP habituels. @cap-js/sqlite, @cap-js/postgres, et @cap-js/service-de-base-de-données font partie de l'écosystème de bases de données SAP CAP, tandis que mbt est utilisé dans le cadre des workflows de compilation de SAP Cloud .
Cette campagne comporte donc peu de paquets, mais son impact pourrait être considérable. Ces paquets sont susceptibles d'être exécutés sur les machines des développeurs et les serveurs d'intégration continue (CI) ayant accès à GitHub, à npm, cloud et aux secrets de déploiement de l'entreprise.
Détection et atténuation
Recherchez dans les fichiers de verrouillage, les caches de paquets, les journaux d'intégration continue, les registres internes, les référentiels d'artefacts et les machines des développeurs les éléments suivants :
@cap-js/sqlite - v2.2.2@cap-js/postgres - v2.2.2@cap-js/db-service - v2.10.1mbt@1.2.48setup.mjsexecution.jspreinstallscripts en cours d'exécutionfichier setup.mjs- Petit pain
1.3.13téléchargements effectués lors de l'installation du paquet
Rechercher sur GitHub :
- Valider les résultats de la recherche pour
Oh non, qu'est-ce qui se passe avec GitHub ?:https://github.com/search?q=OhNoWhatsGoingOnWithGitHub&type=commits - référentiels accompagnés d'une description
Un mini Shai-Hulud est apparu - commits contenant
Oh non, qu'est-ce qui se passe avec GitHub ? - commits intitulés
tâche : mise à jour des dépendances - commits créés par
claude <claude@users.noreply.github.com> - inattendu
.claude/ou.vscode/setup.mjsfichiers résultats/résultats-*.jsonfichiers dans les dépôts publics nouvellement créés
Si un paquet concerné a été installé, procédez à la rotation des secrets. Ne limitez pas cette rotation aux jetons npm. La charge utile cible GitHub, npm, cloud , Kubernetes, les secrets d'intégration continue (CI) et les outils de développement locaux.
Comment Aikido détecte cela
Si vous êtes un utilisateur Aikido, vérifiez votre flux central et filtrez les problèmes de logiciels malveillants. Cela apparaîtra comme un problème critique 100/100. Aikido effectue des rescans nocturnes, mais nous vous recommandons de déclencher un rescan manuel dès maintenant.
Si vous n'êtes pas encore un utilisateur Aikido, vous pouvez créer un compte et connecter vos dépôts. Notre couverture des logiciels malveillants est incluse dans le plan gratuit, aucune carte de crédit requise.
Pour une couverture plus large de toute votre équipe, l'Endpoint Protection d'Aikido vous offre une visibilité et un contrôle sur les packages logiciels installés sur les appareils de votre équipe. Elle couvre les extensions de navigateur, les bibliothèques de code, les plugins d'IDE et les dépendances de build, le tout en un seul endroit. Arrêtez les logiciels malveillants avant qu'ils ne soient installés.
Pour vous protéger à l'avenir, pensez à Aikido Chain (open source). Safe Chain s'intègre à votre flux de travail actuel : il intercepte les commandes npm, npx, yarn, pnpm et pnpx et vérifie la conformité des paquets par rapport Aikido avant leur installation.
Indicateurs de Compromission
Paquets concernés :
@cap-js/sqlite - v2.2.2@cap-js/postgres - v2.2.2@cap-js/db-service - v2.10.1mbt@1.2.48
Hachages issus de l'analyse @cap-js/sqlite@2.2.2 exemple :
setup.mjs:4066781fa830224c8bbcc3aa005a396657f9c8f9016f9a64ad44a9d7f5f45e34execution.js:6f933d00b7d05678eb43c90963a80b8947c4ae6830182f89df31da9f568fea95- Outil de sauvegarde de la mémoire intégré à GitHub Runner :
29ac906c8bd801dfe1cb39596197df49f80fff2270b3e7fbab52278c24e4f1a7
Chaînes et marqueurs :
Un mini Shai-Hulud est apparuOh non, qu'est-ce qui se passe avec GitHub ?(mot-clé de propagation / marqueur de dépôt GitHub)ctf-scramble-v2tmp.987654321.locktâche : mise à jour des dépendancesclaude@users.noreply.github.com
URL et points de terminaison :
hxxps://github[.]com/oven-sh/bun/releases/download/bun-v1.3.13/hxxps://api.github[.]com/search/commits?q=OhNoWhatsGoingOnWithGitHub&sort=author-date&order=desc&per_page=50hxxp://169.254.169.254hxxp://169.254.170.2hxxp://[fd00:ec2::254]

