Service Principal authentication attempts from a new country may indicate credential compromise or reconnaissance by an adversary seeking to establish persistent access. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify potential lateral movement or unauthorized access attempts early.
KQL Query
let known_locations = (
AADServicePrincipalSignInLogs
| where TimeGenerated between(ago(14d)..ago(1d))
| where ResultType == 0
| summarize by Location);
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(1d)
| where ResultType != 50126
| where Location !in (known_locations)
| extend City = tostring(parse_json(LocationDetails).city)
| extend State = tostring(parse_json(LocationDetails).state)
| extend Place = strcat(City, " - ", State)
| extend Result = strcat(tostring(ResultType), " - ", ResultDescription)
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), make_set(Result), make_set(IPAddress), make_set(Place) by ServicePrincipalName, Location
id: 1baaaf00-655f-4de9-8ff8-312e902cda71
name: Service Principal Authentication Attempt from New Country
description: |
'Detects when there is a Service Principal login attempt from a country that has not seen a successful login in the previous 14 days.
Threat actors may attempt to authenticate with credentials from compromised accounts - monitoring attempts from anomalous locations may help identify these attempts.
Authentication attempts should be investigated to ensure the activity was legitimate and if there is other similar activity.
Ref: https://docs.microsoft.com/azure/active-directory/fundamentals/security-operations-user-accounts#monitoring-for-failed-unusual-sign-ins'
severity: Medium
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AADServicePrincipalSignInLogs
queryFrequency: 1d
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
- InitialAccess
relevantTechniques:
- T1078.004
tags:
- AADSecOpsGuide
query: |
let known_locations = (
AADServicePrincipalSignInLogs
| where TimeGenerated between(ago(14d)..ago(1d))
| where ResultType == 0
| summarize by Location);
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(1d)
| where ResultType != 50126
| where Location !in (known_locations)
| extend City = tostring(parse_json(LocationDetails).city)
| extend State = tostring(parse_json(LocationDetails).state)
| extend Place = strcat(City, " - ", State)
| extend Result = strcat(tostring(ResultType), " - ", ResultDescription)
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), make_set(Result), make_set(IPAddress), make_set(Place) by ServicePrincipalName, Location
entityMappings:
- entityType: Account
fieldMappings:
- identifier: Name
columnName: ServicePrincipalName
version: 1.0.1
kind: Scheduled
metadata:
source:
kind: Community
author:
name: Pete Bryan
support:
tier: Community
categories:
domains: [ "Security - Others", "Identity" ]
Scenario: Scheduled Job Execution from a New Country
Description: A legitimate scheduled job (e.g., Azure DevOps pipeline, Jenkins job, or SQL Server Agent job) runs from a new geographic location due to a recent infrastructure change.
Filter/Exclusion: where AccountType == "ServicePrincipal" and RequestedResource == "https://management.azure.com/" or check for known job execution IPs in the environment.
Scenario: Admin Task Execution from a New Country
Description: An administrator performs a routine task (e.g., Azure CLI command, PowerShell script, or Azure Portal activity) from a new country due to remote access or travel.
Filter/Exclusion: where AccountType == "ServicePrincipal" and Activity == "Azure Portal Login" or use IP whitelisting for known admin IPs.
Scenario: Azure Automation Runbook Execution from a New Country
Description: A legitimate Azure Automation runbook is executed from a new geographic location due to a recent deployment or regional shift.
Filter/Exclusion: where AccountType == "ServicePrincipal" and ResourceProvider == "Microsoft.Automation/automationAccounts" or check for known runbook execution patterns.
Scenario: Backup or Sync Job from a New Country
Description: A backup or sync job (e.g., Azure Backup, Veeam, or rsync) runs from a new country due to a new data center or regional configuration.
Filter/Exclusion: where AccountType == "ServicePrincipal" and Activity == "Backup" or "Sync" or use known backup IP ranges.
Scenario: Third-Party Service Integration from a New Country
Description: A third-party service (e.g., Okta, Azure AD Connect, or a SaaS tool) authenticates from a new country due to a global deployment or regional endpoint change.