↳ Source GitHubRègle analytiqueHigh

MFA Spamming followed by Successful login

Description

'Identifies MFA Spamming followed by Successful logins and by a successful authentication within a given time window. Default Failure count is 10 and 1 successful login with default Time Window is 5 minutes.'
Type de règle
Scheduled
Version
1.0.4
Statut déclaré
Available
Fréquence
1d
Période analysée
1d
Déclenchement
gt 0

Couverture MITRE déclarée

Sources déclarées

Métadonnées du fichier source. Aucune dépendance déduite du KQL.

Connecteurs

Types de données

Requête KQL

Requête originale, sans modification.

// Filter for sign-in logs ingested within the last day
SigninLogs
| where ingestion_time() > ago(1d)
// Filter for records with AuthenticationRequirement set to multiFactorAuthentication
| where AuthenticationRequirement == "multiFactorAuthentication"
// Extract information from dynamic columns DeviceDetail and LocationDetails
| extend DeviceDetail = todynamic(DeviceDetail), LocationDetails = todynamic(LocationDetails)
// Extract specific attributes from DeviceDetail and LocationDetails
| extend
      OS = tostring(DeviceDetail.operatingSystem),
      Browser = tostring(DeviceDetail.browser),
      State = tostring(LocationDetails.state),
      City = tostring(LocationDetails.city),
      Region = tostring(LocationDetails.countryOrRegion)
// Expand multi-value property AuthenticationDetails into separate records
| mv-expand todynamic(AuthenticationDetails)
// Parse AuthResult from JSON in AuthenticationDetails and convert to string
| extend AuthResult = tostring(parse_json(AuthenticationDetails).authenticationStepResultDetail)
// Summarize data by aggregating statistics for each user, IP, and AuthResult
| summarize FailedAttempts = countif(AuthResult == "MFA denied; user declined the authentication" or AuthResult == "MFA denied; user did not respond to mobile app notification"), SuccessfulAttempts = countif(AuthResult == "MFA successfully completed"), InvolvedOS = make_set(OS, 5), InvolvedBrowser = make_set(Browser), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserPrincipalName, IPAddress, State, City, Region
// Calculate AuthenticationWindow by finding time difference between start and end times
| extend AuthenticationWindow = (EndTime - StartTime)
// Filter for records with more than 10 failed attempts in 5-minute window and at least 1 successful attempt
| where FailedAttempts > 10 and AuthenticationWindow <= 5m and SuccessfulAttempts >= 1
// Extract user's name and UPN suffix using split function
| extend Name = tostring(split(UserPrincipalName, '@', 0)[0]), UPNSuffix = tostring(split(UserPrincipalName, '@', 1)[0])

Entités déclarées

AccountIP

Contenus associés

Liens établis à partir des identifiants déclarés et des manifests des solutions.

Traçabilité de la source

GitHub

Les valeurs affichées proviennent des fichiers du dépôt Azure/Azure-Sentinel. Elles décrivent le modèle publié, pas la configuration de votre workspace.

Identifiant source
a8cc6d5c-4e7e-4b48-b4ac-d8a116c62a8b
Autres fichiers source 2Solutions/Microsoft Entra ID/Analytic Rules/MFASpammingfollowedbySuccessfullogin.yamlsource ↗Solutions/Microsoft Entra ID/Data/Solution_AAD.jsonsolution-membership ↗
GSTEP / SUIVI DU CATALOGUE

Ajouté au catalogue : 16 sept. 2026 · 05:49 UTC
Dernier changement observé : 16 sept. 2026 · 05:49 UTC

Dates de synchronisation GSTEP, distinctes des dates de publication du contenu source.