Microsoft recently broke this with an Update for Defender they will need to deploy the fix due to Tamper Protection :
Context
[[“DefenderUpdateSvc”,”c:\\programdata\\microsoft\\microsoft defender\\defender update\\platform\\10.8838.26060.15013-0\\defenderupdateservice.exe”],[“Sense”,”c:\\programdata\\microsoft\\windows defender advanced threat protection\\platform\\versions\\10.8838.26060.15013-0\\mssense.exe”]]?
[“DefenderUpdateSvc”,”c:\\programdata\\microsoft\\microsoft defender\\defender update\\platform\\10.8838.26060.15013-0\\defenderupdateservice.exe”]?
[“Sense”,”c:\\programdata\\microsoft\\windows defender advanced threat protection\\platform\\versions\\10.8838.26060.15013-0\\mssense.exe”]
Advanced Hunting Query
DeviceTvmSecureConfigurationAssessment
| where IsApplicable == 1 and IsCompliant == 0
| join kind=inner (DeviceTvmSecureConfigurationAssessmentKB
| where ConfigurationName has "unquoted") on ConfigurationId
| project DeviceName, ConfigurationName, Context, Timestamp
Detection.ps1
$rx = '^(?!")(?<exe>[^"]*?\.exe)(?<rest>.*)$' # lazy: stops at the FIRST .exe
$hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine','Registry64')
$svc = $hklm.OpenSubKey('SYSTEM\CurrentControlSet\Services')
$bad = foreach ($n in $svc.GetSubKeyNames()) {
$k = $svc.OpenSubKey($n); if (-not $k) { continue }
$p = $k.GetValue('ImagePath', $null, 'DoNotExpandEnvironmentNames'); $k.Close()
if ($p -is [string] -and $p -match $rx -and $Matches.exe -match '\s') { "$n => $p" }
}
$svc.Close(); $hklm.Close()
if ($bad) { Write-Output ("Unquoted: " + ($bad -join ' | ')); exit 1 }
Write-Output "Compliant"; exit 0
Remmediation.ps1
$rx = '^(?!")(?<exe>[^"]*?\.exe)(?<rest>.*)$'
$hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine','Registry64')
$svc = $hklm.OpenSubKey('SYSTEM\CurrentControlSet\Services')
$fixed = @()
foreach ($n in $svc.GetSubKeyNames()) {
$k = $null
try { $k = $svc.OpenSubKey($n, $true) } catch { continue }
if (-not $k) { continue }
try {
$p = $k.GetValue('ImagePath', $null, 'DoNotExpandEnvironmentNames')
if ($p -is [string] -and $p -match $rx) {
$exe = $Matches.exe; $rest = $Matches.rest
if ($exe -match '\s') {
$kind = $k.GetValueKind('ImagePath')
$new = '"' + $exe + '"' + $rest
$k.SetValue('ImagePath', $new, $kind)
$fixed += "$n : $p -> $new"
}
}
} catch { Write-Output "Failed $n : $($_.Exception.Message)" }
finally { $k.Close() }
}
$svc.Close(); $hklm.Close()
Write-Output ("Fixed {0}: {1}" -f $fixed.Count, ($fixed -join ' | '))
exit 0