Skip to content
Please update to the latest release 0.77.3 to address Multiple CVEs.
Windows.ETW.Powershell
Edit this artifact

Windows.ETW.Powershell

This artifact enables Powershell scriptblock and commandlet load monitoring.
It uses the ETW provider: Microsoft-Windows-PowerShell

Detection logic is managed by several global ignore entries and an IOC csv.

Global Ignore

IgnoreProcessExe - Process exe path to ignore
IgnoreParentProcessExe - Parent exe path for child generated events to ignore
IgnoreParentProcessName - Ignore events generated by a child process

IocCsv

Name - detection name
Type - type of detection: ScriptBlock,Commandlet or ScriptBlock|Commandlet
Regex - regex to search for
Ignore - regex to ignore
DateModified - date detection last modified


name: Windows.ETW.Powershell
author: Matt Green - @mgreen27
description: |
    This artifact enables Powershell scriptblock and commandlet load monitoring.  
    It uses the ETW provider: Microsoft-Windows-PowerShell  
    
    Detection logic is managed by several global ignore entries and an IOC csv.  

    ##### Global Ignore  
    IgnoreProcessExe - Process exe path to ignore  
    IgnoreParentProcessExe - Parent exe path for child generated events to ignore  
    IgnoreParentProcessName - Ignore events generated by a child process 
      
    ##### IocCsv 
    Name - detection name  
    Type - type of detection: ScriptBlock,Commandlet or ScriptBlock|Commandlet  
    Regex - regex to search for  
    Ignore - regex to ignore  
    DateModified - date detection last modified  
    

type: CLIENT_EVENT

