Comment Storm-2949 a transformé une identité compromise en une violation à l’échelle du cloud
Detection stack
- AIDR
- Alert
- ETL
- Query
Résumé
Storm-2949 a utilisé l’ingénierie sociale et l’abus de la réinitialisation du mot de passe en libre-service pour compromettre les comptes Microsoft Entra ID. Après avoir obtenu un accès privilégié, l’acteur malveillant a utilisé des actions du plan de gestion Azure pour atteindre les Services d’application, les coffres de clés, les comptes de stockage et les bases de données SQL. Les données ont ensuite été exfiltrées à partir de Microsoft 365, du stockage Azure et d’autres ressources cloud. L’intrusion a ensuite progressé vers le déploiement de l’outil d’accès à distance ScreenConnect sur des machines virtuelles pour soutenir des reconnaissances supplémentaires et le vol de justificatifs.
Enquête
Les analystes de Microsoft ont observé les attaquants énumérant les utilisateurs et les applications via l’API Microsoft Graph avec des outils Python personnalisés. Ils ont récupéré les profils de publication des services App Azure, extrait des secrets des coffres de clés, modifié les règles de pare-feu et utilisé l’extension VMAccess pour créer des comptes administrateurs locaux sur des machines virtuelles. À une étape ultérieure, un script PowerShell a installé ScreenConnect, effacé les journaux et déguisé les services pour réduire la visibilité. L’enquête a lié cette activité à trois adresses IP contrôlées par les attaquants.
Atténuation
Les organisations devraient activer l’AMF et exiger une authentification résistante au phishing pour les comptes privilégiés. Les autorisations Azure RBAC devraient être strictement restreintes et surveillées, en particulier l’accès de niveau Propriétaire aux coffres de clés et aux services App. Les extensions de VM Azure inutiles devraient être désactivées, et la journalisation devrait être appliquée pour les activités de commande Run et VMAccess. Microsoft Defender for Cloud et Defender for Endpoint devraient également être activés avec une protection anti-sabotage et un mode de blocage.
Réponse
Les défenseurs devraient bloquer immédiatement les adresses IP malveillantes identifiées et révoquer les justificatifs compromis. Les mots de passe et les enregistrements AMF des comptes affectés devraient être réinitialisés, et tous les secrets stockés dans les coffres de clés devraient être renouvelés. Les équipes de sécurité devraient également effectuer une révision complète des affectations Azure RBAC et supprimer les privilèges excessifs. Les règles de détection devraient être mises à jour pour identifier les demandes de profil de publication suspectes, les accès aux secrets des coffres de clés, et les activités inattendues des extensions VM.
Flux d’attaque
Détections
Usage suspect de Invoke-RestMethod (via powershell)
Voir
Un coffre Azure possible a été contacté par un processus rare (via dns_query)
Voir
IOC (SourceIP) pour détecter : Comment Storm-2949 a transformé une identité compromise en une violation cloud générale
Voir
IOC (DestinationIP) pour détecter : Comment Storm-2949 a transformé une identité compromise en une violation cloud générale
Voir
Détection des opérations du plan de gestion Azure pour l’exfiltration de données [Journaux d’activité Azure]
Voir
Exécution de simulation
Condition préalable : La vérification télémétrique et de référence doit avoir réussi.
-
Narrative d’attaque et commandes :
Un adversaire qui a obtenu un compte valide Azure AD (ou principal de service par défaut) veut exfiltrer le code source de l’application et les instantanés de la base de données. L’attaquant exécute les étapes suivantes entièrement via Azure CLI, générant exactement
operationNameles événements que règle surveille :- Publier l’application Web XML – extrait la configuration de l’application Web (y compris les justificatifs de déploiement).
- Créer un nouveau compte de stockage – fournit un conteneur pour la mise en scène des données exfiltrées.
- Ajouter une règle de pare-feu au serveur SQL – ouvre le serveur à la plage IP de l’attaquant, permettant la copie directe de données.
Chaque étape produit une entrée du journal d’activité avec
operationNamecorrespondant à la liste blanche de la règle, déclenchant ainsi la détection. -
Script de test de régression :
#!/usr/bin/env bash # Condition préalable : l'interface CLI az est connectée avec un principal Azure AD compromis/valide. set -euo pipefail # Variables – modifiez si nécessaire pour le locataire de test RG="test-rg-$(date +%s)" WEBAPP="test-webapp-$RANDOM" STORAGE="teststorage$RANDOM" LOCATION="eastus" SQLSERVER="testsql$RANDOM" MY_IP=$(curl -s https://api.ipify.org) echo "=== Créer un groupe de ressources ===" az group create --name "$RG" --location "$LOCATION" echo "=== Déployer une application Web factice ===" az appservice plan create --name "${WEBAPP}Plan" --resource-group "$RG" --sku B1 --is-linux az webapp create --resource-group "$RG" --plan "${WEBAPP}Plan" --name "$WEBAPP" echo "=== Publier la configuration XML (déclenche la détection) ===" az webapp config backup create --resource-group "$RG" --webapp-name "$WEBAPP" --backup-name "xmlbackup-$(date +%s)" --output none echo "=== Créer un compte de stockage (déclenche la détection) ===" az storage account create --name "$STORAGE" --resource-group "$RG" --location "$LOCATION" --sku Standard_LRS --kind StorageV2 --output none echo "=== Créer un serveur SQL (nécessaire pour la règle de pare-feu) ===" az sql server create --name "$SQLSERVER" --resource-group "$RG" --location "$LOCATION" --admin-user "sqladmin" --admin-password "P@ssw0rd1234!" --output none echo "=== Ajouter une règle de pare-feu au serveur SQL (déclenche la détection) ===" az sql server firewall-rule create --resource-group "$RG" --server "$SQLSERVER" --name "AllowMyIP" --start-ip-address "$MY_IP" --end-ip-address "$MY_IP" --output none echo "=== Simulation terminée. Veuillez vérifier les alertes dans Azure Sentinel. ===" -
Commandes de nettoyage :
#!/usr/bin/env bash set -euo pipefail # Les variables doivent correspondre à celles utilisées dans le script de simulation RG="test-rg-..." # Si vous avez conservé les noms exacts de l'exécution précédente, veuillez remplacer les espaces réservés en conséquence. echo "=== Supprimer le groupe de ressources et toutes les ressources contenues ===" az group delete --name "$RG" --yes --no-wait echo "Nettoyage initié."