Analyse télémétrique du password spraying & Brute-force
Malgré la promotion croissante des architectures sans mot de passe (passwordless), les mots de passe demeurent le facteur d’authentification principal pour l’immense majorité des entreprises sous Microsoft 365. Si les attaques par force brute traditionnelles (tester rapidement des milliers de mots de passe sur une même cible) sont neutralisées par les mécanismes d’Entra Smart Lockout, le Password Spraying reste l’un des vecteurs d’accès initial les plus dévastateurs et répandus.
Dans une attaque par password spraying, l’attaquant inverse la logique de force brute : au lieu de tester de nombreux mots de passe contre un compte unique, il teste un mot de passe unique et probable (ex. Automne2026!, Entreprise123#) contre des milliers d’identités du tenant sur une période étendue. En répartissant les requêtes à travers des proxys résidentiels rotatifs et en ciblant les protocoles d’authentification héritée, les cybercriminels échappent aux seuils d’alerte et neutralisent les défenses périmétriques.
Ce guide propose une dissection technique et forensique du password spraying sous Entra ID, analyse les méthodes d’énumération préalable d’utilisateurs, détaille la signification exacte des codes d’erreur de connexion et fournit des requêtes de détection KQL de niveau production.
1. Mécanismes d’attaque : force Brute vs password spraying distribué
Section intitulée « 1. Mécanismes d’attaque : force Brute vs password spraying distribué »graph TD subgraph "Force Brute Verticale (Bloquée par Smart Lockout)" ATT1[Attaquant] -->|1 000 Mots de passe / 1 Utilisateur| USER_A[alice@target.com] USER_A --> LOCKOUT[Smart Lockout Déclenché<br/>ResultType : 50053<br/>IP Bloquée / Compte Verrouillé] end
subgraph "Password Spraying Horizontal (Furtif)" ATT2[Réseau de Proxys Résidentiels] -->|Mot de passe unique : Printemps2026!| POOL{Annuaire Utilisateurs} POOL -->|Tentative 1 / IP 1| U1[user1@target.com] POOL -->|Tentative 1 / IP 2| U2[user2@target.com] POOL -->|Tentative 1 / IP 3| U3[user3@target.com] POOL -->|Tentative 1 / IP N| UN[userN@target.com] U1 & U2 & U3 & UN --> IDP[Entra ID Security Token Service] IDP -->|Seuils Non Dépassés| STEALTH[Contourne le Verrouillage et le Blocage d'IP] endPourquoi le password spraying échappe aux détections :
Section intitulée « Pourquoi le password spraying échappe aux détections : »- Basse fréquence par compte : tester un mot de passe toutes les 2 à 4 heures par identité n’atteint jamais les seuils d’Entra ID Smart Lockout (qui verrouille généralement après 10 échecs consécutifs sur une fenêtre glissante).
- Rotation des adresses IP résidentielles : les outils d’attaque modernes acheminent chaque requête via des réseaux de proxys résidentiels commerciaux, garantissant qu’aucune adresse IP source n’émet plus de 1 ou 2 tentatives.
- Ciblage des protocoles hérités (legacy auth) : les attaquants dirigent leurs attaques vers les points d’entrée de messagerie anciens (IMAP4, POP3, ActiveSync, SMTP AUTH) qui ne supportent pas les invites MFA interactives ni les contrôles de conformité de terminal de l’Accès Conditionnel.
2. Reconnaissance préalable : l’API d’énumération GetCredentialType
Section intitulée « 2. Reconnaissance préalable : l’API d’énumération GetCredentialType »Avant de déclencher une campagne de spray, les cybercriminels filtrent leur dictionnaire d’adresses afin d’exclure les identifiants inexistants, évitant ainsi de générer du bruit inutile ou des codes d’erreur d’utilisateur inconnu.
2.1 sondage du Point de terminaison des métadonnées
Section intitulée « 2.1 sondage du Point de terminaison des métadonnées »Entra ID expose une API publique et non authentifiée, exploitée par le portail officiel de connexion Microsoft pour déterminer la personnalisation graphique du tenant, le mode de fédération et les options d’authentification :
POST /common/GetCredentialType?mkt=fr-FR HTTP/1.1Host: login.microsoftonline.comContent-Type: application/json
{ "username": "victime@target.com", "isOtherIdpSupported": true, "checkPhones": false, "isRemoteNGCSupported": true, "isCookieBannerShown": false, "isFidoSupported": true, "country": "FR", "forceotclogin": false, "isExternalFederationDisallowed": false, "isRemoteConnectSupported": false, "federationFlags": 0, "isSignup": false, "flowToken": "..."}2.2 interprétation forensique du paramètre IfExistsResult
Section intitulée « 2.2 interprétation forensique du paramètre IfExistsResult »La réponse JSON contient un champ entier, IfExistsResult, qui révèle l’existence réelle du compte sans consigner la moindre trace dans les SigninLogs :
Valeur d’IfExistsResult | État du Compte dans Entra ID | Conséquence Forensique |
|---|---|---|
0 | L’utilisateur existe (compte valide) | Le compte est actif dans l’annuaire du tenant. Ajouté à la liste de spray de l’attaquant. |
1 | L’utilisateur n’existe pas | L’identifiant est erroné. Écarté par l’attaquant pour ne pas créer d’anomalies. |
5 | Requête régulée (throttled) | Le STS Microsoft a temporairement freiné l’adresse IP de l’attaquant. |
6 | Domaine fédéré | Le tenant délègue l’authentification à un STS local (ADFS/PingFederate). |
3. Décodage télémétrique des codes d’erreur entra ID
Section intitulée « 3. Décodage télémétrique des codes d’erreur entra ID »Lors d’une campagne de password spraying, chaque tentative est consignée dans la table SigninLogs. La maîtrise des codes ResultType permet à l’analyste de distinguer un mot de passe erroné anodin d’une découverte de mot de passe valide par l’attaquant :
graph TD ATT[Tentative de Spray Reçue par le STS] --> EVAL{Vérification des Identifiants}
EVAL -->|Mot de Passe Incorrect| RT_50126[ResultType : 50126<br/>Identifiant ou mot de passe invalide] EVAL -->|Compte Verrouillé| RT_50053[ResultType : 50053<br/>Smart Lockout déclenché] EVAL -->|Compte Inexistant| RT_50056[ResultType : 50056<br/>Utilisateur absent du tenant]
EVAL -->|Mot de Passe Correct !| MFA_CHECK{Le Compte Exige-t-il le MFA ?} MFA_CHECK -->|Oui| RT_50076[ResultType : 50076<br/>SIGNAL FORENSIQUE CRITIQUE :<br/>Mot de passe valide, redirigé vers MFA !] MFA_CHECK -->|Non / Protocole Hérité| RT_0[ResultType : 0<br/>SUCCÈS : Prise de contrôle du compte]3.1 codes d’erreur fondamentaux pour l’analyse DFIR
Section intitulée « 3.1 codes d’erreur fondamentaux pour l’analyse DFIR »ResultType | Description de l’Erreur | Signification en Investigation |
|---|---|---|
0 | Succès | Authentification réussie. Si précédé d’échecs 50126, prouve la réussite d’une tentative de spray. |
50126 | Identifiant OU mot de passe invalide | Échec classique d’authentification. Trace de base du password spraying lorsqu’elle est distribuée sur de multiples comptes. |
50053 | Compte verrouillé (smart lockout) | Le seuil d’échecs a été dépassé. Indique un spray agressif ou simultané. |
50056 | L’utilisateur n’existe pas | Révèle une attaque sans énumération préalable (utilisation d’un dictionnaire non qualifié). |
50076 | Redirigé vers le MFA | VALEUR FORENSIQUE MAXIMALE. Prouve que l’attaquant a trouvé le bon mot de passe, mais a été arrêté par l’exigence MFA. Endiguement immédiat requis ! |
50079 | Inscription MFA requise | L’attaquant a trouvé le mot de passe valide d’un compte sans MFA enrôlé ; il peut enrôler sa propre méthode ! |
50074 | Échec d’authentification forte | Le challenge MFA a été émis (push/SMS) mais refusé ou ignoré par l’utilisateur légitime. |
53003 | Bloqué par l’accès conditionnel | Les identifiants étaient valides, mais une règle (pays, équipement non conforme) a bloqué l’accès. |
4. Requêtes de chasse KQL en production
Section intitulée « 4. Requêtes de chasse KQL en production »4.1 détection du password spraying distribué multi-comptes
Section intitulée « 4.1 détection du password spraying distribué multi-comptes »Identifier les cas où de multiples comptes distincts subissent des échecs d’authentification (50126) sur une fenêtre de 2 heures depuis différentes adresses IP partageant des caractéristiques communes :
let ThresholdFailedUsers = 15; // Nombre minimal d'utilisateurs distincts cibléslet TimeWindow = 2h;SigninLogs| where TimeGenerated >= ago(24h)| where ResultType in (50126, 50053) // Mot de passe invalide ou compte verrouillé| summarize FailedAttemptCount = count(), TargetedUsers = make_set(UserPrincipalName), TargetedUserCount = dcount(UserPrincipalName), IPAddresses = make_set(IPAddress), IPCount = dcount(IPAddress), Locations = make_set(Location), AppNames = make_set(AppDisplayName), UserAgents = make_set(UserAgent) by bin(TimeGenerated, TimeWindow), ClientAppUsed| where TargetedUserCount >= ThresholdFailedUsers| project TimeGenerated, ClientAppUsed, TargetedUserCount, FailedAttemptCount, IPCount, AppNames, UserAgents, TargetedUsers, IPAddresses| sort by TargetedUserCount desc4.2 détection de la découverte d’un mot de passe valide (50126 suivi de 50076 OU 0)
Section intitulée « 4.2 détection de la découverte d’un mot de passe valide (50126 suivi de 50076 OU 0) »Repérer spécifiquement les comptes pour lesquels un attaquant a réussi à identifier le mot de passe valide au cours d’une campagne :
let SprayedUsers = SigninLogs| where TimeGenerated >= ago(24h)| where ResultType == 50126| distinct UserPrincipalName;SigninLogs| where TimeGenerated >= ago(24h)| where UserPrincipalName in (SprayedUsers)| where ResultType in (0, 50076, 50079) // Succès ou mot de passe valide exigeant le MFA| project TimeGenerated, UserPrincipalName, IPAddress, Location, ResultType, ResultDescription, AppDisplayName, ClientAppUsed, UserAgent| sort by TimeGenerated asc4.3 chasse au spraying sur protocoles d’authentification héritée
Section intitulée « 4.3 chasse au spraying sur protocoles d’authentification héritée »Repérer les attaques ciblant les protocoles anciens qui court-circuitent les mécanismes modernes d’authentification :
SigninLogs| where TimeGenerated >= ago(7d)| where ClientAppUsed in ("IMAP4", "POP3", "SMTP", "Exchange ActiveSync", "MAPI over HTTP", "Autodiscover")| where ResultType in (50126, 50053, 0)| summarize Attempts = count(), SuccessfulLogins = countif(ResultType == 0), FailedLogins = countif(ResultType != 0), DistinctUsers = dcount(UserPrincipalName), TargetedAccounts = make_set(UserPrincipalName) by IPAddress, Location, AutonomousSystemNumber, ClientAppUsed, bin(TimeGenerated, 1h)| where DistinctUsers >= 5| sort by DistinctUsers desc5. Stratégie de durcissement architectural et neutralisation
Section intitulée « 5. Stratégie de durcissement architectural et neutralisation »Pour neutraliser durablement les attaques par password spraying, les équipes de sécurité doivent combiner plusieurs couches défensives :
graph TD DEF[Architecture Anti-Password Spray] --> L1[1. Bloquer l'Authentification Héritée<br/>Accès Conditionnel : Applications clientes = Autres / ActiveSync] DEF --> L2[2. Durcir Entra Smart Lockout<br/>Seuil de verrouillage = 5 / Durée = 15 min / Analyse comportementale IP] DEF --> L3[3. Imposer un MFA Résistant au Phishing<br/>Exiger FIDO2 / Windows Hello via Authentication Strengths] DEF --> L4[4. Transition vers le Passwordless<br/>Clés FIDO2, Microsoft Authenticator sans mot de passe]- Blocage définitif de l’authentification héritée :
- Déployer une règle d’Accès Conditionnel bloquant l’accès pour tous les clients classés dans
"Clients Exchange ActiveSync"et"Autres clients"(IMAP, POP, SMTP).
- Déployer une règle d’Accès Conditionnel bloquant l’accès pour tous les clients classés dans
- Optimisation d’entra ID smart lockout :
- Dans le portail Entra (
Protection$\rightarrow$Méthodes d'authentification$\rightarrow$Protection par mot de passe), fixer le seuil de verrouillage à 5 ou 10 tentatives. Smart Lockout distingue les adresses IP familières des IP d’attaquants, bloquant ces dernières sans pénaliser l’utilisateur légitime.
- Dans le portail Entra (
- Migration vers l’authentification passwordless :
- La suppression complète du mot de passe anéantit définitivement le modèle économique et opérationnel du password spraying.
6. Maillage interne & navigation
Section intitulée « 6. Maillage interne & navigation »- Fiche précédente : 23. Attaques par Consentement OAuth & Phishing d’Application
- Fiche suivante : 25. Abus du Device Code Flow OAuth & Détournement de Jetons
- Fiches complémentaires :