Created
June 6, 2024 14:18
-
-
Save caueb/1e2c6af5464bf06ae7f15292799d4b94 to your computer and use it in GitHub Desktop.
Retrieve Defender exclusion paths as low-privilege user by parsing Windows event 5007.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-DefenderExclusions { | |
param ( | |
[string]$LogName = "Microsoft-Windows-Windows Defender/Operational", | |
[int]$EventID = 5007 | |
) | |
# Get all event logs with the specified Event ID efficiently | |
$events = Get-WinEvent -FilterHashtable @{LogName=$LogName; Id=$EventID} | |
# Filter events that contain the word "Exclusions" | |
$exclusionEvents = $events | Where-Object { $_.Message -match "Exclusions" } | |
# Define the regex patterns to match exclusion paths, extensions, and processes | |
$patternPaths = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\(.+?)\s*=" | |
$patternExtensions = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Extensions\\(.+)" | |
$patternProcesses = "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes\\(.+)" | |
# Extract and print all types of exclusions from the message | |
$exclusionEvents | ForEach-Object { | |
$message = $_.Message | |
# Check and extract Path exclusions | |
if ($message -match $patternPaths) { | |
[PSCustomObject]@{ | |
TimeCreated = $_.TimeCreated | |
ExclusionType = 'Path' | |
ExclusionDetail = $matches[1] # Use matches[1] to get the capturing group | |
} | |
} | |
# Check and extract Extension exclusions | |
if ($message -match $patternExtensions) { | |
[PSCustomObject]@{ | |
TimeCreated = $_.TimeCreated | |
ExclusionType = 'Extension' | |
ExclusionDetail = $matches[1] # Use matches[1] to get the capturing group | |
} | |
} | |
# Check and extract Process exclusions | |
if ($message -match $patternProcesses) { | |
[PSCustomObject]@{ | |
TimeCreated = $_.TimeCreated | |
ExclusionType = 'Process' | |
ExclusionDetail = $matches[1] # Use matches[1] to get the capturing group | |
} | |
} | |
} | |
} | |
function Test-UserPermissions { | |
param ( | |
[Parameter(Mandatory)] | |
[PSCustomObject[]]$Exclusions | |
) | |
$results = @() | |
foreach ($exclusion in $Exclusions) { | |
if ($exclusion.ExclusionType -eq 'Path' -and ![string]::IsNullOrWhiteSpace($exclusion.ExclusionDetail)) { | |
$path = $exclusion.ExclusionDetail | |
try { | |
Write-Output "" | |
Write-Output "[i] Checking path: ${path} $_" | |
# Get the item details and determine if it is a file or directory | |
$item = Get-Item -Path $path -ErrorAction Stop | |
if ($item -is [System.IO.DirectoryInfo]) { | |
$parentDirectory = $path # It's a directory, check permissions on itself | |
} else { | |
$parentDirectory = $item.DirectoryName # It's a file, check permissions on its directory | |
} | |
#Write-Output "Parent Directory: $parentDirectory" | |
# Test permissions | |
$acl = Get-Acl -Path $parentDirectory | |
$user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
# Write-Output "`tChecking permissions for user: $user" | |
$hasPermission = $false | |
foreach ($access in $acl.Access) { | |
if ($access.IdentityReference.Value -eq $user) { | |
if ($access.FileSystemRights -match "Modify" -or $access.FileSystemRights -match "FullControl") { | |
$hasPermission = $true | |
Write-Output "`tUser $user has modify/full control permissions." | |
break | |
} | |
} | |
} | |
$results += [PSCustomObject]@{ | |
FileName = $item.Name | |
HasPermission = $hasPermission | |
ParentDirectory = $parentDirectory | |
User = $user | |
} | |
} catch { | |
Write-Output "Error processing path ${path}: $_" | |
$results += [PSCustomObject]@{ | |
FileName = $path | |
HasPermission = $false | |
Error = $_.Exception.Message | |
ParentDirectory = $parentDirectory | |
User = $user | |
} | |
} | |
} else { | |
Write-Output "Invalid or empty path detected for exclusion detail: $($exclusion.ExclusionDetail)" | |
$results += [PSCustomObject]@{ | |
FileName = "Invalid/Empty Path" | |
HasPermission = $false | |
Error = "Path was null or empty." | |
} | |
} | |
} | |
return $results | |
} | |
$exclusions = Get-DefenderExclusions | |
$exclusions | |
Test-UserPermissions -Exclusions $exclusions |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is also this one liner do do a quick dirty job of the above: