↳ Source GitHubRègle analytiqueHigh

Account Created and Deleted in Short Timeframe

Description

'Search for user principal name (UPN) events. Look for accounts created and then deleted within 7 days. Attackers may create an account for their use, and then remove the account when no longer needed. Ref : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#short-lived-account'
Type de règle
Scheduled
Version
1.1.2
Statut déclaré
Available
Fréquence
1h
Période analysée
7d
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.

let queryfrequency = 1h;
let queryperiod = 7d; // Increased queryperiod to 7 days to mitigate timing-based bypasses
AuditLogs
| where TimeGenerated > ago(queryfrequency)
| where OperationName =~ "Delete user"
| mv-apply TargetResource = TargetResources on 
  (
      where TargetResource.type == "User"
      // Normalize TargetUserPrincipalName by removing optional 32-char hex prefixes and underscores
      // Making extraction case-insensitive, and converting the result to lowercase for consistency
      | extend TargetUserPrincipalName = tolower(extract(@"(?i)([a-f0-9]{32})?_?(.*)", 2, tostring(TargetResource.userPrincipalName)))
      // Standardize UserId to ensure consistent, immutable identification
      | extend UserId = tostring(TargetResource.id)
  )
| extend DeletedByApp = tostring(InitiatedBy.app.displayName),
DeletedByAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId),
DeletedByUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName),
DeletedByAadUserId = tostring(InitiatedBy.user.id),
DeletedByIPAddress = tostring(InitiatedBy.user.ipAddress)
| project Deletion_TimeGenerated = TimeGenerated, TargetUserPrincipalName, UserId, DeletedByApp, DeletedByAppServicePrincipalId, DeletedByUserPrincipalName, DeletedByAadUserId, DeletedByIPAddress, 
Deletion_AdditionalDetails = AdditionalDetails, Deletion_InitiatedBy = InitiatedBy, Deletion_TargetResources = TargetResources
| join kind=inner (
    AuditLogs
    | where TimeGenerated > ago(queryperiod)
    | where OperationName =~ "Add user"      
    | mv-apply TargetResource = TargetResources on 
      (
          where TargetResource.type == "User"
          // Normalize TargetUserPrincipalName by removing optional 32-char hex prefixes and underscores
          // Making extraction case-insensitive, and converting the result to lowercase for consistency
          | extend TargetUserPrincipalName = tolower(extract(@"(?i)([a-f0-9]{32})?_?(.*)", 2, tostring(TargetResource.userPrincipalName)))
          // Standardize UserId to ensure consistent, immutable identification
          | extend UserId = tostring(TargetResource.id)
      )
    | project-rename Creation_TimeGenerated = TimeGenerated
) on UserId
| extend TimeDelta = Deletion_TimeGenerated - Creation_TimeGenerated
| where  TimeDelta between (time(0s) .. queryperiod)
| extend CreatedByApp = tostring(InitiatedBy.app.displayName),
CreatedByAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId),
CreatedByUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName),
CreatedByAadUserId = tostring(InitiatedBy.user.id),
CreatedByIPAddress = tostring(InitiatedBy.user.ipAddress)
| project Creation_TimeGenerated, Deletion_TimeGenerated, TimeDelta, UserId, TargetUserPrincipalName, DeletedByApp, DeletedByAppServicePrincipalId, DeletedByUserPrincipalName, DeletedByAadUserId, DeletedByIPAddress, 
CreatedByApp, CreatedByAppServicePrincipalId, CreatedByUserPrincipalName, CreatedByAadUserId, CreatedByIPAddress, Creation_AdditionalDetails = AdditionalDetails, Creation_InitiatedBy = InitiatedBy, Creation_TargetResources = TargetResources, Deletion_AdditionalDetails, Deletion_InitiatedBy, Deletion_TargetResources
| extend TargetName = tostring(split(TargetUserPrincipalName,'@',0)[0]), TargetUPNSuffix = tostring(split(TargetUserPrincipalName,'@',1)[0])
| extend CreatedByName = tostring(split(CreatedByUserPrincipalName,'@',0)[0]), CreatedByUPNSuffix = tostring(split(CreatedByUserPrincipalName,'@',1)[0])
| extend DeletedByName = tostring(split(DeletedByUserPrincipalName,'@',0)[0]), DeletedByUPNSuffix = tostring(split(DeletedByUserPrincipalName,'@',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
bb616d82-108f-47d3-9dec-9652ea0d3bf6
Autres fichiers source 3Solutions/Microsoft Entra ID/Analytic Rules/AccountCreatedandDeletedinShortTimeframe.yamlsource ↗Detections/AuditLogs/AccountCreatedandDeletedinShortTimeframe.yamlmigration-note ↗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.