[REQ-PAW-025] Configure Exploit Protection Profile for PAWs
Target Scope
- Applicable Systems: Privileged Access Workstations (PAWs) used for Tier 0 directory administration.
- Operating Systems: Windows 10 Enterprise (1607+) and Windows 11 Enterprise.
Implementation Details
- Priority: High
- GPO Path / Registry Location:
- GPO Paths:
Computer Configuration\Administrative Templates\Windows Components\Windows Defender Exploit Guard\Exploit Protection-> Use a common set of exploit protection settingsComputer Configuration\Administrative Templates\Windows Components\Windows Defender Security Center\App and Browser protection-> Prevent users from modifying settingsComputer Configuration\Administrative Templates\MS Security Guide-> Enable Certificate PaddingComputer Configuration\Administrative Templates\MS Security Guide-> Enable Structured Exception Handling Overwrite Protection (SEHOP)
- Registry Locations:
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit ProtectionExploitProtectionSettings=C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml(REG_SZ)
HKLM\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protectionDisallowExploitProtectionOverride=1(REG_DWORD)
HKLM\SOFTWARE\Microsoft\Cryptography\Wintrust\ConfigEnableCertPaddingCheck=1(REG_DWORD)
HKLM\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\ConfigEnableCertPaddingCheck=1(REG_DWORD)
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\kernelDisableExceptionChainValidation=0(REG_DWORD)
- GPO Paths:
Rationale
Exploit Protection provides a set of advanced memory and vulnerability mitigations. These mitigations protect both the operating system and applications from memory corruption, buffer overflows, execution redirection, and process hijack attempts.
By enforcing system-wide mitigations:
- Data Execution Prevention (DEP): Enforces non-executable memory pages, preventing attackers from executing shellcode injected into data-only memory regions (such as the stack or heap).
- Address Space Layout Randomization (ASLR): Randomizes the locations where system components, executable code, and memory allocations are loaded. Enabling Mandatory ASLR (Force Relocate Images), Bottom-Up ASLR, and High Entropy ASLR makes memory structures unpredictable, thwarting return-oriented programming (ROP) exploits.
- Control Flow Guard (CFG): Verifies control flow integrity for indirect call targets at compile time, preventing attackers from hijacking indirect jumps to point to arbitrary payloads.
- Structured Exception Handler Overwrite Protection (SEHOP): Blocks exploits that overwrite Structured Exception Handlers (SEH) to gain control of execution paths during error handling.
- Heap Termination on Corruption: Immediately terminates a process if corruption is detected in its heap. This blocks heap-based buffer overflow exploitation before execution control can be seized.
Legacy Impact & Compatibility
- Application Crashes: Strict system-wide mitigations, particularly Mandatory ASLR (
ForceRelocateImages) and DEP, can cause legacy, proprietary, or unsigned applications that are not compiled to support dynamic base relocations to crash upon launching. - Orchestration/Agent Conflicts: Certain older monitoring agents or custom management wrappers that perform memory hook injections may fail when CFG or strict memory mitigations are enforced.
Implementation Steps
Option A: Group Policy Object (GPO) Configuration (Preferred)
Step 1: Generate the Reference XML Configuration File
Before configuring the GPO, you must create a reference XML file containing the desired Exploit Protection mitigations:
- On a reference workstation, open the Windows Security app.
- Select App & browser control and click Exploit protection settings.
- Under the System settings tab, configure the following:
- Control Flow Guard (CFG): On by default
- Data Execution Prevention (DEP): On by default
- Force randomization for images (Mandatory ASLR): On by default
- Randomize memory allocations (Bottom-up ASLR): On by default
- High-entropy ASLR: On by default
- Validate exception chains (SEHOP): On by default
- Validate heap integrity: On by default
- Select the Program settings tab and configure application-specific overrides for administrative utilities and scripting hosts (
powershell.exe,cmd.exe, etc.) to apply EAF, IAF, and ROP mitigations. - Scroll to the bottom of the page and click Export settings.
- Save the file as
ExploitProtectionSettings.xml. - Copy this XML file to a location accessible by target endpoints, or distribute it to local target directories (e.g.,
C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xml) via Group Policy Preferences (Files).
Step 2: Configure the Group Policy Setting
- Open the Group Policy Management Console (
gpmc.msc) on a domain controller or management host. - Edit the PAW GPO (e.g.,
GPO_Hardening_PAW). - Navigate to:
Computer Configuration\Administrative Templates\Windows Components\Windows Defender Exploit Guard\Exploit Protection - Configure the following setting:
- Policy:
Use a common set of exploit protection settings - Setting:
Enabled - Options: Under the Path or Url field, enter the full path to the XML file (e.g.,
C:\ProgramData\ExploitProtection\ExploitProtectionSettings.xmlor a UNC share path).
- Policy:
- If utilizing Microsoft Security Guide templates:
- Navigate to:
Computer Configuration\Administrative Templates\MS Security Guide - Configure policies:
- Policy:
Enable Certificate Padding-> Set to Enabled - Policy:
Enable Structured Exception Handling Overwrite Protection (SEHOP)-> Set to Enabled
- Policy:
- Navigate to:
- Lock down Exploit Protection settings against user tampering:
- Navigate to:
Computer Configuration\Policies\Administrative Templates\Windows Components\Windows Defender Security Center\App and Browser protection - Configure policy: Prevent users from modifying settings -> Set to Enabled
- Navigate to:
- Link the GPO to the appropriate Organizational Unit (OU) containing the target PAWs.
Option B: PowerShell & Registry Configuration (Remediation / Non-GPO)
Use this method to apply the exploit protection profile locally on individual systems or standalone hosts.
Download Script: Configure-PawExploitProtection.ps1
# Configure-PawExploitProtection.ps1
# Description: Generates the system-wide and application-specific Exploit Protection XML profile, applies it locally, and configures the policy registry keys on PAWs.
Write-Host "Applying Exploit Protection Profile..." -ForegroundColor Cyan
# 1. Define the XML content including System and App settings
$XmlContent = @"
<?xml version="1.0" encoding="utf-8"?>
<MitigationPolicy>
<SystemConfig>
<DEP Enable="true" EmulateAtlThunks="false" />
<ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" />
<ControlFlowGuard Enable="true" SuppressExports="false" />
<SEHOP Enable="true" TelemetryOnly="false" />
<Heap TerminateOnError="true" />
</SystemConfig>
<AppConfig Executable="wscript.exe">
<DEP Enable="true" EmulateAtlThunks="false" />
<ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" />
<ControlFlowGuard Enable="true" SuppressExports="false" />
<Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" />
<ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" />
</AppConfig>
<AppConfig Executable="cscript.exe">
<DEP Enable="true" EmulateAtlThunks="false" />
<ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" />
<ControlFlowGuard Enable="true" SuppressExports="false" />
<Payload EnableExportAddressFilter="true" AuditEnableExportAddressFilter="false" EnableExportAddressFilterPlus="true" AuditEnableExportAddressFilterPlus="false" EnableImportAddressFilter="true" AuditEnableImportAddressFilter="false" EnableRopStackPivot="true" AuditEnableRopStackPivot="false" EnableRopCallerCheck="true" AuditEnableRopCallerCheck="false" EnableRopSimExec="true" AuditEnableRopSimExec="false" />
<ImageLoad BlockRemoteImageLoads="true" AuditBlockRemoteImageLoads="false" PreferSystem32="true" AuditPreferSystem32="false" />
</AppConfig>
<AppConfig Executable="powershell.exe">
<DEP Enable="true" EmulateAtlThunks="false" />
<ASLR ForceRelocateImages="true" RequireInfo="false" BottomUp="true" HighEntropy="true" />
<ControlFlowGuard Enable="true" SuppressExports="false" />
</AppConfig>
</MitigationPolicy>
"@
# 2. Create the target directory and write the XML file
$TargetDir = "C:\ProgramData\ExploitProtection"
if (-not (Test-Path $TargetDir)) {
New-Item -Path $TargetDir -ItemType Directory -Force | Out-Null
}
$XmlPath = "$TargetDir\ExploitProtectionSettings.xml"
Set-Content -Path $XmlPath -Value $XmlContent -Encoding UTF8
Write-Host "Exploit Protection XML profile written to $($XmlPath)" -ForegroundColor Gray
# 3. Apply the settings locally using the cmdlet
if (Get-Command Set-ProcessMitigation -ErrorAction SilentlyContinue) {
Set-ProcessMitigation -PolicyFilePath $XmlPath
Write-Host "[+] Exploit protection system settings applied locally." -ForegroundColor Green
} else {
Write-Warning "Set-ProcessMitigation cmdlet is not available. Please ensure you are running Windows 10/11 or Windows Server 2016+."
}
# 4. Configure policy registry keys to point to the XML file
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (-not (Test-Path $RegPath)) {
New-Item -Path $RegPath -Force | Out-Null
}
Set-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -Value $XmlPath -Type String -Force
Write-Host "[+] GPO policy registry values configured." -ForegroundColor Green
# 5. Configure MS Security Guide mitigations: Certificate Padding check and SEHOP registry keys
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustPath)) {
New-Item -Path $WintrustPath -Force | Out-Null
}
Set-ItemProperty -Path $WintrustPath -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
if (-not (Test-Path $WintrustWow64Path)) {
New-Item -Path $WintrustWow64Path -Force | Out-Null
}
Set-ItemProperty -Path $WintrustWow64Path -Name "EnableCertPaddingCheck" -Value 1 -Type DWord -Force
$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
if (-not (Test-Path $SessionKernelPath)) {
New-Item -Path $SessionKernelPath -Force | Out-Null
}
Set-ItemProperty -Path $SessionKernelPath -Name "DisableExceptionChainValidation" -Value 0 -Type DWord -Force
Write-Host "[+] Certificate Padding check and SEHOP registry keys applied." -ForegroundColor Green
# 6. Prevent users from modifying Exploit Protection settings in Windows Security Center
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
if (-not (Test-Path $SecCenterPath)) {
New-Item -Path $SecCenterPath -Force | Out-Null
}
Set-ItemProperty -Path $SecCenterPath -Name "DisallowExploitProtectionOverride" -Value 1 -Type DWord -Force
Write-Host "[+] Exploit protection override lockdown applied." -ForegroundColor Green
Write-Host "Exploit Protection Profile application completed successfully." -ForegroundColor Cyan
To verify the settings have been applied:
Download Script: Get-PawExploitProtectionStatus.ps1
# Get-PawExploitProtectionStatus.ps1
# Description: Audits system-wide Exploit Protection settings against the recommended security baseline on PAWs.
Write-Host "Auditing system-wide Exploit Protection mitigations..." -ForegroundColor Cyan
$BaselineFailed = $false
$Mitigations = Get-ProcessMitigation -System
# Helper function to evaluate and display status
function Test-MitigationSetting {
param(
[string]$MitigationName,
[string]$CurrentValue,
[string]$ExpectedValue
)
if ($CurrentValue -eq $ExpectedValue) {
Write-Host " [PASS] $($MitigationName): $($CurrentValue)" -ForegroundColor Green
} else {
Write-Host " [FAIL] $($MitigationName): $($CurrentValue) (Expected: $($ExpectedValue))" -ForegroundColor Red
$script:BaselineFailed = $true
}
}
Write-Host "`nSystem-wide Mitigations:" -ForegroundColor Gray
# Audit DEP
Test-MitigationSetting -MitigationName "DEP Enable" -CurrentValue $Mitigations.DEP.Enable -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "DEP EmulateAtlThunks" -CurrentValue $Mitigations.DEP.EmulateAtlThunks -ExpectedValue "OFF"
# Audit ASLR
Test-MitigationSetting -MitigationName "ASLR ForceRelocateImages" -CurrentValue $Mitigations.ASLR.ForceRelocateImages -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR BottomUp" -CurrentValue $Mitigations.ASLR.BottomUp -ExpectedValue "ON"
Test-MitigationSetting -MitigationName "ASLR HighEntropy" -CurrentValue $Mitigations.ASLR.HighEntropy -ExpectedValue "ON"
# Audit CFG
Test-MitigationSetting -MitigationName "CFG Enable" -CurrentValue $Mitigations.CFG.Enable -ExpectedValue "ON"
# Audit SEHOP
Test-MitigationSetting -MitigationName "SEHOP Enable" -CurrentValue $Mitigations.SEHOP.Enable -ExpectedValue "ON"
# Audit Heap
Test-MitigationSetting -MitigationName "Heap TerminateOnError" -CurrentValue $Mitigations.Heap.TerminateOnError -ExpectedValue "ON"
# Audit Registry Policy and XML Configuration
Write-Host "`nRegistry Policy and XML Configuration:" -ForegroundColor Gray
$RegPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender ExploitGuard\Exploit Protection"
if (Test-Path $RegPath) {
$SettingsValue = Get-ItemProperty -Path $RegPath -Name "ExploitProtectionSettings" -ErrorAction SilentlyContinue
if ($SettingsValue -and $SettingsValue.ExploitProtectionSettings -ne "") {
$XmlPath = $SettingsValue.ExploitProtectionSettings
Write-Host " [PASS] Exploit Protection Policy registry key is configured." -ForegroundColor Green
Write-Host " Path: $XmlPath" -ForegroundColor Gray
if (Test-Path $XmlPath) {
Write-Host " [PASS] Exploit Protection XML file exists." -ForegroundColor Green
try {
[xml]$xml = Get-Content -Path $XmlPath -Raw -ErrorAction Stop
# Verify SystemConfig block
if ($xml.MitigationPolicy.SystemConfig) {
Write-Host " [PASS] XML contains SystemConfig block." -ForegroundColor Green
} else {
Write-Host " [FAIL] XML is missing SystemConfig block." -ForegroundColor Red
$BaselineFailed = $true
}
# Verify major AppConfigs
$ExpectedApps = @("wscript.exe", "cscript.exe", "powershell.exe")
$ConfiguredApps = $xml.MitigationPolicy.AppConfig | ForEach-Object { $_.Executable }
foreach ($app in $ExpectedApps) {
if ($ConfiguredApps -contains $app) {
Write-Host " [PASS] XML contains application profile for: $app" -ForegroundColor Green
} else {
Write-Host " [FAIL] XML is missing application profile for: $app" -ForegroundColor Red
$BaselineFailed = $true
}
}
} catch {
Write-Host " [FAIL] Failed to parse Exploit Protection XML. Error: $($_.Exception.Message)" -ForegroundColor Red
$BaselineFailed = $true
}
} else {
Write-Host " [FAIL] Exploit Protection XML file does not exist at specified path." -ForegroundColor Red
$BaselineFailed = $true
}
} else {
Write-Host " [FAIL] Exploit Protection Policy registry key is empty or missing." -ForegroundColor Red
$BaselineFailed = $true
}
} else {
Write-Host " [FAIL] Exploit Protection Policy registry path does not exist." -ForegroundColor Red
$BaselineFailed = $true
}
# Audit MS Security Guide Registry Settings
Write-Host "`nMS Security Guide Mitigations (Certificate Padding & SEHOP):" -ForegroundColor Gray
function Test-MitigationRegistryValue ($path, $name, $expectedValue) {
$val = Get-ItemProperty -Path $path -Name $name -ErrorAction SilentlyContinue
$actual = if ($val) { $val.$name } else { "" }
$color = "Red"
if ($actual -eq $expectedValue) {
$color = "Green"
} else {
$script:BaselineFailed = $true
}
Write-Host " - Registry Setting: $name | Actual: '$actual' (Expected: '$expectedValue')" -ForegroundColor $color
}
$WintrustPath = "HKLM:\SOFTWARE\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustPath "EnableCertPaddingCheck" 1
$WintrustWow64Path = "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Wintrust\Config"
Test-MitigationRegistryValue $WintrustWow64Path "EnableCertPaddingCheck" 1
$SessionKernelPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\kernel"
Test-MitigationRegistryValue $SessionKernelPath "DisableExceptionChainValidation" 0
$SecCenterPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender Security Center\App and Browser protection"
Test-MitigationRegistryValue $SecCenterPath "DisallowExploitProtectionOverride" 1
Write-Host ""
if ($BaselineFailed) {
Write-Host "Auditing FAILED: One or more configurations do not match the secure baseline." -ForegroundColor Red
exit 1
} else {
Write-Host "Auditing PASSED: All configurations match the secure baseline." -ForegroundColor Green
exit 0
}
Sources & Compliance References
- CIS Microsoft Windows 10/11 Client Benchmark: Section 18.9.30 (ASR/Exploit Guard Mitigation Policy configurations)
- CIS Microsoft Windows 10/11 Client Benchmark: Section 18.4.4 (Enable Certificate Padding), Section 18.4.5 (Enable Structured Exception Handling Overwrite Protection (SEHOP))
- CIS Microsoft Windows Client Benchmark: Section 18.10.92.2.1 (Prevent users from modifying settings in App and Browser protection)
- Microsoft Security Baselines: Exploit Protection baseline templates and application configurations
- ANSSI Active Directory Hardening Guide: Recommendations regarding endpoint protective controls