Anomalous Single Factor Signin
Id | f7c3f5c8-71ea-49ff-b8b3-148f0e346291 |
Rulename | Anomalous Single Factor Signin |
Description | Detects successful signins using single factor authentication where the device, location, and ASN are abnormal. Single factor authentications pose an opportunity to access compromised accounts, investigate these for anomalous occurrencess. Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-devices#non-compliant-device-sign-in |
Severity | Low |
Tactics | InitialAccess |
Techniques | T1078.004 |
Required data connectors | AzureActiveDirectory |
Kind | Scheduled |
Query frequency | 1d |
Query period | 7d |
Trigger threshold | 0 |
Trigger operator | gt |
Source Uri | https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SigninLogs/AnomalousSingleFactorSignin.yaml |
Version | 1.0.4 |
Arm template | f7c3f5c8-71ea-49ff-b8b3-148f0e346291.json |
let known_locations = (SigninLogs
| where TimeGenerated between(ago(7d)..ago(1d))
| where ResultType == 0
| extend LocationDetail = strcat(Location, "-", LocationDetails.state)
| summarize by LocationDetail);
let known_asn = (SigninLogs
| where TimeGenerated between(ago(7d)..ago(1d))
| where ResultType == 0
| summarize by AutonomousSystemNumber);
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == 0
| where isempty(DeviceDetail.deviceId)
| where AuthenticationRequirement == "singleFactorAuthentication"
| extend LocationParsed = parse_json(LocationDetails), DeviceParsed = parse_json(DeviceDetail)
| extend City = tostring(LocationParsed.city), State = tostring(LocationParsed.state)
| extend LocationDetail = strcat(Location, "-", State)
| extend DeviceId = tostring(DeviceParsed.deviceId), DeviceName=tostring(DeviceParsed.displayName), OS=tostring(DeviceParsed.operatingSystem), Browser=tostring(DeviceParsed.browser)
| where AutonomousSystemNumber !in (known_asn) and LocationDetail !in (known_locations)
| project TimeGenerated, Type, UserId, UserDisplayName, UserPrincipalName, IPAddress, Location, State, City, ResultType, ResultDescription, AppId, AppDisplayName, AuthenticationRequirement, ConditionalAccessStatus, ResourceDisplayName, ClientAppUsed, Identity, HomeTenantId, ResourceTenantId, Status, UserAgent, DeviceId, DeviceName, OS, Browser, MfaDetail
| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])
metadata:
support:
tier: Community
author:
name: Pete Bryan
categories:
domains:
- Security - Others
source:
kind: Community
version: 1.0.4
description: |
'Detects successful signins using single factor authentication where the device, location, and ASN are abnormal.
Single factor authentications pose an opportunity to access compromised accounts, investigate these for anomalous occurrencess.
Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-devices#non-compliant-device-sign-in'
query: |
let known_locations = (SigninLogs
| where TimeGenerated between(ago(7d)..ago(1d))
| where ResultType == 0
| extend LocationDetail = strcat(Location, "-", LocationDetails.state)
| summarize by LocationDetail);
let known_asn = (SigninLogs
| where TimeGenerated between(ago(7d)..ago(1d))
| where ResultType == 0
| summarize by AutonomousSystemNumber);
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == 0
| where isempty(DeviceDetail.deviceId)
| where AuthenticationRequirement == "singleFactorAuthentication"
| extend LocationParsed = parse_json(LocationDetails), DeviceParsed = parse_json(DeviceDetail)
| extend City = tostring(LocationParsed.city), State = tostring(LocationParsed.state)
| extend LocationDetail = strcat(Location, "-", State)
| extend DeviceId = tostring(DeviceParsed.deviceId), DeviceName=tostring(DeviceParsed.displayName), OS=tostring(DeviceParsed.operatingSystem), Browser=tostring(DeviceParsed.browser)
| where AutonomousSystemNumber !in (known_asn) and LocationDetail !in (known_locations)
| project TimeGenerated, Type, UserId, UserDisplayName, UserPrincipalName, IPAddress, Location, State, City, ResultType, ResultDescription, AppId, AppDisplayName, AuthenticationRequirement, ConditionalAccessStatus, ResourceDisplayName, ClientAppUsed, Identity, HomeTenantId, ResourceTenantId, Status, UserAgent, DeviceId, DeviceName, OS, Browser, MfaDetail
| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SigninLogs/AnomalousSingleFactorSignin.yaml
entityMappings:
- entityType: Account
fieldMappings:
- columnName: UserPrincipalName
identifier: FullName
- columnName: Name
identifier: Name
- columnName: UPNSuffix
identifier: UPNSuffix
- entityType: IP
fieldMappings:
- columnName: IPAddress
identifier: Address
- entityType: CloudApplication
fieldMappings:
- columnName: AppId
identifier: AppId
- columnName: AppDisplayName
identifier: Name
id: f7c3f5c8-71ea-49ff-b8b3-148f0e346291
triggerThreshold: 0
tags:
- AADSecOpsGuide
name: Anomalous Single Factor Signin
queryPeriod: 7d
requiredDataConnectors:
- dataTypes:
- SigninLogs
connectorId: AzureActiveDirectory
triggerOperator: gt
queryFrequency: 1d
kind: Scheduled
relevantTechniques:
- T1078.004
severity: Low
tactics:
- InitialAccess
{
"$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/f7c3f5c8-71ea-49ff-b8b3-148f0e346291')]",
"kind": "Scheduled",
"name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/f7c3f5c8-71ea-49ff-b8b3-148f0e346291')]",
"properties": {
"alertRuleTemplateName": "f7c3f5c8-71ea-49ff-b8b3-148f0e346291",
"customDetails": null,
"description": "'Detects successful signins using single factor authentication where the device, location, and ASN are abnormal.\n Single factor authentications pose an opportunity to access compromised accounts, investigate these for anomalous occurrencess.\n Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-devices#non-compliant-device-sign-in'\n",
"displayName": "Anomalous Single Factor Signin",
"enabled": true,
"entityMappings": [
{
"entityType": "Account",
"fieldMappings": [
{
"columnName": "UserPrincipalName",
"identifier": "FullName"
},
{
"columnName": "Name",
"identifier": "Name"
},
{
"columnName": "UPNSuffix",
"identifier": "UPNSuffix"
}
]
},
{
"entityType": "IP",
"fieldMappings": [
{
"columnName": "IPAddress",
"identifier": "Address"
}
]
},
{
"entityType": "CloudApplication",
"fieldMappings": [
{
"columnName": "AppId",
"identifier": "AppId"
},
{
"columnName": "AppDisplayName",
"identifier": "Name"
}
]
}
],
"OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/SigninLogs/AnomalousSingleFactorSignin.yaml",
"query": "let known_locations = (SigninLogs\n | where TimeGenerated between(ago(7d)..ago(1d))\n | where ResultType == 0\n | extend LocationDetail = strcat(Location, \"-\", LocationDetails.state)\n | summarize by LocationDetail);\nlet known_asn = (SigninLogs\n | where TimeGenerated between(ago(7d)..ago(1d))\n | where ResultType == 0\n | summarize by AutonomousSystemNumber);\nSigninLogs\n| where TimeGenerated > ago(1d)\n| where ResultType == 0\n| where isempty(DeviceDetail.deviceId)\n| where AuthenticationRequirement == \"singleFactorAuthentication\"\n| extend LocationParsed = parse_json(LocationDetails), DeviceParsed = parse_json(DeviceDetail)\n| extend City = tostring(LocationParsed.city), State = tostring(LocationParsed.state)\n| extend LocationDetail = strcat(Location, \"-\", State)\n| extend DeviceId = tostring(DeviceParsed.deviceId), DeviceName=tostring(DeviceParsed.displayName), OS=tostring(DeviceParsed.operatingSystem), Browser=tostring(DeviceParsed.browser)\n| where AutonomousSystemNumber !in (known_asn) and LocationDetail !in (known_locations)\n| project TimeGenerated, Type, UserId, UserDisplayName, UserPrincipalName, IPAddress, Location, State, City, ResultType, ResultDescription, AppId, AppDisplayName, AuthenticationRequirement, ConditionalAccessStatus, ResourceDisplayName, ClientAppUsed, Identity, HomeTenantId, ResourceTenantId, Status, UserAgent, DeviceId, DeviceName, OS, Browser, MfaDetail\n| extend Name = tostring(split(UserPrincipalName,'@',0)[0]), UPNSuffix = tostring(split(UserPrincipalName,'@',1)[0])\n",
"queryFrequency": "P1D",
"queryPeriod": "P7D",
"severity": "Low",
"subTechniques": [
"T1078.004"
],
"suppressionDuration": "PT1H",
"suppressionEnabled": false,
"tactics": [
"InitialAccess"
],
"tags": [
"AADSecOpsGuide"
],
"techniques": [
"T1078"
],
"templateVersion": "1.0.4",
"triggerOperator": "GreaterThan",
"triggerThreshold": 0
},
"type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
}
]
}