Last active
May 27, 2019 12:59
-
-
Save mgreen27/597579a200d6c20b53203bcd218d9b06 to your computer and use it in GitHub Desktop.
Get-AMSIEvents
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
Function Get-AMSIEvents | |
{ | |
<# | |
.SYNOPSIS | |
Get-AMSIEvents collects AMSI events during interval. | |
Name: Get-AMSIEvents.ps1 | |
Version: 0.1 | |
Date: 2019-05-26 | |
Requirements: Windows 10. Office2019 for VBA | |
.DESCRIPTION | |
Get-AMSIEvents collects AMSI events during interval. | |
Will log all AMSI events including Powershell, vbscript, jscript and VBA. | |
.EXAMPLE | |
Get-AMSIEvents | |
Will Run collection start. When complete results will return variable $AMSIEvents. | |
.EXAMPLE | |
Get-AMSIEvents -Path C:\Users\REM\Desktop\2019-05-26AMSITrace.etl | |
Will parse a precollected AMSI trace Log. When complete results will return variable $AMSIEvents. | |
.NOTES | |
Initial AMSI parsing POC from Matt Graeber @Mattifestation | |
https://gist.github.com/mattifestation/e179218d88b5f100b0edecdec453d9be#file-amsiscriptcontentretrieval-ps1 | |
#> | |
[CmdletBinding()] | |
Param( | |
[Parameter(Mandatory = $False)][String]$Path | |
) | |
Write-Host -ForegroundColor Cyan "`nGet-AMSIEvents" | |
Write-Host -ForegroundColor White "`tA tool to collect AMSI events leveraging Event Tracing for Windows" | |
# Set switches | |
If ($PSBoundParameters.ContainsKey("Path")){ | |
If (Test-Path $Path) { | |
$tracePath = $Path | |
Write-Host -ForegroundColor White "Path is $tracePath`n" | |
} | |
Else { | |
Write-Host -ForegroundColor Red "$Path not found" | |
exit | |
} | |
} | |
Else { | |
# Test for Elevated privilege if to enable AMSI | |
If (!(([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))){ | |
Write-Host -ForegroundColor Red "Exiting Get-AMSIEvents: Elevated privilege required." | |
exit | |
} | |
$date = get-date ([DateTime]::UtcNow) -format yyyy-MM-dd | |
$tracePath = [Environment]::GetFolderPath("Desktop") + "\" + $date + "AMSITrace.etl" | |
$traceName = "AMSITrace" | |
If (Test-Path $tracePath) { Remove-item -Path $tracePath -Force } | |
Write-Host "`tPath: $tracePath`n" | |
logman start $traceName -p Microsoft-Antimalware-Scan-Interface Event1 -o $tracePath -ets | Out-Null | |
Write-Host -ForegroundColor Yellow "`tCollecting AMSI Events." | |
Write-Host "`tRun payloads and " -NoNewline | |
Pause | |
logman stop $traceName -ets | Out-Null | |
} | |
$OSArchProperty = Get-CimInstance -ClassName Win32_OperatingSystem -Property OSArchitecture | |
$OSArch = $OSArchProperty.OSArchitecture | |
$OSPointerSize = 32 | |
if ($OSArch -eq '64-bit') { $OSPointerSize = 64 } | |
Try { | |
$ErrorActionPreference = “silentlycontinue” | |
$AMSIEvents = $null | |
$AMSIEvents = Get-WinEvent -Path $tracePath -Oldest -FilterXPath '*[System[EventID=1101]]' | ForEach-Object { | |
if (-not $_.Properties) { | |
# The AMSI provider is not supplying the contentname property when WSH content is logged resulting | |
# in Get-WinEvent or Event Viewer being unable to parse the data based on the schema. | |
# If this bug were not present, retrieving WSH content would be trivial. | |
$PayloadString = ([Xml] $_.ToXml()).Event.ProcessingErrorData.EventPayload | |
[Byte[]] $PayloadBytes = ($PayloadString -split '([0-9A-F]{2})' | Where-Object {$_} | ForEach-Object {[Byte] "0x$_"}) | |
$MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$PayloadBytes) | |
$BinaryReader = New-Object -TypeName IO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode) | |
switch ($OSPointerSize) { | |
32 { $Session = $BinaryReader.ReadUInt32() } | |
64 { $Session = $BinaryReader.ReadUInt64() } | |
} | |
$ScanStatus = $BinaryReader.ReadByte() | |
$ScanResult = $BinaryReader.ReadInt32() | |
$StringBuilder = New-Object -TypeName Text.StringBuilder | |
do { $CharVal = $BinaryReader.ReadInt16(); $null = $StringBuilder.Append([Char] $CharVal) } while ($CharVal -ne 0) | |
$AppName = $StringBuilder.ToString() | |
$null = $StringBuilder.Clear() | |
$ContentSize = $BinaryReader.ReadInt32() | |
$OriginalSize = $BinaryReader.ReadInt32() | |
$ContentRaw = $BinaryReader.ReadBytes($ContentSize) | |
$Content = [Text.Encoding]::Unicode.GetString($ContentRaw) | |
$Hash = [BitConverter]::ToString($BinaryReader.ReadBytes(0x20)).Replace('-', '') | |
[Bool] $ContentFiltered = $BinaryReader.ReadInt32() | |
$BinaryReader.Close() | |
[PSCustomObject] @{ | |
Session = $Session | |
ScanStatus = $ScanStatus | |
ScanResult = $ScanResult | |
AppName = $AppName | |
ContentName = $null | |
Content = $Content | |
Hash = $Hash | |
ContentFiltered = $ContentFiltered | |
} | |
} else { | |
$Session = $_.Properties[0].Value | |
$ScanStatus = $_.Properties[1].Value | |
$ScanResult = $_.Properties[2].Value | |
$AppName = $_.Properties[3].Value | |
$ContentName = $_.Properties[4].Value | |
$Content = [Text.Encoding]::Unicode.GetString($_.Properties[7].Value) | |
$Hash = [BitConverter]::ToString($_.Properties[8].Value).Replace('-', '') | |
$ContentFiltered = $_.Properties[9].Value | |
[PSCustomObject] @{ | |
Session = $Session | |
ScanStatus = $ScanStatus | |
ScanResult = $ScanResult | |
AppName = $AppName | |
ContentName = $ContentName | |
Content = $Content | |
Hash = $Hash | |
ContentFiltered = $ContentFiltered | |
} | |
} | |
} | |
If ( $AMSIEvents.count -gt 0 ) { return $AMSIEvents } | |
Else { Write-host -ForegroundColor White "`tNo AMSI events found." } | |
} | |
Catch { Write-Host -ForegroundColor Yellow "Looks like there are no events... please try again." } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment