SOC Prime Bias: Élevé

20 May 2026 22:10 UTC

Comment Storm-2949 a transformé une identité compromise en une violation à l’échelle du cloud

Author Photo
SOC Prime Team linkedin icon Suivre
Comment Storm-2949 a transformé une identité compromise en une violation à l’échelle du cloud
shield icon

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

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 operationName les événements que règle surveille :

    1. Publier l’application Web XML – extrait la configuration de l’application Web (y compris les justificatifs de déploiement).
    2. Créer un nouveau compte de stockage – fournit un conteneur pour la mise en scène des données exfiltrées.
    3. 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 operationName correspondant à 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é."