Skip to content

Instantly share code, notes, and snippets.

@caueb
Created June 6, 2024 14:18
Show Gist options
  • Save caueb/1e2c6af5464bf06ae7f15292799d4b94 to your computer and use it in GitHub Desktop.
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.
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
@caueb
Copy link
Author

caueb commented Jun 6, 2024

There is also this one liner do do a quick dirty job of the above:

Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" | Where-Object { $_.Id -eq 5007 -and $_.Message -match "Exclusions" } | ForEach-Object { if ($_.Message -match "SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths\\[^\s]+") { $matches[0] } }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment