mirror of
https://github.com/Primusinterp/PrimusASR
synced 2026-06-08 12:14:14 +00:00
272 lines
11 KiB
PowerShell
272 lines
11 KiB
PowerShell
function Get-ExclusionsFromEvent {
|
|
param (
|
|
[string]$EventXml,
|
|
[string]$ExclusionType
|
|
)
|
|
|
|
$exclusions = @()
|
|
|
|
if ($ExclusionType -eq 'Defender') {
|
|
$pattern = 'HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\[^<]+'
|
|
$matches = [regex]::Matches($EventXml, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
foreach ($match in $matches) {
|
|
$exclusions += $match.Value
|
|
}
|
|
}
|
|
elseif ($ExclusionType -eq 'ASR') {
|
|
|
|
|
|
$pattern = 'HKLM[\\]+SOFTWARE[\\]+Microsoft[\\]+Windows Defender[\\]+Windows Defender Exploit Guard[\\]+ASR[\\]+ASROnlyExclusions[^<]+'
|
|
$matches = [regex]::Matches($EventXml, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
foreach ($match in $matches) {
|
|
$exclusions += $match.Value
|
|
}
|
|
|
|
$pattern = 'HKLM[\\]+SOFTWARE[\\]+Policies[\\]+Microsoft[\\]+Windows Defender[\\]+Policy Manager[\\]+Windows Defender Exploit Guard[\\]+ASR[\\]+ASROnlyExclusions[^<]+'
|
|
$matches = [regex]::Matches($EventXml, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
foreach ($match in $matches) {
|
|
$exclusions += $match.Value
|
|
}
|
|
|
|
$pattern = 'HKLM[\\]+SOFTWARE[\\]+Policies[\\]+Microsoft[\\]+Windows Defender[\\]+Policy Manager[\\]+Windows Defender Exploit Guard[\\]+ASR[\\]+ASROnlyPerRuleExclusions[^<]+'
|
|
$matches = [regex]::Matches($EventXml, $pattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
foreach ($match in $matches) {
|
|
$exclusions += $match.Value
|
|
}
|
|
}
|
|
|
|
return $exclusions
|
|
}
|
|
|
|
function Get-ASRRulesFromEvent {
|
|
param (
|
|
[string]$EventXml,
|
|
[System.Diagnostics.Eventing.Reader.EventLogRecord]$Event
|
|
)
|
|
|
|
$asrRules = @{}
|
|
# Regex shenanigans
|
|
$asrRulePathPattern = '(?:HKLM[\\]+SOFTWARE[\\]+Policies[\\]+Microsoft[\\]+Windows Defender[\\]+Policy Manager[\\]+Windows Defender Exploit Guard[\\]+ASR[\\]+Rules[\\]+|ASR[\\]+Rules[\\]+)([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\s*=\s*(0x[0-9a-fA-F]+)'
|
|
|
|
$matches = [regex]::Matches($EventXml, $asrRulePathPattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
|
|
foreach ($match in $matches) {
|
|
$ruleId = $match.Groups[1].Value
|
|
$hexAction = $match.Groups[2].Value
|
|
|
|
try {
|
|
$actionValue = [Convert]::ToInt32($hexAction, 16)
|
|
}
|
|
catch {
|
|
continue
|
|
}
|
|
|
|
$ruleName = Get-ASRRuleName -RuleId $ruleId
|
|
if ($ruleName) {
|
|
$action = Get-ActionName -ActionValue $actionValue
|
|
|
|
$normalizedRuleId = $ruleId.ToLower()
|
|
$asrRules[$normalizedRuleId] = @{
|
|
Name = $ruleName
|
|
Action = $action
|
|
}
|
|
}
|
|
}
|
|
|
|
return $asrRules
|
|
}
|
|
|
|
function Get-ASRRuleName {
|
|
param (
|
|
[string]$RuleId
|
|
)
|
|
|
|
$normalizedRuleId = $RuleId.ToLower()
|
|
# Rules IDs and their names
|
|
$ruleMap = @{
|
|
"56a863a9-875e-4185-98a7-b882c64b5ce5" = "Block abuse of exploited vulnerable signed drivers"
|
|
"7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" = "Block Adobe Reader from creating child processes"
|
|
"d4f940ab-401b-4efc-aadc-ad5f3c50688a" = "Block all Office applications from creating child processes"
|
|
"9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" = "Block credential stealing from the Windows local security authority subsystem (lsass.exe)"
|
|
"be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" = "Block executable content from email client and webmail"
|
|
"01443614-cd74-433a-b99e-2ecdc07bfc25" = "Block executable files from running unless they meet a prevalence, age, or trusted list criteria"
|
|
"5beb7efe-fd9a-4556-801d-275e5ffc04cc" = "Block execution of potentially obfuscated scripts"
|
|
"d3e037e1-3eb8-44c8-a917-57927947596d" = "Block JavaScript or VBScript from launching downloaded executable content"
|
|
"3b576869-a4ec-4529-8536-b80a7769e899" = "Block Office applications from creating executable content"
|
|
"75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" = "Block Office applications from injecting code into other processes"
|
|
"26190899-1602-49e8-8b27-eb1d0a1ce869" = "Block Office communication applications from creating child processes"
|
|
"e6db77e5-3df2-4cf1-b95a-636979351e5b" = "Block persistence through WMI event subscription"
|
|
"d1e49aac-8f56-4280-b9ba-993a6d77406c" = "Block process creations originating from PSExec and WMI commands"
|
|
"b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" = "Block untrusted and unsigned processes that run from USB"
|
|
"92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" = "Block Win32 API calls from Office macro"
|
|
"c1db55ab-c21a-4637-bb3f-a12568109d35" = "Use advanced protection against ransomware"
|
|
}
|
|
|
|
return $ruleMap[$normalizedRuleId]
|
|
}
|
|
|
|
function Get-ASRRuleAction {
|
|
param (
|
|
[string]$EventXml,
|
|
[string]$RuleId
|
|
)
|
|
|
|
|
|
|
|
$actionPattern = "$([regex]::Escape($RuleId)).*?(\d+)"
|
|
$match = [regex]::Match($EventXml, $actionPattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
|
|
|
|
if ($match.Success) {
|
|
$actionValue = [int]$match.Groups[1].Value
|
|
return Get-ActionName -ActionValue $actionValue
|
|
}
|
|
|
|
if ($EventXml -match 'AttackSurfaceReductionRules_Actions') {
|
|
$actionMatch = [regex]::Match($EventXml, 'AttackSurfaceReductionRules_Actions[^>]*>([^<]+)')
|
|
if ($actionMatch.Success) {
|
|
$actions = $actionMatch.Groups[1].Value -split ','
|
|
if ($actions.Count -gt 0) {
|
|
$actionValue = [int]($actions[0].Trim())
|
|
return Get-ActionName -ActionValue $actionValue
|
|
}
|
|
}
|
|
}
|
|
|
|
return "Unknown"
|
|
}
|
|
|
|
function Get-ActionName {
|
|
param (
|
|
[int]$ActionValue
|
|
)
|
|
|
|
switch ($ActionValue) {
|
|
0 { return "Disabled" }
|
|
1 { return "Block" }
|
|
2 { return "Audit" }
|
|
6 { return "Warn" }
|
|
default { return "Unknown ($ActionValue)" }
|
|
}
|
|
}
|
|
|
|
Write-Host "`n=== Windows Defender Exclusions Scanner ===" -ForegroundColor Cyan
|
|
Write-Host "Scanning for Defender and ASR Exclusions...`n" -ForegroundColor Green
|
|
|
|
try {
|
|
$events = Get-WinEvent -FilterHashtable @{
|
|
LogName = 'Microsoft-Windows-Windows Defender/Operational'
|
|
ID = 5007
|
|
} -ErrorAction Stop
|
|
|
|
if ($events.Count -eq 0) {
|
|
Write-Host "No exclusion events found." -ForegroundColor Yellow
|
|
exit
|
|
}
|
|
|
|
Write-Host "Found $($events.Count) Event ID 5007 entries. Processing...`n" -ForegroundColor Gray
|
|
|
|
$foundExclusions = $false
|
|
$allASRRules = @{}
|
|
$allDefenderExclusions = @()
|
|
$allASRExclusions = @()
|
|
$totalDisabled = 0
|
|
$totalAudit = 0
|
|
$totalBlock = 0
|
|
$totalWarn = 0
|
|
|
|
$sortedEvents = $events | Sort-Object -Property TimeCreated -Descending
|
|
|
|
foreach ($event in $sortedEvents) {
|
|
$eventXml = $event.ToXml()
|
|
|
|
$defenderExclusions = Get-ExclusionsFromEvent -EventXml $eventXml -ExclusionType 'Defender'
|
|
foreach ($exclusion in $defenderExclusions) {
|
|
if ($exclusion -and $exclusion -notin $allDefenderExclusions) {
|
|
$foundExclusions = $true
|
|
$allDefenderExclusions += $exclusion
|
|
}
|
|
}
|
|
|
|
$asrExclusions = Get-ExclusionsFromEvent -EventXml $eventXml -ExclusionType 'ASR'
|
|
foreach ($exclusion in $asrExclusions) {
|
|
if ($exclusion -and $exclusion -notin $allASRExclusions) {
|
|
$foundExclusions = $true
|
|
$allASRExclusions += $exclusion
|
|
}
|
|
}
|
|
|
|
$asrRules = Get-ASRRulesFromEvent -EventXml $eventXml -Event $event
|
|
foreach ($ruleId in $asrRules.Keys) {
|
|
$normalizedRuleId = $ruleId.ToLower()
|
|
if (-not $allASRRules.ContainsKey($normalizedRuleId)) {
|
|
$allASRRules[$normalizedRuleId] = $asrRules[$ruleId]
|
|
|
|
switch ($asrRules[$ruleId].Action) {
|
|
"Disabled" { $totalDisabled++ }
|
|
"Audit" { $totalAudit++ }
|
|
"Block" { $totalBlock++ }
|
|
"Warn" { $totalWarn++ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "===================================== Defender Exclusions ======================================" -ForegroundColor Cyan
|
|
if ($allDefenderExclusions.Count -gt 0) {
|
|
foreach ($exclusion in $allDefenderExclusions) {
|
|
Write-Host "[+] $exclusion" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "No Defender exclusions found." -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
|
|
Write-Host "===================================== ASR Exclusions ======================================" -ForegroundColor Cyan
|
|
if ($allASRExclusions.Count -gt 0) {
|
|
foreach ($exclusion in $allASRExclusions) {
|
|
Write-Host "[+] $exclusion" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "No ASR exclusions found." -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
|
|
Write-Host "===================================== ASR Summary ======================================" -ForegroundColor Cyan
|
|
if ($allASRRules.Count -gt 0) {
|
|
Write-Host "=> There's $($allASRRules.Count) rules configured" -ForegroundColor White
|
|
Write-Host "=> $totalDisabled in Disabled Mode ** $totalAudit in Audit Mode ** $totalBlock in Block Mode ** $totalWarn in Warn Mode" -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "===================================== ASR Rules ======================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
foreach ($ruleId in ($allASRRules.Keys | Sort-Object)) {
|
|
$rule = $allASRRules[$ruleId]
|
|
Write-Host "Rule ID : $ruleId" -ForegroundColor Cyan
|
|
Write-Host "Name : $($rule.Name)" -ForegroundColor White
|
|
Write-Host "Action : $($rule.Action)" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
}
|
|
}
|
|
else {
|
|
Write-Host "No ASR rules found in the event log." -ForegroundColor Gray
|
|
Write-Host ""
|
|
Write-Host "Note: Event ID 5007 only logs configuration changes. Rules that were never modified" -ForegroundColor Yellow
|
|
Write-Host " may not appear in the event log." -ForegroundColor Yellow
|
|
}
|
|
Write-Host ""
|
|
|
|
Write-Host "=== Scan Complete ===" -ForegroundColor Cyan
|
|
}
|
|
catch {
|
|
if ($_.Exception.Message -like "*No events were found*") {
|
|
Write-Host "No exclusion events found in the log." -ForegroundColor Yellow
|
|
}
|
|
else {
|
|
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
}
|
|
} |