parameters:
  - name: IgnoreProcessExe
    description: Regex of process exe path to ignore
    default: \\Program Files\\(Microsoft Monitoring Agent\\Agent|Microsoft System Center\\Operations Manager\\Server)\\MonitoringHost\.exe$
  - name: IgnoreParentProcessExe
    description: Regex of parent exe path for child generated events to ignore
    default: ^(C:\\Program Files\\Windows Defender Advanced Threat Protection\\SenseIR\.exe|C:\\Program Files\\Microsoft SQL Server\\MSSQL\d{1,2}\.MSSQLSERVER\\MSSQL\\Binn\\SQLAGENT\.EXE)$
  - name: IgnorePaths
    description: "List of path regex to ignore. This list will be joined and excluded."
    default: |
        \\SDIAG_.{8}-(.{4}-){3}.{12}\\
        \\Windows Defender Advanced Threat Protection\\
        \\Microsoft Azure Backup Server\\
        \\Program Files\\Microsoft Dependency Agent\\
        \\(Program Files|ProgramData)\\Amazon\\(WorkSpaces|EC2-Windows)
        \\Program Files(|\(x86\))\\Symantec\\Symantec Endpoint
        \\Program Files(|\(x86\))\\Automox\\execDir
  - name: IocCsv
    type: csv
    description: "Application name Regex to enable filtering on source."
    default: |
        Name,Type,Regex,Ignore,DateModified
        T1059.001-Mimikatz Execution via PowerShell,ScriptBlock,TOKEN_PRIVILE|SE_PRIVILEGE_ENABLED|mimikatz|lsass.dmp,,12/8/2022
        T1059.001-Cobalt Strike Powershell Loader,ScriptBlock,\$Doit|-bxor 35,,12/8/2022
        TT1562-Impair Defences,ScriptBlock,powershell -version 2|Set-PSReadlineOption|-HistorySaveStyle SaveNothing|remove-module +psreadline|[Amsi]::Bypass()|{2781761E-28E0-4109-99FE-B9D127C57AFE}|amsiInitFailed|System.Management.Automation.AmsiUtils|Remove-EtwTraceProvider|System.Management.Automation.Tracing.PSEtwLogProvider|HKLM.SYSTEM.CurrentControlSet.Control.WMI.Autologger.AUTOLOGGER_NAME,,23/8/2022
        T1562.001-Win Defender Disable using Powershell,ScriptBlock,Set-MpPreference -DisableRealtimeMonitoring|Set-MpPreference DisableBehaviorMonitoring|Set-MpPreference -DisableScriptScanning|Set-MpPreference -DisableBlockAtFirstSeen|MpPreference -ExclusionPath,,12/8/2022
        T1059.001-Malicious Powershell Commandlets,Commandlet,Add-ConstrainedDelegationBackdoor|Add-DomainObjectAcl|Add-Exfiltration|Add-ObjectAcl|Add-Persistance|Add-Persistence|Add-RegBackdoor|Add-RemoteConnection|Add-ScrnSaveBackdoor|Add-ServiceDacl|Add-SignedIntAsUnsigned|Bloodhound|Check-VM|Convert-ADName|Convert-DNSRecord|Convert-FileRight|Convert-LDAPProperty|Convert-NameToSid|Convert-SwitchtoBool|Convert-UIntToInt|ConvertFrom-LDAPLogonHours|ConvertFrom-SID|ConvertFrom-UACValue|ConvertTo-LittleEndian|ConvertTo-LogonHoursArray|ConvertTo-RC4ByteStream|ConvertTo-SID|Copy-ArrayOfMemAddresses|Copy-VSS|Create-MultipleSessions|Create-NamedPipe|Create-ProcessWithToken|Create-RemoteThread|Create-SuspendedWinLogon|Create-WinLogonProcess|DataToEncode|Decrypt-Bytes|DNS_TXT_Pwnage|Do-Exfiltration|Download_Execute|Download-Execute-PS|DumpCerts|DumpCreds|Emit-CallThreadStub|Enable-Duplication|Enable-Privilege|Enable-SeAssignPrimaryTokenPrivilege|Enable-SeDebugPrivilege|Enabled-DuplicateToken|Enum-AllTokens|Exclude-Hosts|Execute-Command-MSSQL|Execute-DNSTXT-Code|Execute-OnTime|ExetoText|exfill|ExfilOption|Expand-Archive|Exploit-Jboss|Export-PowerViewCSV|FakeDC|Find-4624Logon|Find-4648Logon|Find-AppLockerLog|Find-AVSignature|Find-DomainLocalGroupMember|Find-DomainObjectPropertyOutlier|Find-DomainProcess|Find-DomainShare|Find-DomainUserEvent|Find-DomainUserLocation|Find-ForeignGroup|Find-ForeignUser|Find-Fruit|Find-GPOComputerAdmin|Find-GPOLocation|Find-InterestingDomainAcl|Find-InterestingDomainShareFile|Find-InterestingFile|Find-LocalAdminAccess|Find-ManagedSecurityGroups|Find-PathDLLHijack|Find-ProcessDLLHijack|Find-PSScriptsInPSAppLog|Find-RDPClientConnection|Find-TrustedDocuments|FireBuster|FireListener|Free-AllTokens|Get-ADObject|Get-AllAttributesForClass|Get-ApplicationHost|Get-CachedGPPPassword|Get-CachedRDPConnection|Get-ChromeDump|Get-ClipboardContents|Get-ComputerDetail|Get-DecryptedCpassword|Get-DecryptedSitelistPassword|Get-DelegateType|Get-DFSshare|Get-DNSRecord|Get-DNSZone|Get-Domain|Get-DomainComputer|Get-DomainController|Get-DomainDFSShare|Get-DomainDFSShareV1|Get-DomainDFSShareV2|Get-DomainDNSRecord|Get-DomainDNSZone|Get-DomainFileServer|Get-DomainForeignGroupMember|Get-DomainForeignUser|Get-DomainGPO|Get-DomainGPOComputerLocalGroupMapping|Get-DomainGPOLocalGroup|Get-DomainGPOUserLocalGroupMapping|Get-DomainGroup|Get-DomainGroupMember|Get-DomainGroupMemberDeleted|Get-DomainGUIDMap|Get-DomainManagedSecurityGroup|Get-DomainObject|Get-DomainOU|Get-DomainPolicy|Get-DomainSearcher|Get-DomainSID|Get-DomainSite|Get-DomainSPNTicket|Get-DomainSubnet|Get-DomainTrust|Get-DomainTrustMapping|Get-DomainUser|Get-DomainUserEvent|Get-Forest|Get-ForestDomain|Get-ForestGlobalCatalog|Get-ForestSchemaClass|Get-ForestTrust|Get-FoxDump|Get-GPODelegation|Get-GPPInnerField|Get-GPPPassword|Get-GptTmpl|Get-GroupsXML|Get-Hex|Get-HttpStatus|Get-ImageNtHeaders|Get-IndexedItem|Get-Information|Get-IniContent|Get-IPAddress|Get-Keystrokes|Get-LastLoggedOn|Get-LoggedOnLocal|Get-LSASecret|Get-MemoryProcAddress|Get-MicrophoneAudio|Get-ModifiablePath|Get-ModifiableRegistryAutoRun|Get-ModifiableScheduledTaskFile|Get-ModifiableService|Get-ModifiableServiceFile|Get-NetComputer|Get-NetComputerSiteName|Get-NetDomain|Get-NetDomainController|Get-NetDomainTrust|Get-NetFileServer|Get-NetForest|Get-NetGPO|Get-NetGroup|Get-NetGroupMember|Get-NetLocalGroup|Get-NetLoggedon|Get-NetOU|Get-NetProcess|Get-NetRDPSession|Get-NetSession|Get-NetShare|Get-NetSite|Get-NetSubnet|Get-NetUser|Get-ObjectAcl|Get-PassHashes|Get-PassHints|Get-PathAcl|Get-PEArchitecture|Get-PEBasicInfo|Get-PEDetailedInfo|Get-PrimaryToken|Get-PrincipalContext|Get-ProcAddress|Get-ProcessTokenGroup|Get-ProcessTokenPrivilege|Get-ProcessTokenType|Get-Property|Get-Proxy|Get-RandomName|Get-RegAlwaysInstallElevated|Get-RegAutoLogon|Get-RegistryAlwaysInstallElevated|Get-RegistryAlwaysInstallElevated.|Get-RegistryAutoLogon|Get-RegistryMountedDrive|Get-RegLoggedOn|Get-RemoteProcAddress|Get-RemoteProcAddressFunction|Get-RickAstley|Get-Screenshot|Get-SecurityPackages|Get-ServiceDetail|Get-ServiceFilePermission|Get-ServicePermission|Get-ServiceUnquoted|Get-SitelistField|Get-SiteListPassword|Get-SiteName|Get-System|Get-SystemNamedPipe|Get-SystemToken|Get-ThreadToken|Get-TimedScreenshot|Get-TokenInformation|Get-TopPort|Get-UnattendedInstallFile|Get-Unconstrained|Get-UniqueTokens|Get-UnquotedService|Get-USBKeystrokes|Get-UserEvent|Get-VaultCredential|Get-VaultElementValue|Get-VirtualProtectValue|Get-VolumeShadowCopy|Get-VulnAutoRun|Get-VulnSchTask|Get-Web-Credentials|Get-WebConfig|Get-Win32Constants|Get-Win32Functions|Get-Win32Types|Get-WLAN-Keys|Get-WMIProcess|Get-WMIRegCachedRDPConnection|Get-WMIRegLastLoggedOn|Get-WMIRegMountedDrive|Get-WMIRegProxy|Gupt-Backdoor|HTTP-Backdoor|HTTP-Login|Import-DllImports|Import-DllInRemoteProcess|Inject-LocalShellcode|Inject-RemoteShellcode|Install-ServiceBinary|Install-SSP|InttoIP|Invoke-ACLScanner|Invoke-ADSBackdoor|Invoke-AllChecks|Invoke-AmsiBypass|Invoke-ARPScan|Invoke-AzureHound|Invoke-BackdoorLNK|Invoke-BadPotato|Invoke-BetterSafetyKatz|Invoke-BruteForce|Invoke-BypassUAC|Invoke-Carbuncle|Invoke-Certify|Invoke-CheckLocalAdminAccess|Invoke-CompareAttributesForClass|Invoke-CreateRemoteThread|Invoke-CredentialInjection|Invoke-CredentialsPhish|Invoke-DAFT|Invoke-DCSync|Invoke-Decode|Invoke-DinvokeKatz|Invoke-DllInjection|Invoke-DowngradeAccount|Invoke-EgressCheck|Invoke-Empire|Invoke-Encode|Invoke-EnumerateLocalAdmin|Invoke-EventHunter|Invoke-EventVwrBypass|Invoke-Eyewitness|Invoke-FakeLogonScreen|Invoke-Farmer|Invoke-FileFinder|Invoke-Get-RBCD-Threaded|Invoke-Gopher|Invoke-GPOLinks|Invoke-Grouper2|Invoke-HandleKatz|Invoke-ImpersonateUser|Invoke-Interceptor|Invoke-Internalmonologue|Invoke-Inveigh|Invoke-InveighRelay|Invoke-JSRatRegsvr|Invoke-JSRatRundll|Invoke-Kerberoast|Invoke-KrbRelayUp|Invoke-LdapSignCheck|Invoke-Lockless|Invoke-MapDomainTrust|Invoke-MemoryFreeLibrary|Invoke-MemoryLoadLibrary|Invoke-Method|Invoke-MITM6|Invoke-NanoDump|Invoke-NetRipper|Invoke-NetworkRelay|Invoke-NinjaCopy|Invoke-OxidResolver|Invoke-P0wnedshell|Invoke-Paranoia|Invoke-PatchDll|Invoke-PortScan|Invoke-PoshRatHttp|Invoke-PoshRatHttps|Invoke-PostExfil|Invoke-Potato|Invoke-PowerDump|Invoke-PPLDump|Invoke-Prasadhak|Invoke-PrintNightmare|Invoke-PrivescAudit|Invoke-ProcessHunter|Invoke-PsExec|Invoke-PSGcat|Invoke-PsGcatAgent|Invoke-PSInject|Invoke-PsUaCme|Invoke-ReflectivePEInjection|Invoke-ReverseDNSLookup|Invoke-ReverseDnsLookup|Invoke-RevertToSelf|Invoke-Rubeus|Invoke-RunAs|Invoke-SafetyKatz|Invoke-SauronEye|Invoke-SCShell|Invoke-Seatbelt|Invoke-ServiceAbuse|Invoke-SessionGopher|Invoke-ShareFinder|Invoke-SharpAllowedToAct|Invoke-SharpBlock|Invoke-SharpBypassUAC|Invoke-SharpChromium|Invoke-SharpClipboard|Invoke-SharpCloud|Invoke-SharpDPAPI|Invoke-SharpDump|Invoke-SharPersist|Invoke-SharpGPO-RemoteAccessPolicies|Invoke-SharpGPOAbuse|Invoke-SharpHandler|Invoke-SharpHide|Invoke-Sharphound|Invoke-SharpImpersonation|Invoke-SharpImpersonationNoSpace|Invoke-SharpKatz|Invoke-SharpLdapRelayScan|Invoke-Sharplocker|Invoke-SharpLoginPrompt|Invoke-SharpMove|Invoke-SharpPrinter|Invoke-SharpPrintNightmare|Invoke-SharpRDP|Invoke-SharpSecDump|Invoke-Sharpshares|Invoke-SharpSniper|Invoke-SharpSploit|Invoke-SharpSpray|Invoke-SharpSSDP|Invoke-SharpStay|Invoke-SharpUp|Invoke-Sharpview|Invoke-SharpWatson|Invoke-Sharpweb|Invoke-Shellcode|Invoke-ShellCommand|Invoke-SMBAutoBrute|Invoke-SMBScanner|Invoke-Snaffler|Invoke-Spoolsample|Invoke-SSHCommand|Invoke-SSIDExfil|Invoke-StandIn|Invoke-StickyNotesExtract|Invoke-Tater|Invoke-ThreadedFunction|Invoke-Thunderfox|Invoke-ThunderStruck|Invoke-TokenManipulation|Invoke-Tokenvator|Invoke-UrbanBishop|Invoke-UserHunter|Invoke-UserImpersonation|Invoke-VoiceTroll|Invoke-Whisker|Invoke-WinEnum|Invoke-winPEAS|Invoke-WireTap|Invoke-WmiCommand|Invoke-WScriptBypassUAC|Invoke-Zerologon|Jitter|Kerberoast|Kerbroast|Keylogger|LoggedKeys|MailRaider|Mimikat|Mimikittenz|Mount-VolumeShadowCopy|NetShareEnum|NetWkstaUserEnum|New-ADObjectAccessControlEntry|New-DomainGroup|New-DomainUser|New-DynamicParameter|New-HoneyHash|New-InMemoryModule|New-ScriptBlockCallback|New-ThreadedFunction|New-VolumeShadowCopy|Nishang|NotAllNameSpaces|Out-CHM|Out-CompressedDll|OUT-DNSTXT|Out-EncodedCommand|Out-EncryptedScript|Out-HTA|Out-Minidump|Out-RundllCommand|Out-SCF|Out-Shortcut|Out-WebQuery|Out-Word|Parse_Keys|Parse-Hosts|Parse-ILHosts|Parse-IPList|Parse-IpPorts|Parse-Pkt|Parse-Ports|ParseKeys|Password-List|Port-Scan|PortScan-Alive|Portscan-Port|PowerBreach|Powerpreter|PowerUp|PowerView|Remove-DomainGroupMember|Remove-DomainObjectAcl|Remove-Persistence|Remove-Ports|Remove-PoshRat|Remove-RemoteConnection|Remove-Update|Remove-VolumeShadowCopy|Request-SPNTicket|Resolve-IPAddress|Restore-ServiceBinary|Run-EXEonRemote|Set-ADObject|Set-DCShadowPermissions|Set-DesktopACLs|Set-DesktopACLToAllowEveryone|Set-DomainObject|Set-DomainObjectOwner|Set-DomainUserPassword|Set-FilelessBypassUac|Set-MacAttribute|Set-PowerStego|Set-Property|Set-RemotePSRemoting|Set-RemoteWMI|Set-ServiceBinaryPath|Set-Wallpaper|Sharphound|Shellcode|Shellcode32|Shellcode64|Show-TargetScreen|Split-Path|Start-CaptureServer|Start-Dnscat|Start-WebcamRecorder|StringtoBase64|Sub-SignedIntAsUnsigned|Test-AdminAccess|Test-IsAdmin|Test-MemoryRangeValid|Test-ServiceDaclPermission|TexttoExe|Update-ExeFunctions|Update-MemoryAddresses|Update-MemoryProtectionFlags|VolumeShadowCopyTools|Write-BytesToMemory|Write-HijackDll|Write-PortscanOut|Write-ServiceBinary|Write-UserAddMSI,,12/8/2022
        T1059.01-Powershell Malicious Keywords,ScriptBlock|Commandlet,AdjustTokenPrivileges|IMAGE_NT_OPTIONAL_HDR64_MAGIC|Microsoft.Win32.UnsafeNativeMethods|ReadProcessMemory.Invoke|SE_PRIVILEGE_ENABLED|LSA_UNICODE_STRING|MiniDumpWriteDump|PAGE_EXECUTE_READ|SECURITY_DELEGATION|TOKEN_ADJUST_PRIVILEGES|TOKEN_ALL_ACCESS|TOKEN_ASSIGN_PRIMARY|TOKEN_DUPLICATE|TOKEN_ELEVATION|TOKEN_IMPERSONATE|TOKEN_INFORMATION_CLASS|TOKEN_PRIVILEGES|TOKEN_QUERY|System.Reflection.Assembly.Load|[System.Reflection.Assembly]::Load|[Reflection.Assembly]::Load|System.Reflection.AssemblyName|Reflection.Emit.AssemblyBuilderAccess|Runtime.InteropServices.DllImportAttribute|SuspendThread|Metasploit|Mimikatz|PS ATTACK,,12/8/2022
        T1059.001-Loading Powershell in Memory,ScriptBlock|Commandlet,System.Reflection.AssemblyName|System.Reflection.Emit.AssemblyBuilderAccess|System.Runtime.InteropServices.MarshalAsAttribute|memorystream,,12/8/2022
        
