This detection identifies adversaries attempting to compromise or pivot through high-privilege break-glass accounts by modifying their credentials and MFA configurations, thereby neutralizing a critical emergency access path. Proactive hunting for these anomalies in Azure Sentinel is essential because unauthorized changes to these typically static accounts often signal an attacker establishing persistent backdoors or preparing for lateral movement before triggering standard alerting thresholds.
let starttime = todatetime('{{StartTimeISO}}');
let endtime = todatetime('{{EndTimeISO}}');
let BreakGlassAccounts = (
_GetWatchlist('BreakGlassAccounts')
| project AccountUPN = tolower(tostring(SearchKey))
);
let SecurityInfoOps = dynamic([
"Admin registered security info",
"Admin updated security info",
"Admin deleted security info",
"User registered security info",
"User changed default security info",
"User deleted security info",
"User registered all required security info",
"User started security info registration"
]);
// Password reset/change operation names are not consistent across tenants and Entra ID
// service versions (this repo alone has three different exact-string lists for the same
// event in other hunting queries), so credential resets are matched the same way the
// official "Multiple Password Reset by user" analytic rule does it: any OperationName
// that mentions a password/credential noun together with a change/reset verb, admin or
// self-service alike, rather than an exact-string list that silently misses variants.
let PasswordWords = dynamic(["password", "credential", "credentials"]);
let ChangeActionWords = dynamic(["change", "changed", "reset"]);
AuditLogs
| where TimeGenerated between (starttime .. endtime)
| where Result =~ "success"
| where OperationName in~ (SecurityInfoOps)
or (OperationName has_any (PasswordWords) and OperationName has_any (ChangeActionWords))
// The target user is read from whichever TargetResources entry has type "User" rather
// than a fixed array index, since these operations do not consistently place the target
// first; this matches the extraction used elsewhere in this repository for password
// reset events specifically.
| mv-apply TargetResource = TargetResources on (
where TargetResource.type =~ "User"
| extend TargetUpn = tolower(tostring(TargetResource.userPrincipalName))
)
| where TargetUpn in (BreakGlassAccounts)
| extend ActorUpn = 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 AccountName = tostring(split(TargetUpn, "@")[0])
| extend AccountUPNSuffix = tostring(split(TargetUpn, "@")[1])
| project
TimeGenerated,
OperationName,
TargetUpn,
AccountName,
AccountUPNSuffix,
Actor,
ActorIp,
CorrelationId
| sort by TimeGenerated desc
id: 67657f61-a999-4c64-9093-e988d8d98f63
name: Break-glass account credentials or MFA modified
description: |
Identifies password resets, security-info registrations, and MFA changes made to an account
designated as an emergency break-glass account, which should otherwise remain untouched
between scheduled tests.
description-detailed: |
Break-glass (emergency access) accounts exist to remain usable when every other authentication
path in the tenant has failed, which only works if their credentials and registered security
info stay exactly as documented between the periodic tests organizations run to validate them.
A password reset or a change to registered MFA methods outside a documented test window is a
strong signal that either the account is being repurposed by an attacker for persistence, or
that its emergency-access properties have silently drifted out of the state the runbook expects.
This query depends on the same watchlist as the other two queries in this pack: a watchlist
named `BreakGlassAccounts` whose `SearchKey` column holds the user principal names of the
tenant's designated emergency access accounts.
Every match should be checked against the change calendar for a planned access-recovery test
before escalating. A match with no corresponding test window, or one closely followed by a
sign-in or a role and group membership change on the same account (see the two companion
hunting queries in this pack), should be treated as high priority.
References:
- https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access
- https://attack.mitre.org/techniques/T1098/
- https://attack.mitre.org/techniques/T1556/006/
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
tactics:
- Persistence
- DefenseEvasion
relevantTechniques:
- T1098
- T1556.006
query: |
let starttime = todatetime('{{StartTimeISO}}');
let endtime = todatetime('{{EndTimeISO}}');
let BreakGlassAccounts = (
_GetWatchlist('BreakGlassAccounts')
| project AccountUPN = tolower(tostring(SearchKey))
);
let SecurityInfoOps = dynamic([
"Admin registered security info",
"Admin updated security info",
"Admin deleted security info",
"User registered security info",
"User changed default security info",
"User deleted security info",
"User registered all required security info",
"User started security info registration"
]);
// Password reset/change operation names are not consistent across tenants and Entra ID
// service versions (this repo alone has three different exact-string lists for the same
// event in other hunting queries), so credential resets are matched the same way the
// official "Multiple Password Reset by user" analytic rule does it: any OperationName
// that mentions a password/credential noun together with a change/reset verb, admin or
// self-service alike, rather than an
| Sentinel Table | Notes |
|---|---|
AuditLogs | Ensure this data connector is enabled |
Here are 4 specific false positive scenarios for the Break-glass account credentials or MFA modified rule, including suggested filters and exclusions:
Scheduled Quarterly Security Audit by Identity Management Tool
InitiatorUser or SourceIP matches the dedicated service account used by the Identity Management tool (e.g., svc-sailpoint-audit) and occurs only during the defined maintenance window (e.g., Sundays between 02:00–04:00 UTC).Automated Break-Glass Account Health Check Script
ComputerName hosting the automation agent (e.g., AZ-automation-host-01) and filter out actions where the ChangeType indicates a “Test” or “Dry-run” flag rather than a permanent modification.Onboarding of New Emergency Access Session