Adversaries may use critical user management operations to establish persistence and then disable System Restore to eliminate forensic evidence. SOC teams should proactively hunt for this behavior as it indicates potential privilege escalation and evidence tampering in Azure Sentinel.
KQL Query
let security_info_actions = dynamic(["User registered security info", "User changed default security info", "User deleted security info", "Admin updated security info", "User reviewed security info", "Admin deleted security info", "Admin registered security info"]);
let AdminUsers =
(IdentityInfo
| mv-expand AssignedRoles
| where AssignedRoles matches regex 'Admin'
| summarize by tolower(AccountUPN));
(union isfuzzy=true
(
SecurityEvent
| where EventID == '4688'
| where ParentProcessName has 'rundll32.exe'
and NewProcessName has 'schtasks.exe'
and CommandLine has 'Change' and CommandLine has 'SystemRestore'
and CommandLine has 'disable'
| extend MachineName = Computer , Process = NewProcessName
| project AccountDomain,Account = AccountName, _ResourceId, _SubscriptionId, CategoryId, ClientIPAddress, CommandLine, Process
),
(
WindowsEvent
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend IpAddress = tostring(EventData.IpAddress)
| extend CommandLine = tostring(EventData.CommandLine)
| where isnotempty(CommandLine)
| where ParentProcessName has 'rundll32.exe'
and NewProcessName has 'schtasks.exe'
and CommandLine has 'Change' and CommandLine has 'SystemRestore' and CommandLine has 'disable'
| extend MachineName = Computer , Process = NewProcessName
| extend MachineName = Computer , Process = NewProcessName
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| project _ResourceId, _SubscriptionId, CommandLine, Account, Computer, IpAddress, Process
),
(
DeviceProcessEvents
| where InitiatingProcessFileName =~ 'rundll32.exe'
and InitiatingProcessCommandLine !contains " " and InitiatingProcessCommandLine != ""
and FileName in~ ('schtasks.exe')
and ProcessCommandLine has 'Change' and ProcessCommandLine has 'SystemRestore' and ProcessCommandLine has 'disable'
| extend MachineName = DeviceName , Process = InitiatingProcessFolderPath, Account = AccountName
| project AccountDomain,Account = AccountName, AccountObjectId, TenantId, ReportId, Computer=MachineName, Process
))
| join kind=inner
(
AuditLogs
| where Category =~ "UserManagement"
| where ActivityDisplayName in (security_info_actions)
| extend Initiator = tostring(InitiatedBy.user.userPrincipalName)
| extend IP = tostring(InitiatedBy.user.ipAddress)
| extend Target = tolower(tostring(TargetResources[0].userPrincipalName))
| where Target in (AdminUsers)
| project ActivityDateTime, Target, IP, Account=Initiator, ResourceId, ResultType, AADTenantId, CorrelationId, OperationName
) on Account
| project AccountCustomEntity=Account, CategoryId, HostCustomEntity=Computer, IPCustomEntity=IpAddress, CorrelationId, ReportId, ResourceId, TenantId, ProcessCustomEntity=Process, CommandLineCustomEntity=CommandLine, _ResourceId, _SubscriptionId
id: dcc15282-2bcb-496e-84db-3c90d0dc0a0c
name: Critical user management operations followed by disabling of System Restore from admin account
description: |
'This query could identify critical user management operations like user registration(Microsoft Entra ID Multi-Factor Authentication & self-service password reset (SSPR)) authentication by admin account followed by attempts to stop System Restore activity. Stopping system restore prevents from recovering data by going back to a restore point. The operations could be an indication of attackers trying to maintain persistence, move laterally with attempts to stop system restore point that could point to a potential ransomware attack.'
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AuditLogs
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceProcessEvents
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvents
- connectorId: WindowsForwardedEvents
dataTypes:
- WindowsEvent
- connectorId: BehaviorAnalytics
dataTypes:
- IdentityInfo
tactics:
- InitialAccess
- Impact
relevantTechniques:
- T1078
- T1490
query: |
let security_info_actions = dynamic(["User registered security info", "User changed default security info", "User deleted security info", "Admin updated security info", "User reviewed security info", "Admin deleted security info", "Admin registered security info"]);
let AdminUsers =
(IdentityInfo
| mv-expand AssignedRoles
| where AssignedRoles matches regex 'Admin'
| summarize by tolower(AccountUPN));
(union isfuzzy=true
(
SecurityEvent
| where EventID == '4688'
| where ParentProcessName has 'rundll32.exe'
and NewProcessName has 'schtasks.exe'
and CommandLine has 'Change' and CommandLine has 'SystemRestore'
and CommandLine has 'disable'
| extend MachineName = Computer , Process = NewProcessName
| project AccountDomain,Account = AccountName, _ResourceId, _SubscriptionId, CategoryId, ClientIPAddress, CommandLine, Process
),
(
WindowsEvent
| extend ParentProcessName = tostring(EventData.ParentProcessName)
| extend NewProcessName = tostring(EventData.NewProcessName)
| extend IpAddress = tostring(EventData.IpAddress)
| extend CommandLine = tostring(EventData.CommandLine)
| where isnotempty(CommandLine)
| where ParentProcessName has 'rundll32.exe'
and NewProcessName has 'schtasks.exe'
and CommandLine has 'Change' and CommandLine has 'SystemRestore' and CommandLine has 'disable'
| extend MachineName = Computer , Process = NewProcessName
| extend MachineName = Computer , Process = NewProcessName
| extend Account = strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| project _ResourceId, _SubscriptionId, CommandLine, Account, Computer, IpAddress, Process
),
| Sentinel Table | Notes |
|---|---|
AuditLogs | Ensure this data connector is enabled |
DeviceProcessEvents | Ensure this data connector is enabled |
IdentityInfo | Ensure this data connector is enabled |
SecurityEvent | Ensure this data connector is enabled |
WindowsEvent | Ensure this data connector is enabled |
Scenario: System Restore is disabled as part of a scheduled maintenance job by the admin account.
Filter/Exclusion: Exclude events where the action is performed by a scheduled task or service account (e.g., Task Scheduler or System account), or filter by event ID 6008 (System Restore disabled via Group Policy or registry).
Scenario: An admin account disables System Restore during a routine security audit or compliance check.
Filter/Exclusion: Exclude events where the user is a member of the Security Administrators group or has a role like Compliance Auditor, or filter by event source Security or Group Policy.
Scenario: A legitimate system update or patching process disables System Restore temporarily.
Filter/Exclusion: Exclude events where the action is associated with a known patching tool (e.g., Windows Update, SCCM, or WSUS), or filter by event ID 6006 (System event log) or Microsoft Windows Update.
Scenario: An admin account disables System Restore after performing a user management task, such as resetting a password via Microsoft Entra ID.
Filter/Exclusion: Exclude events where the preceding action is related to password reset (e.g., event ID 4741 or 4724) or user registration (e.g., event ID 4726), or filter by the same admin account performing both actions within a short time window.
Scenario: A third-party management tool (e.g., Microsoft Intune or Azure AD Connect) disables System Restore as part of a configuration change.
Filter/Exclusion: Exclude events where the process is initiated by a known third-party tool (e.g., Intune, Azure AD Connect, or Microsoft Endpoint Manager), or filter by the process name or service name associated with the tool