sources:
  - query: |
      -- materialize ignore path regex where exist and not \s
      LET ScriptIgnore = SELECT _value as PathRegex 
        FROM foreach(row=split(string=IgnorePaths,sep='\n')) 
        WHERE PathRegex AND NOT PathRegex =~ '^\\s+$'
      LET ScriptIgnorePath <= join(array=ScriptIgnore.PathRegex,sep='|')
      
      -- materialize scriptblock regex for initial pass
      LET ScriptBlock = SELECT Regex,Type FROM IocCsv WHERE Type =~ 'ScriptBlock'
      LET ScriptBlockRegex <= join(array=ScriptBlock.Regex,sep='|')
      
      -- materialize Commandlet regex for initial pass
      LET Commandlet = SELECT Regex,Type FROM IocCsv WHERE Type =~ 'Commandlet'
      LET CommandletRegex <= join(array=Commandlet.Regex,sep='|')
      
      -- watch ETW provider and first round data manipulation
      LET hits = SELECT 
            timestamp(epoch=timestamp(string=System.TimeStamp).unix) as EventTime,
            System.ID as EventID,
            System.ProcessID as ProcessID,
            get(member="EventData") AS EventData
      FROM watch_etw(guid="{a0c1853b-5c40-4b15-8766-3cf1c58f985a}") 
      WHERE ( EventData.ScriptBlockText OR EventData.Payload =~ '^Command .+ is Started\.\r\n$' )
        AND ( EventData.ScriptBlockText =~ ScriptBlockRegex
           OR EventData.Payload =~ CommandletRegex )
      
      -- print rows
      SELECT * FROM foreach(row=hits,query={
            SELECT
                EventTime,
                dict(
                    Name=Name,
                    Type=Type,
                    Regex=Regex,
                    Ignore=Ignore
                ) as Detection,
                EventID,
                if(condition= EventID=4104,
                    then= EventData.ScriptBlockText,
                    else= regex_replace(
                            source=EventData.Payload,
                            re='^Command | is Started\.\r\n$',
                            replace=''
                    )) as Payload,
                if(condition= EventID=4104,
                    then= EventData,
                    else= dict(Payload=EventData.Payload,
                        ContextInfo=parse_string_with_regex(string=EventData.ContextInfo,
                        regex=[
                            'Severity = (?P<Severity>[^\\r]*)',
                            'Host Name = (?P<HostName>[^\\r]*)',
                            'Host Version = (?P<HostVersion>[^\\r]*)',
                            'Host ID = (?P<HostID>[^\\r]*)',
                            'Host Application = (?P<HostApplication>[^\\r]*)',
                            'Engine Version = (?P<EngineVersion>[^\\r]*)',
                            'Runspace ID = (?P<RunspaceID>[^\\r]*)',
                            'Pipeline ID = (?P<PipelineID>[^\\r]*)',
                            'Command Name= (?P<CommandName>[^\\r]*)',
                            'CommandType = (?P<CommandType>[^\\r]*)',
                            'Script Name = (?P<ScriptName>[^\\r]*)',
                            'Command Path = (?P<CommandPath>[^\\r]*)',
                            'Sequence Number = (?P<SequenceNumber>[^\\r]*)',
                            'User = (?P<User>[^\\r]*)',
                            'Connected User = (?P<ConnectedUser>[^\\r]*)',
                            'Shell ID = (?P<ShellID>[^\\r]*)'
                        ]),
                        UserData=EventData.UserData)) as EventData,
                process_tracker_callchain(id=ProcessID).Data[-1] as ProcessInfo,
                process_tracker_callchain(id=ProcessID).Data as ProcessChain
            FROM IocCsv
            WHERE 
                if(condition= EventID=4104, then= Type=~'ScriptBlock',else= Type=~'Commandlet' )
                AND NOT if(condition=IgnoreProcessExe, 
                    then= ProcessInfo.Exe =~ IgnoreProcessExe, else= False)
                AND NOT if(condition=IgnoreParentProcessExe, 
                    then= ProcessChain.Exe[-2] =~ IgnoreParentProcessExe, else= False)
                AND Payload =~ Regex 
                AND NOT if(condition=Ignore, then= Payload=~Ignore, else= False)
                AND NOT if(condition=IgnorePaths,
                    then= EventData.Path =~ ScriptIgnorePath 
                        OR EventData.ContextInfo.CommandPath =~ ScriptIgnorePath
                        OR EventData.ContextInfo.ScriptName =~ ScriptIgnorePath,
                            else= False)
            LIMIT 1 -- limts to 1 row per IocCsv entry.
        })