Skip to content

Instantly share code, notes, and snippets.

function Get-ProcessStartKey {
<#
.SYNOPSIS
Derives the process start key for one or more processes.
.DESCRIPTION
Get-ProcessStartKey derives the process start key for one or more processes. Process start keys were introduced in Win 10 1507 and are intended to serve as a locally unique identifier for a process. A process ID cannot be considered a unique identifier since process IDs are repeatable.
@mattifestation
mattifestation / NiftyETWProviders.json
Created December 21, 2018 19:27
ETW providers you never knew existed...
[
{
"ProviderGUID": "72d164bf-fd64-4b2b-87a0-62dbcec9ae2a",
"ProviderName": "AccEventTool",
"ProviderGroupGUID": "4f50731a-89cf-4782-b3e0-dce8c90476ba",
"AssociatedFilenames": [
"accevent.exe",
"inspect.exe",
"narrator.exe",
"srh.dll"
@mattifestation
mattifestation / TLGMetadataParser.psm1
Last active April 17, 2025 14:01
Retrieves TraceLogging metadata from a file.
#requires -version 5
<#
The things you find on Google searching for specific GUIDs...
Known Keyword friendly names:
"UTC:::CATEGORYDEFINITION.MS.CRITICALDATA":"140737488355328"
"UTC:::CATEGORYDEFINITION.MS.MEASURES":"70368744177664"
"UTC:::CATEGORYDEFINITION.MS.TELEMETRY":"35184372088832"
"UTC:::CATEGORYDEFINITION.MSWLAN.CRITICALDATA":"2147483648"
@mattifestation
mattifestation / amsi.tmf
Last active March 6, 2022 20:11
A hand-crafted, artisanal WPP TMF file for amsi.dll
68fdd900-4a3e-11d1-84f4-0000f80464e3 EventTrace
#typev Header 0 "%0EventTrace"
{
BufferSize, ItemULong //10
Version, ItemULong //11
BuildNumber, ItemULong //12
NumProc, ItemULong //13
EndTime, ItemULongLong //14
TimerResolution,ItemULong //15
MaxFileSize, ItemULong //16
@mattifestation
mattifestation / CorruptCLRGlobal.ps1
Created December 7, 2018 12:45
A PoC function to corrupt the g_amsiContext global variable in clr.dll in .NET Framework Early Access build 3694
function Subvert-CLRAntiMalware {
<#
.SYNOPSIS
A proof-of-concept demonstrating overwriting a global variable that stores a pointer to an antimalware scan interface context structure. This PoC was only built to work with .NET Framework Early Access build 3694.
.DESCRIPTION
clr.dll in .NET Framework Early Access build 3694 has a global variable that stores a pointer to an antimalware scan interface context structure. By reading the pointer at that offset and then overwriting the forst DWORD, the context structure will become corrupted and subsequent scanning calls will fail open.
@mattifestation
mattifestation / EnableAMSILogging.ps1
Last active October 29, 2022 14:28
Enables AMSI logging to the AMSI/Operational event log
$AutoLoggerName = 'MyAMSILogger'
$AutoLoggerGuid = "{$((New-Guid).Guid)}"
New-AutologgerConfig -Name $AutoLoggerName -Guid $AutoLoggerGuid -Start Enabled
Add-EtwTraceProvider -AutologgerName $AutoLoggerName -Guid '{2A576B87-09A7-520E-C21A-4942F0271D67}' -Level 0xff -MatchAnyKeyword ([UInt64] (0x8000000000000001 -band ([UInt64]::MaxValue))) -Property 0x41
@mattifestation
mattifestation / CollectDotNetEvents.ps1
Created August 27, 2018 21:50
A PoC script to capture relevant .NET runtime artifacts for the purposes of potential detections
logman --% start dotNetTrace -p Microsoft-Windows-DotNETRuntime (JitKeyword,NGenKeyword,InteropKeyword,LoaderKeyword) win:Informational -o dotNetTrace.etl -ets
# Do your evil .NET thing now. In this example, I executed the Microsoft.Workflow.Compiler.exe bypass
# logman stop dotNetTrace -ets
# This is the process ID of the process I want to capture. In this case, Microsoft.Workflow.Compiler.exe
# I got the process ID by running a procmon trace
$TargetProcessId = 8256
@mattifestation
mattifestation / WorkflowCompilerDetectionTests.ps1
Created August 20, 2018 21:33
Microsoft.Workflow.Compiler.exe bypass technique detection test suite
function Test-MSWorkflowCompilerDetection {
[CmdletBinding()]
param (
[String]
[ValidateNotNullOrEmpty()]
$Arg1FileName = 'Test.xml',
[String]
[ValidateNotNullOrEmpty()]
$Arg2FileName = 'Results.xml',
@mattifestation
mattifestation / EmulateProcExpDotNetEnumeration.ps1
Created July 26, 2018 18:50
Replicates the data collected when enumerating .NET Assemblies in Process Explorer
logman start trace dotNetAssemblyTrace2 -p "Microsoft-Windows-DotNETRuntimeRundown" "LoaderRundownKeyword, StartRundownKeyword" win:Informational -o dotNetAssemblyTrace2.etl -ets
Start-Sleep -Seconds 5
logman stop dotNetAssemblyTrace2 -ets
$EnumeratedCLRRuntimes = Get-WinEvent -Path .\dotNetAssemblyTrace2.etl -Oldest -FilterXPath '*[System[(EventID=187)]]'
$EnumeratedAppDomains = Get-WinEvent -Path .\dotNetAssemblyTrace2.etl -Oldest -FilterXPath '*[System[(EventID=157)]]'
$EnumeratedAssemblies = Get-WinEvent -Path .\dotNetAssemblyTrace2.etl -Oldest -FilterXPath '*[System[(EventID=155)]]'
$EnumeratedModules = Get-WinEvent -Path .\dotNetAssemblyTrace2.etl -Oldest -FilterXPath '*[System[(EventID=153)]]'
@mattifestation
mattifestation / SysmonEventGUIDParser.ps1
Last active April 23, 2025 13:16
Extracts fields from sysmon process and logon GUIDs
# Author: Matthew Graeber (@mattifestation)
$Epoch = Get-Date '01/01/1970'
# Conversion trick taken from https://blogs.technet.microsoft.com/heyscriptingguy/2017/02/01/powertip-convert-from-utc-to-my-local-time-zone/
$StrCurrentTimeZone = (Get-WmiObject Win32_timezone).StandardName
$TZ = [TimeZoneInfo]::FindSystemTimeZoneById($StrCurrentTimeZone)
# Parse out all the LogonGUID fields for sysmon ProcessCreate events
Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-Sysmon/Operational'; Id = 1 } | ForEach-Object {