Created
May 8, 2024 14:57
-
-
Save egglessness/5035c5b3c1c849b51b596a0ca809f6a4 to your computer and use it in GitHub Desktop.
Parse UAC consent prompt events with information about the called process
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
$ScanResultsPath = ".\UacPrompts.csv" | |
$DateFormat = "yyyyMMddHHmmss" | |
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") | |
if (-not $isAdmin) { | |
Write-Host "You must run this script with administrator privileges!" | |
exit | |
} | |
$isAuditEnabled = auditpol /get /subcategory:"{0CCE922B-69AE-11D9-BED3-505054503030}" | select-string "Success" -Quiet | |
if ($isAuditEnabled -ne $true) { | |
Write-Warning "Process Creation audit logging has not been enabled. Details will not be available." | |
} | |
try { | |
$ScanResults = Import-Csv -Path $ScanResultsPath | |
if (-not ($ScanResults -is [System.Array])) { | |
$ScanResults = @($ScanResults) | |
} | |
$LastScanDate = [datetime]::ParseExact($ScanResults[0].Timestamp, $DateFormat, $null) | |
Write-Host "Found data from previous scan. Last collected event was at" $LastScanDate | |
} | |
catch { | |
$ScanResults = @() | |
$LastScanDate = $null | |
} | |
Write-Host "Collecting UAC Consent Prompt events (EventID: 4624, ProcessName: consent.exe, ElevatedToken: Yes) ..." | |
$AllUacPrompts = Get-WinEvent -FilterXml @" | |
<QueryList> | |
<Query Id='0' Path='Security'> | |
<Select Path='Security'> | |
*[System[(EventID=4624)] and EventData[Data[@Name='ProcessName']='C:\Windows\System32\consent.exe'] and EventData[Data[@Name='ElevatedToken']='%%1842']] | |
</Select> | |
</Query> | |
</QueryList> | |
"@ | |
if ($LastScanDate) { | |
$UacPrompts = $AllUacPrompts | Where-Object { $_.TimeCreated -gt $LastScanDate.AddSeconds(1) } | |
} | |
else { | |
$UacPrompts = $AllUacPrompts | |
} | |
Write-Host "Correlating with Process Creation events (EventID: 4688, MandatoryLabel: High) ..." | |
$Results = @() | |
foreach ($UacPrompt in $UacPrompts) { | |
$FromTime = $UacPrompt.TimeCreated.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.000Z") | |
$ToTime = $UacPrompt.TimeCreated.AddSeconds(1).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.000Z") | |
$ProcessCreationEvent = Get-WinEvent -FilterXml @" | |
<QueryList> | |
<Query Id='0' Path='Security'> | |
<Select Path='Security'> | |
*[System[(EventID=4688) and (TimeCreated[@SystemTime>'$FromTime' and @SystemTime<'$ToTime'])]] | |
and | |
*[EventData[Data[@Name='MandatoryLabel']='S-1-16-12288' or Data[@Name='MandatoryLabel']='S-1-16-16384']] | |
</Select> | |
</Query> | |
</QueryList> | |
"@ -ErrorAction SilentlyContinue | Sort-Object TimeCreated | Select-Object -First 1 | |
try { | |
$Results += [PSCustomObject]@{ | |
Timestamp = $UacPrompt.TimeCreated.ToString($DateFormat) | |
Computer = $ProcessCreationEvent.Properties[1].Value | |
Domain = $ProcessCreationEvent.Properties[11].Value | |
User = $ProcessCreationEvent.Properties[10].Value | |
Process = $ProcessCreationEvent.Properties[5].Value | |
} | |
} | |
catch { | |
$Results += [PSCustomObject]@{ | |
Timestamp = $UacPrompt.TimeCreated.ToString($DateFormat) | |
Computer = $null | |
Domain = $null | |
User = $null | |
Process = $null | |
} | |
} | |
} | |
Write-Host "Found" $Results.Length "new events." | |
$Results | Format-Table | |
if ($Results.Length -gt 0) { | |
$ScanResults + $Results | Sort-Object Timestamp -Descending | Export-Csv -Path $ScanResultsPath -NoTypeInformation | |
Write-Host "Scan results saved on file:" $ScanResultsPath | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found out that this script does not work on Windows 11, where the UAC interactions are a little bit different.
If you happen to have Defender for Endpoint installed on the machines you want to monitor, you can track UAC elevation prompts just by using the following KQL query to extract the same data for any version of Windows: