Repository navigation
Expand file tree
/
Copy pathGet-ExploitProtectionEvents.ps1
More file actions
164 lines (134 loc) · 5.4 KB
/
Copy pathGet-ExploitProtectionEvents.ps1
File metadata and controls
164 lines (134 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<#
.SYNOPSIS
Queries and analyzes Exploit Protection (Security-Mitigations) event logs.
.DESCRIPTION
Retrieves events from Microsoft-Windows-Security-Mitigations/KernelMode and
Microsoft-Windows-Security-Mitigations/UserMode logs. Filters audit and block
events by process name, event ID, time window, or action type (Audit vs Block).
Standard Exploit Protection Event IDs:
- 1 / 2 : Dynamic Code (ACG) [Audit / Block]
- 3 / 4 : Child Process Restrictions [Audit / Block]
- 5 / 6 : Low Integrity Image Loads [Audit / Block]
- 7 / 8 : Remote (UNC) Image Loads [Audit / Block]
- 9 / 10 : Win32k System Calls [Audit / Block]
- 11 / 12 : Code Integrity / Module Dependency Signing [Audit / Block]
- 23 / 24 : Hardware-enforced Stack Protection (CET) [Audit / Block]
- 33 / 34 : Non-System Font Restrictions [Audit / Block]
.PARAMETER ProcessName
Filter by executable name or pattern (e.g. 'chrome.exe', 'vlc*').
.PARAMETER Hours
Retrieve events from the last N hours. Default is 24. Ignored if -All is specified.
.PARAMETER All
Retrieve all historical events without time limit.
.PARAMETER Action
Filter events by action type: 'All', 'Audit', or 'Block'. Default is 'All'.
.PARAMETER EventId
Filter by specific event IDs.
.EXAMPLE
.\Get-ExploitProtectionEvents.ps1 -Hours 48
Displays all exploit protection events in the last 48 hours.
.EXAMPLE
.\Get-ExploitProtectionEvents.ps1 -Action Block
Displays only blocked mitigation events.
.EXAMPLE
.\Get-ExploitProtectionEvents.ps1 -ProcessName 'vlc*' -Action Audit
Displays audit events for processes matching 'vlc*'.
#>
[CmdletBinding()]
param (
[Parameter(Position = 0)]
[string]$ProcessName,
[Parameter()]
[int]$Hours = 24,
[Parameter()]
[switch]$All,
[Parameter()]
[ValidateSet('All', 'Audit', 'Block')]
[string]$Action = 'All',
[Parameter()]
[int[]]$EventId
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$logs = @(
'Microsoft-Windows-Security-Mitigations/KernelMode',
'Microsoft-Windows-Security-Mitigations/UserMode'
)
$mitigationMap = @{
1 = @{ Name = 'Dynamic Code'; Action = 'Audit' }
2 = @{ Name = 'Dynamic Code'; Action = 'Block' }
3 = @{ Name = 'Child Process'; Action = 'Audit' }
4 = @{ Name = 'Child Process'; Action = 'Block' }
5 = @{ Name = 'Low Integrity Image'; Action = 'Audit' }
6 = @{ Name = 'Low Integrity Image'; Action = 'Block' }
7 = @{ Name = 'Remote Image'; Action = 'Audit' }
8 = @{ Name = 'Remote Image'; Action = 'Block' }
9 = @{ Name = 'Win32k System Calls'; Action = 'Audit' }
10 = @{ Name = 'Win32k System Calls'; Action = 'Block' }
11 = @{ Name = 'Code Integrity / Signing'; Action = 'Audit' }
12 = @{ Name = 'Code Integrity / Signing'; Action = 'Block' }
23 = @{ Name = 'User Shadow Stack (CET)'; Action = 'Audit' }
24 = @{ Name = 'User Shadow Stack (CET)'; Action = 'Block' }
33 = @{ Name = 'Non-System Fonts'; Action = 'Audit' }
34 = @{ Name = 'Non-System Fonts'; Action = 'Block' }
}
$startTime = if ($All) { [DateTime]::MinValue } else { (Get-Date).AddHours(-$Hours) }
$results = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($log in $logs) {
try {
$filter = @{
LogName = $log
StartTime = $startTime
}
if ($EventId -and $EventId.Count -gt 0) {
$filter['Id'] = $EventId
}
$events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue
if (-not $events) { continue }
foreach ($evt in $events) {
$id = $evt.Id
$known = $mitigationMap[$id]
$mitigationName = if ($known) { $known.Name } else { "Mitigation ($id)" }
$actionType = if ($known) { $known.Action } else { if ($id % 2 -eq 1) { 'Audit' } else { 'Block' } }
# Filter by Action if requested
if ($Action -ne 'All' -and $actionType -ne $Action) {
continue
}
# Parse process info from message or XML
$msg = $evt.Message
$proc = 'Unknown'
$pidVal = $null
if ($msg -match "Process '(?<path>[^']+)'(?: \(PID (?<pid>\d+)\))?") {
$rawPath = $Matches['path']
$proc = Split-Path -Leaf $rawPath
$pidVal = $Matches['pid']
}
elseif ($msg -match "Process (?<proc>[^\s]+) \(PID (?<pid>\d+)\)") {
$proc = Split-Path -Leaf $Matches['proc']
$pidVal = $Matches['pid']
}
# Filter by ProcessName if specified
if ($ProcessName -and ($proc -notlike $ProcessName)) {
continue
}
$results.Add([PSCustomObject]@{
TimeCreated = $evt.TimeCreated
EventId = $id
Action = $actionType
Mitigation = $mitigationName
ProcessName = $proc
ProcessId = $pidVal
LogSource = (Split-Path -Leaf $log)
MessageSummary = ($msg -split "`r?`n")[0]
})
}
}
catch {
Write-Verbose "Could not query log $log : $_"
}
}
if ($results.Count -eq 0) {
Write-Host "No matching Exploit Protection events found." -ForegroundColor Yellow
return
}
$results | Sort-Object TimeCreated -Descending