Service principal credential added by user granted privileged role in last 24 hours
Description
Identifies service principal credential additions by users who received Application Administrator or Global Administrator roles within the preceding 24 hours, consistent with immediate post-compromise privilege abuse.
Query · kql
let timeframe = 1d;
let roleWindow = 24h;
let lookback = 7d;
let PrivilegedRoles = dynamic([
"Application Administrator",
"Cloud Application Administrator",
"Global Administrator",
"Privileged Role Administrator"
]);
let RecentRoleGrants =
AuditLogs
| where TimeGenerated >= ago(timeframe + lookback) and TimeGenerated < ago(0h)
| where OperationName in~ ("Add member to role.", "Add member to role")
| where Result =~ "success"
| extend NewRoleUser = tolower(tostring(TargetResources[0].userPrincipalName))
| extend RoleName = tostring(TargetResources[1].displayName)
| where RoleName in~ (PrivilegedRoles)
| where isnotempty(NewRoleUser)
| project NewRoleUser, RoleName, RoleGrantedTime = TimeGenerated;
AuditLogs
| where TimeGenerated >= ago(timeframe)
| where OperationName in~ (
"Add service principal credentials",
"Update application - Certificates and secrets management"
)
| where Result =~ "success"
| extend ActorUpn = tolower(tostring(InitiatedBy.user.userPrincipalName))
| extend ActorApp = tostring(InitiatedBy.app.displayName)
| extend Actor = iff(isnotempty(ActorUpn), ActorUpn, ActorApp)
| extend ActorIp = iff(
isnotempty(tostring(InitiatedBy.user.ipAddress)),
tostring(InitiatedBy.user.ipAddress),
tostring(InitiatedBy.app.ipAddress))
| extend TargetSpName = tostring(TargetResources[0].displayName)
| extend TargetSpId = tostring(TargetResources[0].id)
| where isnotempty(ActorUpn)
| join kind=inner RecentRoleGrants on $left.ActorUpn == $right.NewRoleUser
| where TimeGenerated >= RoleGrantedTime and TimeGenerated <= RoleGrantedTime + roleWindow
| extend AccountName = iff(ActorUpn has "@", tostring(split(ActorUpn, "@")[0]), ActorUpn)
| extend AccountUPNSuffix = iff(ActorUpn has "@", tostring(split(ActorUpn, "@")[1]), "")
| project
TimeGenerated,
ActorUpn,
AccountName,
AccountUPNSuffix,
RoleName,
RoleGrantedTime,
TargetSpName,
TargetSpId,
ActorIp,
CorrelationId
| sort by TimeGenerated desc