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.
        })