mirror of
https://github.com/Primusinterp/PrimusASR
synced 2026-06-08 12:14:14 +00:00
Initial Commit
This commit is contained in:
+272
@@ -0,0 +1,272 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1 +1,19 @@
|
||||
# PrimusASR
|
||||
# PrimusASR
|
||||
|
||||
PrimusASR is a helper script that i created in order to find ASR exclusions as low privilege user on a Windows endpoint. It parses the Windows Defender event logs for Event ID 5007 and extracts the ASR rules and their configuration state, along with any discovered exclusions. This method allows for an easy way of bypassing ASR rules such as ``01443614-cd74-433a-b99e-2ecdc07bfc25 - Block executable files from running unless they meet a prevalence, age, or trusted list criteria``. For further details about this method and other methods of bypassing this ASR rule, please check out my blog post [here](https://primusinterp.com/posts/WindowsASR/).
|
||||
|
||||
## Usage
|
||||
|
||||
```powershell
|
||||
.\PrimusASR.ps1
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
The output is a table of the ASR rules and their configuration state.
|
||||
|
||||
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This tool is designed for legitimate security testing and research purposes only. Users are responsible for ensuring compliance with applicable laws and regulations. The authors are not responsible for any misuse of this software.
|
||||
Reference in New Issue
Block a user