Skip to content

Instantly share code, notes, and snippets.

@cobbr
Forked from mattifestation/CollectDotNetEvents.ps1
Last active January 24, 2019 01:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cobbr/1bab9e175ebbc6ff93cc5875c69ecc50 to your computer and use it in GitHub Desktop.
Save cobbr/1bab9e175ebbc6ff93cc5875c69ecc50 to your computer and use it in GitHub Desktop.
A PoC script to capture relevant .NET runtime artifacts for the purposes of potential detections
function Start-DotNetEventCollection
{
Param(
[Parameter(Position = 0)]
[Alias('PSPath')]
[String] $TracePath = './dotNetTrace.etl',
[Parameter(Position = 1)]
[String] $TraceName = 'dotNetTrace'
)
Process
{
try
{
$Command = "logman --% start $TraceName -p Microsoft-Windows-DotNETRuntime (JitKeyword,NGenKeyword,InteropKeyword,LoaderKeyword) win:Informational -o $TracePath -ets"
Write-Verbose $Command
$Output = iex $Command
Write-Verbose $Output
}
catch
{
Write-Error $_
}
[PSCustomObject] @{
TraceName = $TraceName
TracePath = $TracePath
}
}
}
function Stop-DotNetEventCollection
{
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName)]
[String] $TraceName = 'dotNetTrace'
)
Process
{
logman stop $TraceName -ets
}
}
function Get-DotNetEvents
{
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName)]
[Alias('PID', 'Id')]
[int] $ProcessID,
[Parameter(Position = 1, Mandatory, ValueFromPipelineByPropertyName)]
[Alias('PSPath')]
[String] $TracePath = './dotNetTrace.etl'
)
Process
{
$TargetProcessId = $ProcessID
$WorkflowCompilerEvents = Get-WinEvent -Path $TracePath -Oldest -FilterXPath "*[System[Execution[@ProcessID=$TargetProcessId]]]"
# Group events by event ID
$EventIDGrouping = $WorkflowCompilerEvents | Sort Id | Group Id
# Event ID 143 corresponds to the following ETW provider keyword: JitKeyword, NGenKeyword
$MethodLoadVerboseEvents = $EventIDGrouping | ? { $_.Name -eq '143' }
$MethodsCalled = $MethodLoadVerboseEvents.Group | % {
$Namespace = $_.Properties[6].Value
$Method = $_.Properties[7].Value
$MethodComponent0 = $_.Properties[8].Value.Split('(')[0].TrimEnd()
$MethodComponent1 = $_.Properties[8].Value.Split('(')[1]
"$($MethodComponent0) $($Namespace)$($Method)($($MethodComponent1)"
}
# Event ID 88 corresponds to the following ETW provider keyword: InteropKeyword
$ILStubStubGeneratedEvents = $EventIDGrouping | ? { $_.Name -eq '88' }
$MarshaledNativeMethods = $ILStubStubGeneratedEvents.Group | % {
$Namespace = $_.Properties[5].Value
$Method = $_.Properties[6].Value
$ReturnVal = $_.Properties[7].Value.Split('(')[0].TrimEnd()
$Signature = $_.Properties[7].Value.Split('(')[1]
"$($ReturnVal) $($Namespace).$($Method)($($Signature)"
}
# Event ID 151 corresponds to the following ETW provider keyword: LoaderKeyword
$LoaderDomainModuleLoadEvents = $EventIDGrouping | ? { $_.Name -eq '151' }
$ModuleLoads = $LoaderDomainModuleLoadEvents.Group | % {
$_.Properties[5].Value
}
# Event ID 154 corresponds to the following ETW provider keyword: LoaderKeyword
$LoaderAssemblyLoadEvents = $EventIDGrouping | ? { $_.Name -eq '154' }
$AssemblyLoads = $LoaderAssemblyLoadEvents.Group | % {
$_.Properties[4].Value
}
# Event ID 157 corresponds to the following ETW provider keyword: LoaderKeyword
$LoaderAppDomainUnloadEvents = $EventIDGrouping | ? { $_.Name -eq '157' }
$AppDomainUnloadLoads = $LoaderAppDomainUnloadEvents.Group | % {
$_.Properties[2].Value
}
# Event ID 187 corresponds to the following ETW provider keyword: LoaderKeyword
$RuntimeStartEvents = $EventIDGrouping | ? { $_.Name -eq '187' }
$CommandLines = $RuntimeStartEvents.Group | % {
$_.Properties[12].Value
}
[PSCustomObject] @{
ProcessID = $TargetProcessId
CommandLine = $CommandLines
AppDomainsLoaded = $AppDomainUnloadLoads
AssembliesLoaded = $AssemblyLoads
ModulesLoaded = $ModuleLoads
ManagedMethodsCalled = $MethodsCalled
PInvokeMethodsCalled = $MarshaledNativeMethods
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment