Account Created and Deleted in Short Timeframe
Id | bb616d82-108f-47d3-9dec-9652ea0d3bf6 |
Rulename | Account Created and Deleted in Short Timeframe |
Description | Search for user principal name (UPN) events. Look for accounts created and then deleted in under 24 hours. 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 |
Severity | High |
Tactics | InitialAccess |
Techniques | T1078.004 |
Required data connectors | AzureActiveDirectory |
Kind | Scheduled |
Query frequency | 1h |
Query period | 1d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AccountCreatedandDeletedinShortTimeframe.yaml |
Version | 1.1.0 |
Arm template | bb616d82-108f-47d3-9dec-9652ea0d3bf6.json |
let queryfrequency = 1h;
let queryperiod = 1d;
AuditLogs
| where TimeGenerated > ago(queryfrequency)
| where OperationName =~ "Delete user"
| mv-apply TargetResource = TargetResources on
(
where TargetResource.type == "User"
| extend TargetUserPrincipalName = extract(@'([a-f0-9]{32})?(.*)', 2, tostring(TargetResource.userPrincipalName))
)
| 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, 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"
| extend TargetUserPrincipalName = trim(@'"',tostring(TargetResource.userPrincipalName))
)
| project-rename Creation_TimeGenerated = TimeGenerated
) on TargetUserPrincipalName
| 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, 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])
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AccountCreatedandDeletedinShortTimeframe.yaml
status: Available
id: bb616d82-108f-47d3-9dec-9652ea0d3bf6
query: |
let queryfrequency = 1h;
let queryperiod = 1d;
AuditLogs
| where TimeGenerated > ago(queryfrequency)
| where OperationName =~ "Delete user"
| mv-apply TargetResource = TargetResources on
(
where TargetResource.type == "User"
| extend TargetUserPrincipalName = extract(@'([a-f0-9]{32})?(.*)', 2, tostring(TargetResource.userPrincipalName))
)
| 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, 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"
| extend TargetUserPrincipalName = trim(@'"',tostring(TargetResource.userPrincipalName))
)
| project-rename Creation_TimeGenerated = TimeGenerated
) on TargetUserPrincipalName
| 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, 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])
tags:
- AADSecOpsGuide
description: |
'Search for user principal name (UPN) events. Look for accounts created and then deleted in under 24 hours. 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'
name: Account Created and Deleted in Short Timeframe
relevantTechniques:
- T1078.004
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: TargetUserPrincipalName
- identifier: Name
columnName: TargetName
- identifier: UPNSuffix
columnName: TargetUPNSuffix
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: CreatedByUserPrincipalName
- identifier: Name
columnName: CreatedByName
- identifier: UPNSuffix
columnName: CreatedByUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: CreatedByAadUserId
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: DeletedByUserPrincipalName
- identifier: Name
columnName: DeletedByName
- identifier: UPNSuffix
columnName: DeletedByUPNSuffix
- entityType: Account
fieldMappings:
- identifier: AadUserId
columnName: DeletedByAadUserId
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CreatedByIPAddress
- entityType: IP
fieldMappings:
- identifier: Address
columnName: DeletedByIPAddress
triggerThreshold: 0
severity: High
requiredDataConnectors:
- dataTypes:
- SigninLogs
connectorId: AzureActiveDirectory
queryFrequency: 1h
queryPeriod: 1d
version: 1.1.0
kind: Scheduled
tactics:
- InitialAccess
triggerOperator: gt
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspace": {
"type": "String"
}
},
"resources": [
{
"apiVersion": "2024-01-01-preview",
"id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/bb616d82-108f-47d3-9dec-9652ea0d3bf6')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/bb616d82-108f-47d3-9dec-9652ea0d3bf6')]",
"properties": {
"alertRuleTemplateName": "bb616d82-108f-47d3-9dec-9652ea0d3bf6",
"customDetails": null,
"description": "'Search for user principal name (UPN) events. Look for accounts created and then deleted in under 24 hours. Attackers may create an account for their use, and then remove the account when no longer needed.\nRef : https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#short-lived-account'\n",
"displayName": "Account Created and Deleted in Short Timeframe",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "TargetUserPrincipalName",
"identifier": "FullName"
},
{
"columnName": "TargetName",
"identifier": "Name"
},
{
"columnName": "TargetUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "CreatedByUserPrincipalName",
"identifier": "FullName"
},
{
"columnName": "CreatedByName",
"identifier": "Name"
},
{
"columnName": "CreatedByUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "CreatedByAadUserId",
"identifier": "AadUserId"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "DeletedByUserPrincipalName",
"identifier": "FullName"
},
{
"columnName": "DeletedByName",
"identifier": "Name"
},
{
"columnName": "DeletedByUPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "DeletedByAadUserId",
"identifier": "AadUserId"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "CreatedByIPAddress",
"identifier": "Address"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "DeletedByIPAddress",
"identifier": "Address"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/Microsoft Entra ID/Analytic Rules/AccountCreatedandDeletedinShortTimeframe.yaml",
"query": "let queryfrequency = 1h;\nlet queryperiod = 1d;\nAuditLogs\n| where TimeGenerated > ago(queryfrequency)\n| where OperationName =~ \"Delete user\"\n| mv-apply TargetResource = TargetResources on \n (\n where TargetResource.type == \"User\"\n | extend TargetUserPrincipalName = extract(@'([a-f0-9]{32})?(.*)', 2, tostring(TargetResource.userPrincipalName))\n )\n| extend DeletedByApp = tostring(InitiatedBy.app.displayName),\nDeletedByAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId),\nDeletedByUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName),\nDeletedByAadUserId = tostring(InitiatedBy.user.id),\nDeletedByIPAddress = tostring(InitiatedBy.user.ipAddress)\n| project Deletion_TimeGenerated = TimeGenerated, TargetUserPrincipalName, DeletedByApp, DeletedByAppServicePrincipalId, DeletedByUserPrincipalName, DeletedByAadUserId, DeletedByIPAddress, \nDeletion_AdditionalDetails = AdditionalDetails, Deletion_InitiatedBy = InitiatedBy, Deletion_TargetResources = TargetResources\n| join kind=inner (\n AuditLogs\n | where TimeGenerated > ago(queryperiod)\n | where OperationName =~ \"Add user\" \n | mv-apply TargetResource = TargetResources on \n (\n where TargetResource.type == \"User\"\n | extend TargetUserPrincipalName = trim(@'\"',tostring(TargetResource.userPrincipalName))\n )\n | project-rename Creation_TimeGenerated = TimeGenerated\n) on TargetUserPrincipalName\n| extend TimeDelta = Deletion_TimeGenerated - Creation_TimeGenerated\n| where TimeDelta between (time(0s) .. queryperiod)\n| extend CreatedByApp = tostring(InitiatedBy.app.displayName),\nCreatedByAppServicePrincipalId = tostring(InitiatedBy.app.servicePrincipalId),\nCreatedByUserPrincipalName = tostring(InitiatedBy.user.userPrincipalName),\nCreatedByAadUserId = tostring(InitiatedBy.user.id),\nCreatedByIPAddress = tostring(InitiatedBy.user.ipAddress)\n| project Creation_TimeGenerated, Deletion_TimeGenerated, TimeDelta, TargetUserPrincipalName, DeletedByApp, DeletedByAppServicePrincipalId, DeletedByUserPrincipalName, DeletedByAadUserId, DeletedByIPAddress, \nCreatedByApp, CreatedByAppServicePrincipalId, CreatedByUserPrincipalName, CreatedByAadUserId, CreatedByIPAddress, Creation_AdditionalDetails = AdditionalDetails, Creation_InitiatedBy = InitiatedBy, Creation_TargetResources = TargetResources, Deletion_AdditionalDetails, Deletion_InitiatedBy, Deletion_TargetResources\n| extend TargetName = tostring(split(TargetUserPrincipalName,'@',0)[0]), TargetUPNSuffix = tostring(split(TargetUserPrincipalName,'@',1)[0])\n| extend CreatedByName = tostring(split(CreatedByUserPrincipalName,'@',0)[0]), CreatedByUPNSuffix = tostring(split(CreatedByUserPrincipalName,'@',1)[0])\n| extend DeletedByName = tostring(split(DeletedByUserPrincipalName,'@',0)[0]), DeletedByUPNSuffix = tostring(split(DeletedByUserPrincipalName,'@',1)[0])\n",
"queryFrequency": "PT1H",
"queryPeriod": "P1D",
"severity": "High",
"status": "Available",
"subTechniques": [
"T1078.004"
],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"InitialAccess"
],
"tags": [
"AADSecOpsGuide"
],
"techniques": [
"T1078"
],
"templateVersion": "1.1.0",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}