← ~/DETECTIONS

2024-10-30 // Dylan Evans

Privilege Escalation via Role Assignments Outside Business Hours

Microsoft Sentinel

Detects unauthorized privilege escalation attempts—adding admin/management roles to users outside standard business hours, potentially indicating malicious activity.

privilege-escalationrole-assignmentout-of-hourslateral-movement

Privilege Escalation via Role Assignments Outside Business Hours

Overview

This detection identifies suspicious role assignment operations (e.g., adding admin/management roles) performed by legitimate users during off-hours, which may indicate credential abuse or unauthorized privilege escalation. Such actions could enable lateral movement or compromise system integrity.

Query

let businessHoursStart = 7*60;  // Edit to match your business start time (HH in HH:MM format)
let businessHoursEnd = 18*60;   // Edit to match your business end time

AuditLogs
| where OperationName has_any ("Add member to role completed", "Add app role assignment grant to user")
| extend TargetRole = tostring(TargetResources[0].displayName)
| where isnotempty(TargetRole) and TargetRole contains "admin" or TargetRole contains "Manage"
| extend LocalTime = datetime_add('hour', 12, TimeGenerated)    // Convert to your timezone (replace `12` with UTC+ offset)
| extend DayOfWeek = toint(dayofweek(LocalTime) / 1d)
| extend HourOfDay = hourofday(LocalTime)
| extend MinuteOfHour = datetime_part("minute", LocalTime)
| extend TimeInMinutes = (HourOfDay * 60) + MinuteOfHour
| where DayOfWeek < 1 or DayOfWeek > 5 or TimeInMinutes < businessHoursStart or TimeInMinutes >= businessHoursEnd
| extend InitiatedBy = tostring(InitiatedBy.user.userPrincipalName)
| mv-expand TargetResources
| where TargetResources.type == "User"
| extend TargetUserPrincipalName = tostring(TargetResources.userPrincipalName)
| extend TargetUserDisplayName = tostring(TargetResources.displayName)
| extend LocalTime = format_datetime(LocalTime, "yyyy-MM-dd HH:mm:ss")
| project TimeGenerated, LocalTime, OperationName, Result, InitiatedBy, TargetUserPrincipalName, TargetUserDisplayName, TargetRole, CorrelationId
| sort by TimeGenerated desc

Logic Explanation

The query filters Azure AD Audit Logs for role assignment operations (Add member to role completed or Add app role assignment grant) where:

  • The target role contains "admin" or "Manage."
  • The operation occurs on a weekend (DayOfWeek < 1) or outside business hours (TimeInMinutes < businessHoursStart or ≥ businessHoursEnd). It expands to user-level details, projects relevant fields, and sorts by timestamp.

Tuning Notes

  • False positives risk: Legitimate admins may occasionally perform off-hours maintenance. Consider adjusting businessHoursStart/End if your org operates non-standard hours.
  • Filter out internal users: Exclude known admin accounts (e.g., via InitiatedBy lookup) to reduce noise.
  • Scope to specific roles: Refine TargetRole checks (e.g., only "Global Administrator") for precision.

References