Detect Entra ID Mass Password Reset and Account Disablement for Extortion Lockout in Google Chronicle
Ransomware and extortion crews that have escalated to Global Administrator or Privileged Authentication Administrator in Entra ID (Azure AD) frequently take a final step before or during encryption: locking legitimate defenders and end users out of the tenant so incident response is slowed and the negotiation position is strengthened. Observed patterns (Scattered Spider, Lapsus$, and multiple ransomware affiliates operating from compromised cloud-admin sessions) include scripted, back-to-back calls against a large number of distinct user objects in a short window — admin-initiated password resets (`Reset password (by admin)` / `Change user password`), account disablement (`Disable account`), and outright user deletion (`Delete user`) — usually from a single initiating identity or a small number of newly-elevated identities, often followed by revocation of the legitimate admins' own refresh tokens. This differs sharply from normal offboarding/HR-driven account changes, which are typically initiated by an HR-integration service principal or IT helpdesk staff against one or a handful of accounts per day, not dozens of distinct users within minutes from a single caller. Detection relies on Entra ID audit logs (the `AuditLogs` table in Microsoft Sentinel / Log Analytics, or the equivalent audit event stream ingested into other SIEMs), correlating a burst of these operations against a high count of distinct target users from the same initiating identity.
MITRE ATT&CK
- Tactic
- Impact
YARA-L Detection Query
rule entra_id_extortion_lockout {
meta:
author = "df00tech Detection Engineering"
description = "Detects a single identity performing password resets and/or deletions against many distinct Entra ID user accounts within a short window, consistent with extortion-driven lockout"
reference = "https://attack.mitre.org/techniques/T1531/"
severity = "CRITICAL"
priority = "HIGH"
mitre_attack_tactic = "Impact"
mitre_attack_technique = "T1531"
false_positives = "Scheduled HR offboarding, break-glass reset campaigns, Lifecycle Workflows, tenant consolidation"
version = "1.0"
events:
$e.metadata.event_type = "USER_CHANGE_PASSWORD" or $e.metadata.event_type = "USER_DELETION"
$e.metadata.product_name = "Microsoft Entra ID"
$e.security_result.action = "ALLOW"
$initiator = $e.principal.user.userid
$target = $e.target.user.userid
match:
$initiator over 15m
outcome:
$distinct_targets = count_distinct($target)
condition:
$e and $distinct_targets >= 5
} Chronicle YARA-L 2.0 rule matching USER_CHANGE_PASSWORD and USER_DELETION UDM events from the Entra ID (Microsoft Entra ID) audit log parser, grouped by initiating principal over a 15-minute match window. Fires when the same initiator triggers password-change or deletion events against 5 or more distinct target users. Account-disablement operations are typically parsed under USER_CHANGE_PERMISSIONS or a product-specific event_type in Chronicle depending on the exact Entra ID parser version in use — extend the events block with that event_type once confirmed against your Chronicle instance's UDM mapping.
Data Sources
Required Tables
False Positives & Tuning
- Scheduled bulk offboarding by an authorized HR/IT automation service principal
- Defensive break-glass password reset campaign after a confirmed credential-stuffing incident
- Entra ID Lifecycle Workflows disabling accounts in bulk
- Tenant consolidation/decommissioning projects with bulk account changes
Other platforms for THREAT-EntraID-ExtortionLockout
Testing Methodology
Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1Simulate Bulk Password Reset Against Test Accounts
Expected signal: AuditLogs entries with OperationName='Reset password (by admin)' or 'Change user password', Result='success', InitiatedBy matching the test admin identity, and TargetResources[0].userPrincipalName matching each test account, all within a few minutes of each other.
- Test 2Simulate Bulk Account Disablement Against Test Accounts
Expected signal: AuditLogs entries with OperationName='Disable account', Result='success', for each of the five test accounts within a short window.
- Test 3Simulate Privilege Activation Immediately Followed by Lockout Actions
Expected signal: AuditLogs entries for 'Add member to role' (or 'Add eligible member to role') for the test admin identity, followed within minutes by a 'Disable account' entry initiated by that same identity.
References (6)
- https://attack.mitre.org/techniques/T1531/
- https://attack.mitre.org/tactics/TA0040/
- https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-audit-logs
- https://learn.microsoft.com/en-us/entra/identity/monitoring-health/reference-audit-activities
- https://learn.microsoft.com/en-us/entra/id-governance/privileged-identity-management/pim-how-to-change-default-settings
- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1531/T1531.md
Response Playbook
Triage
- Identify the initiating identity (InitiatedBy.user.userPrincipalName or InitiatedBy.app.displayName in AuditLogs) — is this a known helpdesk account, an HR/IT automation service principal, or an identity that was itself only recently granted admin rights?
- Check whether the initiating identity's own privileged role assignment (Global Administrator, Privileged Authentication Administrator, User Administrator) was granted in the hours immediately before the lockout burst — a freshly-elevated identity performing mass lockouts within minutes of elevation is a strong compromise indicator
- Enumerate every target user affected and check for overlap with your incident-response team, break-glass accounts, and Global Administrators specifically — attackers frequently target defenders' own accounts first to blind detection and response
- Confirm whether the operations correlate with an open, ticketed offboarding/HR batch — cross-reference against your ITSM/HR system for a matching authorized change
- Check sign-in logs for the initiating identity for anomalous authentication immediately prior (impossible travel, new device, legacy/basic-auth protocol, or a token replay pattern) to establish whether the identity itself is compromised versus insider misuse
- Determine whether refresh token revocation (`Revoke user's refresh token` / `Force sign-out`) was performed against the same target set — a combined reset+disable+revoke sequence maximizes lockout speed and is characteristic of a scripted attack rather than manual admin action
Containment
- Immediately suspend or disable the initiating identity's credentials and any active sessions/refresh tokens, using an independent break-glass admin account that was NOT part of the affected target set
- Do not use a password-reset flow tied to the same identity provider path the attacker used (e.g. self-service password reset via a compromised phone number) — use the tenant's documented emergency access (break-glass) account procedure
- Review and, where necessary, revoke Conditional Access policy changes and any new federated identity provider / trust relationship added around the same time — attackers sometimes add a secondary IdP or relax Conditional Access as a persistence mechanism before locking everyone else out
- Restore access for legitimate locked-out users via the break-glass account: re-enable disabled accounts, issue new temporary passwords through an out-of-band verified channel (not self-service), and re-register MFA where security info was also removed
- Rotate credentials and review role assignments for every identity that held privileged roles in the tenant, since the attacker's foothold used to perform the lockout likely retains other capabilities
- Engage Microsoft support / Entra ID recovery procedures immediately if Global Administrator access itself has been lost tenant-wide
Evidence Collection
- Full AuditLogs records for every Reset password / Change user password / Disable account / Delete user / Revoke refresh token operation in the incident window, including the complete InitiatedBy and TargetResources JSON blocks
- SigninLogs / AADNonInteractiveUserSignInLogs for the initiating identity covering the 48-72 hours preceding the lockout burst
- Entra ID role assignment history (PIM activation logs if Privileged Identity Management is in use) showing when and how the initiating identity obtained its privileged role
- Conditional Access policy change history and any newly added federated domain / identity provider trust configuration
- A complete list of affected target users with timestamps, for both incident scoping and end-user communication/recovery planning
Escalation Criteria
- !5 or more distinct user accounts reset, disabled, or deleted by the same initiating identity within a 15-minute window with no matching change ticket
- !The initiating identity's privileged role was granted within hours of performing the lockout burst
- !Incident-response team members, break-glass accounts, or Global Administrators are among the affected targets
- !The lockout burst is observed in the same operational window as other TA0040 indicators (T1486 encryption, T1490 backup/recovery deletion — see THREAT-CloudBackup-SnapshotPurge and THREAT-ESXi-HypervisorRansomware)
- !Tenant-wide Global Administrator access has been lost and Microsoft support engagement is required to regain control
Investigation Guide
Related Techniques
Forensic Artifacts
- >
AuditLogs entries for Reset password (by admin), Change user password, Disable account, Delete user, and Revoke user's refresh token operations, with full InitiatedBy and TargetResources JSON - >
PIM (Privileged Identity Management) activation and role-assignment audit history for the initiating identity - >
SigninLogs / AADNonInteractiveUserSignInLogs for the initiating identity's authentication events in the preceding 48-72 hours - >
Conditional Access policy change audit entries (Update conditional access policy, Add exclusion) around the incident window - >
Federation/identity-provider trust configuration change history (Add federated domain, Update federation settings)
Tuning Guidance
Build and maintain an allowlist of known HR/IT-automation service principal object IDs that legitimately perform bulk offboarding on a schedule, and exclude them by identity rather than by operation name, since the operation names themselves are identical between legitimate offboarding and malicious lockout. Tune the MinDistinctTargets threshold down (e.g. to 3) in smaller tenants where a burst of 5 would rarely occur even maliciously, and up in large enterprises with a busy central helpdesk to avoid alert fatigue — validate against your own 30-day baseline using the first hunting query before deploying to production. Treat the role-activation-then-lockout sequence (second hunting query) as materially higher severity than the base detection alone, since it isolates the pattern with the fewest legitimate explanations. Always correlate a firing alert against the same-window backup-deletion (THREAT-CloudBackup-SnapshotPurge) and hypervisor/endpoint (THREAT-ESXi-HypervisorRansomware) detections — extortion actors frequently execute recovery-denial, lockout, and encryption within the same short campaign window.
Hunting Queries
30-day baseline hunt to distinguish routine helpdesk/HR-automation callers (steady, low daily volume, usually a recognized service principal) from bursty or first-time high-volume callers, which are the higher-suspicion population worth reviewing individually.
// Hunt: initiating identities performing account-lockout-class operations against 3+ distinct users over the last 30 days, to baseline normal helpdesk/HR volume vs anomalous callers
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName in ("Reset password (by admin)", "Change user password", "Disable account", "Delete user")
| where Result == "success"
| extend Initiator = coalesce(tostring(InitiatedBy.user.userPrincipalName), tostring(InitiatedBy.app.displayName))
| extend TargetUser = tostring(TargetResources[0].userPrincipalName)
| summarize DistinctTargets = dcount(TargetUser), TotalActions = count(), ActiveDays = dcount(bin(TimeGenerated, 1d)) by Initiator
| where DistinctTargets >= 3
| order by DistinctTargets desc index=azuread sourcetype="mscs:azure:aad" (operationName="Reset password (by admin)" OR operationName="Change user password" OR operationName="Disable account" OR operationName="Delete user") result="success"
| eval Initiator=coalesce('initiatedBy.user.userPrincipalName', 'initiatedBy.app.displayName')
| eval TargetUser=mvindex('targetResources{}.userPrincipalName', 0)
| stats dc(TargetUser) as DistinctTargets, count as TotalActions by Initiator
| where DistinctTargets >= 3
| sort - DistinctTargets Hunts for the specific sequence of privilege escalation followed quickly by mass account-lockout activity from the same newly-elevated identity — this ordering is a much stronger compromise signal than either event alone, since legitimate admins rarely perform bulk lockouts within an hour of their own role activation.
// Hunt: privileged role activations followed within 1 hour by an account-lockout-class operation from the same identity
let RoleActivations = AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName has_any ("Add member to role", "Add eligible member to role")
| extend ActivatedUser = tostring(TargetResources[0].userPrincipalName)
| project ActivationTime = TimeGenerated, ActivatedUser;
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName in ("Reset password (by admin)", "Change user password", "Disable account", "Delete user")
| extend Initiator = tostring(InitiatedBy.user.userPrincipalName)
| join kind=inner (RoleActivations) on $left.Initiator == $right.ActivatedUser
| where TimeGenerated - ActivationTime between (0min .. 60min)
| project TimeGenerated, Initiator, ActivationTime, OperationName | tstats count where index=azuread sourcetype="mscs:azure:aad" (operationName="Add member to role" OR operationName="Add eligible member to role") by _time, targetResources{}.userPrincipalName
| rename targetResources{}.userPrincipalName as ActivatedUser
| join type=inner ActivatedUser [ search index=azuread sourcetype="mscs:azure:aad" (operationName="Reset password (by admin)" OR operationName="Change user password" OR operationName="Disable account" OR operationName="Delete user") | eval ActivatedUser='initiatedBy.user.userPrincipalName' ]
| where (_time - _time) <= 3600 Atomic Red Team Tests
Performs admin password resets against several disposable test user accounts in rapid succession, simulating the lockout burst pattern. Use only synthetic test accounts created specifically for this exercise, never real user or service accounts.
Command
for UPN in [email protected] [email protected] [email protected] [email protected] [email protected]; do az ad user update --id "$UPN" --password "TempAtomicTest!$(date +%s)" --force-change-password-next-sign-in true; done Cleanup
Have each test account owner (or an admin) complete a normal self-service password reset to restore a known-good credential state, or delete the disposable test accounts entirely if they were created solely for this exercise. Expected Telemetry
AuditLogs entries with OperationName='Reset password (by admin)' or 'Change user password', Result='success', InitiatedBy matching the test admin identity, and TargetResources[0].userPrincipalName matching each test account, all within a few minutes of each other.
Expected Detection
Fires once DistinctTargets >= 5 for the same Initiator within the 15-minute BurstWindow.
Disables several disposable test user accounts in rapid succession, simulating the account-disablement variant of the lockout pattern. Use only synthetic test accounts.
Command
for UPN in [email protected] [email protected] [email protected] [email protected] [email protected]; do az ad user update --id "$UPN" --account-enabled false; done Cleanup
for UPN in [email protected] [email protected] [email protected] [email protected] [email protected]; do az ad user update --id "$UPN" --account-enabled true; done Expected Telemetry
AuditLogs entries with OperationName='Disable account', Result='success', for each of the five test accounts within a short window.
Expected Detection
Fires once DistinctTargets >= 5 for the same Initiator within the 15-minute BurstWindow, combined with any prior Reset password events against the same or overlapping target set in that window.
Activates a privileged role assignment (via PIM or direct role assignment in a test/lab tenant) for a test admin identity, then immediately performs lockout actions against test accounts from that identity, replicating the highest-confidence attacker sequence. Run only in a lab or sandbox tenant.
Command
az rest --method post --uri 'https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments' --body '{"principalId":"<TEST_ADMIN_OBJECT_ID>","roleDefinitionId":"<USER_ADMINISTRATOR_ROLE_TEMPLATE_ID>","directoryScopeId":"/"}' && az ad user update --id [email protected] --account-enabled false Cleanup
Remove the test role assignment created above via the Graph API roleAssignments DELETE endpoint, and re-enable the test account. Expected Telemetry
AuditLogs entries for 'Add member to role' (or 'Add eligible member to role') for the test admin identity, followed within minutes by a 'Disable account' entry initiated by that same identity.
Expected Detection
The second hunting query (role-activation-then-lockout sequence) returns a match joining the two events for the same Initiator within the 60-minute correlation window.