SOC Prime Bias: Critical

20 Oct 2026 12:39 UTC

Identifiants de fournisseur ConnectWise SkyKick utilisés dans des attaques Microsoft 365

Author Photo
SOC Prime Team linkedin icon Suivre
Identifiants de fournisseur ConnectWise SkyKick utilisés dans des attaques Microsoft 365
shield icon

Detection stack

  • AIDR
  • Alert
  • ETL
  • Query

Résumé

Un secret d’API Microsoft 365 compromis, associé à ConnectWise Cloud Backup, anciennement SkyKick, a été abusé par des acteurs malveillants pour accéder sans autorisation à des environnements M365 de clients. Les attaquants ont tiré parti des permissions étendues de l’application pour accéder à Exchange Online, Microsoft Teams et SharePoint Online. L’activité incluait à la fois des demandes de jeton automatisées et des opérations de post-exploitation manuelles.

Enquête

Huntress a identifié un abus des principaux de service ConnectWise via les journaux de connexion Microsoft 365, y compris un accès non autorisé depuis l’adresse IP du fournisseur d’hébergement 144.172.64.128 et l’espace privé Azure IPv6. L’enquête a révélé que les attaquants ont utilisé des identifiants compromis pour assigner des rôles de répertoire tels qu’Administrateur Global et ajouter de nouveaux secrets de client à d’autres applications de confiance pour persistance. L’activité a également montré un mouvement scripté à travers les locataires dans l’ordre GUID et des motifs distincts d’User-Agent.

Atténuation

Les organisations doivent immédiatement désactiver les IDs d’application ConnectWise Cloud Backup et ConnectWise Cloud Management concernés au sein de leurs locataires Microsoft 365. Désactiver plutôt que supprimer les applications est important pour préserver la gestion des consentements. Les équipes de sécurité doivent également auditer toutes les connexions de principaux de service et revoir les identifiants d’application pour toute addition inattendue créée depuis le 13 octobre.

Réponse

Lorsqu’une activité suspecte est identifiée, les organisations doivent examiner les journaux d’audit Entra pour Ajouter un membre à un rôle, Mise à jour de l'application, et Ajouter les identifiants du principal de service événements. Les équipes de sécurité doivent valider les chaînes d’User-Agent associées et distinguer l’activité légitime du fournisseur, comme kiota-dotnet, des outils des attaquants, dont Python-urllib et curl. Enfin, examinez tous les secrets de client et certificats à travers les applications d’entreprise et supprimez les identifiants non autorisés.

Flux d’attaque

Nous mettons toujours à jour cette partie.

Détections

Ajouter un utilisateur à un rôle d’admin (via office365)

Équipe SOC Prime
19 oct. 2026

Mise à jour des identifiants du compte de principal de service (via azuread)

Microsoft, Équipe SOC Prime
19 oct. 2026

Un rôle à haute privilège a été assigné (via azuread)

Équipe SOC Prime
19 oct. 2026

IOC (SourceIP) à détecter : Identifiants de fournisseur ConnectWise (SkyKick) abusés dans les attaques M365

Règles IA SOC Prime
19 oct. 2026

IOC (DestinationIP) à détecter : Identifiants de fournisseur ConnectWise (SkyKick) abusés dans les attaques M365

Règles IA SOC Prime
19 oct. 2026

Détection de modifications non autorisées dans M365 via Python-urllib [Journaux d’activité Azure]

Règles IA SOC Prime
19 oct. 2026

Utilisation non autorisée des jetons Microsoft Graph dans M365 via les applications ConnectWise [Journaux d’audit Azure]

Règles IA SOC Prime
19 oct. 2026

Exécution de simulation

  • Récit de l’attaque & Commandes : L’adversaire a réussi à accéder à un principal de service avec des permissions limitées. Pour atteindre la persistance et le contrôle total de l’environnement, l’attaquant exécute un script Python. Le script cible l’API Microsoft Graph pour : 1) ajouter le principal de service compromis à un rôle de répertoire hautement privilégié (par exemple, Administrateur Global ou Administrateur de Rôle Privilégié), et 2) ajouter un nouveau secret de client au principal de service. L’attaquant utilise la bibliothèque urllib en Python 3.12, qui utilise par défaut l’ User-Agent Python-urllib/3.12 , fournissant le hook de télémétrie spécifique requis par la règle de détection.

  • Script de test de régression :

    import urllib.request
    import json
    
    # NOTE : Ce script est une simulation de la structure d'appel de l'API. 
    # Dans un environnement réel, un jeton Bearer OAuth2 valide serait requis.
    # Ce script est conçu pour déclencher la logique de détection 'UserAgent' et 'OperationName'.
    
    url_cible = "https://graph.microsoft.com/v1.0/directoryRoles"
    jeton_acces = "SIMULATED_TOKEN"
    
    en-têtes = {
        "Authorization": f"Bearer {jeton_acces}",
        "Content-Type": "application/json"
    }
    
    # Cet User-Agent spécifique est le déclencheur pour la règle de détection
    user_agent = "Python-urllib/3.12"
    
    # Simulez "Ajouter un membre à un rôle"
    charge_utile = {
        "roleId": "target-role-guid",
        "principalId": "attacker-service-principal-guid"
    }
    
    print(f"[*] Simulation d'une modification non autorisée de rôle en utilisant {user_agent}...")
    
    try:
        req = urllib.request.Request(
            url_cible, 
            data=json.dumps(charge_utile).encode('utf-8'), 
            headers=en-têtes, 
            method='POST'
        )
        req.add_header('User-Agent', user_agent)
    
        # Dans un vrai test, cela appellerait l'API réelle. 
        # Pour fins de simulation, nous supposons que l'appel API est réussi pour générer le journal.
        print("[+] Requête envoyée. Vérifiez les journaux d'audit Azure pour 'Ajouter un membre à un rôle' avec User-Agent : Python-urllib/3.12")
    except Exception as e:
        print(f"[-] Échec de la simulation : {e}")
  • Commandes de nettoyage :

    # Un nettoyage manuel est requis dans M365 car il s'agit de modifications au niveau des identités.
    # 1. Supprimer l'assignation de rôle ajoutée :
    # Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <ID> -DirectoryRoleMemberId <ID>
    
    # 2. Supprimer les identifiants du principal de service ajoutés :
    # Remove-MgServicePrincipalPassword -ServicePrincipalId <ID> -PasswordId <ID>