Detection rules › Splunk

PowerShell 4104 Hunting

Status
production
Group by
DoIt, base64, compressed, computer_name, downgrade, empire, enccom, get, httplocal, iex, invokecmd, invokewmi, mimikatz, reflection, rundll32, suspcmdlet, suspkeywrd, syswow64, user, webclient
Author
Michael Haag, Splunk
Source
github.com/splunk/security_content

The following analytic identifies suspicious PowerShell execution using Script Block Logging (EventCode 4104). It leverages specific patterns and keywords within the ScriptBlockText field to detect potentially malicious activities. This detection is significant for SOC analysts as PowerShell is commonly used by attackers for various malicious purposes, including code execution, privilege escalation, and persistence. If confirmed malicious, this activity could allow attackers to execute arbitrary commands, exfiltrate data, or maintain long-term access to the compromised system, posing a severe threat to the organization's security.

MITRE ATT&CK coverage

Event coverage

Rule body splunk

name: PowerShell 4104 Hunting
id: d6f2b006-0041-11ec-8885-acde48001122
version: 25
creation_date: '2021-08-19'
modification_date: '2026-05-13'
author: Michael Haag, Splunk
status: production
type: Hunting
description: The following analytic identifies suspicious PowerShell execution using Script Block Logging (EventCode 4104). It leverages specific patterns and keywords within the ScriptBlockText field to detect potentially malicious activities. This detection is significant for SOC analysts as PowerShell is commonly used by attackers for various malicious purposes, including code execution, privilege escalation, and persistence. If confirmed malicious, this activity could allow attackers to execute arbitrary commands, exfiltrate data, or maintain long-term access to the compromised system, posing a severe threat to the organization's security.
data_source:
    - Powershell Script Block Logging 4104
search: |-
    `powershell` EventCode=4104
      | eval DoIt = if(match(ScriptBlockText,"(?i)(\$doit)"), "4", 0)
      | eval enccom=if(match(ScriptBlockText,"[A-Za-z0-9+\/]{44,}([A-Za-z0-9+\/]{4}
      | [A-Za-z0-9+\/]{3}=
      | [A-Za-z0-9+\/]{2}==)") OR match(ScriptBlockText, "(?i)[-]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\s+[^-]"),4,0)
      | eval suspcmdlet=if(match(ScriptBlockText, "(?i)Add-Exfiltration
      | Add-Persistence
      | Add-RegBackdoor
      | Add-ScrnSaveBackdoor
      | Check-VM
      | Do-Exfiltration
      | Enabled-DuplicateToken
      | Exploit-Jboss
      | Find-Fruit
      | Find-GPOLocation
      | Find-TrustedDocuments
      | Get-ApplicationHost
      | Get-ChromeDump
      | Get-ClipboardContents
      | Get-FoxDump
      | Get-GPPPassword
      | Get-IndexedItem
      | Get-Keystrokes
      | LSASecret
      | Get-PassHash
      | Get-RegAlwaysInstallElevated
      | Get-RegAutoLogon
      | Get-RickAstley
      | Get-Screenshot
      | Get-SecurityPackages
      | Get-ServiceFilePermission
      | Get-ServicePermission
      | Get-ServiceUnquoted
      | Get-SiteListPassword
      | Get-System
      | Get-TimedScreenshot
      | Get-UnattendedInstallFile
      | Get-Unconstrained
      | Get-VaultCredential
      | Get-VulnAutoRun
      | Get-VulnSchTask
      | Gupt-Backdoor
      | HTTP-Login
      | Install-SSP
      | Install-ServiceBinary
      | Invoke-ACLScanner
      | Invoke-ADSBackdoor
      | Invoke-ARPScan
      | Invoke-AllChecks
      | Invoke-BackdoorLNK
      | Invoke-BypassUAC
      | Invoke-CredentialInjection
      | Invoke-DCSync
      | Invoke-DllInjection
      | Invoke-DowngradeAccount
      | Invoke-EgressCheck
      | Invoke-Inveigh
      | Invoke-InveighRelay
      | Invoke-Mimikittenz
      | Invoke-NetRipper
      | Invoke-NinjaCopy
      | Invoke-PSInject
      | Invoke-Paranoia
      | Invoke-PortScan
      | Invoke-PoshRat
      | Invoke-PostExfil
      | Invoke-PowerDump
      | Invoke-PowerShellTCP
      | Invoke-PsExec
      | Invoke-PsUaCme
      | Invoke-ReflectivePEInjection
      | Invoke-ReverseDNSLookup
      | Invoke-RunAs
      | Invoke-SMBScanner
      | Invoke-SSHCommand
      | Invoke-Service
      | Invoke-Shellcode
      | Invoke-Tater
      | Invoke-ThunderStruck
      | Invoke-Token
      | Invoke-UserHunter
      | Invoke-VoiceTroll
      | Invoke-WScriptBypassUAC
      | Invoke-WinEnum
      | MailRaider
      | New-HoneyHash
      | Out-Minidump
      | Port-Scan
      | PowerBreach
      | PowerUp
      | PowerView
      | Remove-Update
      | Set-MacAttribute
      | Set-Wallpaper
      | Show-TargetScreen
      | Start-CaptureServer
      | VolumeShadowCopyTools
      | NEEEEWWW
      | (Computer
      | User)Property
      | CachedRDPConnection
      | get-net\S+
      | invoke-\S+hunter
      | Install-Service
      | get-\S+(credent
      | password)
      | remoteps
      | Kerberos.*(policy
      | ticket)
      | netfirewall
      | Uninstall-Windows
      | Verb\s+Runas
      | AmsiBypass
      | nishang
      | Invoke-Interceptor
      | EXEonRemote
      | NetworkRelay
      | PowerShelludp
      | PowerShellIcmp
      | CreateShortcut
      | copy-vss
      | invoke-dll
      | invoke-mass
      | out-shortcut
      | Invoke-ShellCommand"),1,0)
      | eval base64 = if(match(lower(ScriptBlockText),"frombase64"), "4", 0)
      | eval empire=if(match(lower(ScriptBlockText),"system.net.webclient") AND match(lower(ScriptBlockText), "frombase64string") ,5,0)
      | eval mimikatz=if(match(lower(ScriptBlockText),"mimikatz") OR match(lower(ScriptBlockText), "-dumpcr") OR match(lower(ScriptBlockText), "SEKURLSA::Pth") OR match(lower(ScriptBlockText), "kerberos::ptt") OR match(lower(ScriptBlockText), "kerberos::golden") ,5,0)
      | eval iex=if(match(ScriptBlockText, "(?i)iex
      | invoke-expression"),2,0)
      | eval webclient=if(match(lower(ScriptBlockText),"http") OR match(lower(ScriptBlockText),"web(client
      | request)") OR match(lower(ScriptBlockText),"socket") OR match(lower(ScriptBlockText),"download(file
      | string)") OR match(lower(ScriptBlockText),"bitstransfer") OR match(lower(ScriptBlockText),"internetexplorer.application") OR match(lower(ScriptBlockText),"xmlhttp"),5,0)
      | eval get = if(match(lower(ScriptBlockText),"get-"), "1", 0)
      | eval rundll32 = if(match(lower(ScriptBlockText),"rundll32"), "4", 0)
      | eval suspkeywrd=if(match(ScriptBlockText, "(?i)(bitstransfer
      | mimik
      | metasp
      | AssemblyBuilderAccess
      | Reflection\.Assembly
      | shellcode
      | injection
      | cnvert
      | shell\.application
      | start-process
      | Rc4ByteStream
      | System\.Security\.Cryptography
      | lsass\.exe
      | localadmin
      | LastLoggedOn
      | hijack
      | BackupPrivilege
      | ngrok
      | comsvcs
      | backdoor
      | brute.?force
      | Port.?Scan
      | Exfiltration
      | exploit
      | DisableRealtimeMonitoring
      | beacon)"),1,0)
      | eval syswow64 = if(match(lower(ScriptBlockText),"syswow64"), "3", 0)
      | eval httplocal = if(match(lower(ScriptBlockText),"http://127.0.0.1"), "4", 0)
      | eval reflection = if(match(lower(ScriptBlockText),"reflection"), "1", 0)
      | eval invokewmi=if(match(lower(ScriptBlockText), "(?i)(wmiobject
      | WMIMethod
      | RemoteWMI
      | PowerShellWmi
      | wmicommand)"),5,0)
      | eval downgrade=if(match(ScriptBlockText, "(?i)([-]ve*r*s*i*o*n*\s+2)") OR match(lower(ScriptBlockText),"powershell -version"),3,0)
      | eval compressed=if(match(ScriptBlockText, "(?i)GZipStream
      | ::Decompress
      | IO.Compression
      | write-zip
      | (expand
      | compress)-Archive"),5,0)
      | eval invokecmd = if(match(lower(ScriptBlockText),"invoke-command"), "4", 0)
      | addtotals fieldname=Score DoIt, enccom, suspcmdlet, suspkeywrd, compressed, downgrade, mimikatz, iex, empire, rundll32, webclient, syswow64, httplocal, reflection, invokewmi, invokecmd, base64, get
      | stats values(Score)
        BY UserID, Computer, DoIt,
           enccom, compressed, downgrade,
           iex, mimikatz, rundll32,
           empire, webclient, syswow64,
           httplocal, reflection, invokewmi,
           invokecmd, base64, get,
           suspcmdlet, suspkeywrd
      | rename Computer as dest, UserID as user
      | `powershell_4104_hunting_filter`
how_to_implement: The following Hunting analytic requires PowerShell operational logs to be imported. Modify the powershell macro as needed to match the sourcetype or add index. This analytic is specific to 4104, or PowerShell Script Block Logging.
known_false_positives: Limited false positives. May filter as needed.
references:
    - https://github.com/inodee/threathunting-spl/blob/master/hunt-queries/powershell_qualifiers.md
    - https://help.splunk.com/en/security-offerings/splunk-user-behavior-analytics/get-data-in/5.4.1/add-other-data-to-splunk-uba/configure-powershell-logging-to-see-powershell-anomalies-in-splunk-uba
    - https://github.com/marcurdy/dfir-toolset/blob/master/Powershell%20Blueteam.txt
    - https://devblogs.microsoft.com/powershell/powershell-the-blue-team/
    - https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging?view=powershell-5.1
    - https://www.mandiant.com/resources/greater-visibilityt
    - https://hurricanelabs.com/splunk-tutorials/how-to-use-powershell-transcription-logs-in-splunk/
    - https://www.splunk.com/en_us/blog/security/hunting-for-malicious-powershell-using-script-block-logging.html
    - https://adlumin.com/post/powerdrop-a-new-insidious-powershell-script-for-command-and-control-attacks-targets-u-s-aerospace-defense-industry/
analytic_story:
    - Braodo Stealer
    - Cactus Ransomware
    - China-Nexus Threat Activity
    - CISA AA23-347A
    - CISA AA24-241A
    - Cleo File Transfer Software
    - DarkGate Malware
    - Data Destruction
    - Flax Typhoon
    - Hermetic Wiper
    - Lumma Stealer
    - Malicious PowerShell
    - Medusa Ransomware
    - Rhysida Ransomware
    - Salt Typhoon
    - SystemBC
    - PHP-CGI RCE Attack on Japanese Organizations
    - Water Gamayun
    - XWorm
    - Scattered Spider
    - Interlock Ransomware
    - 0bj3ctivity Stealer
    - APT37 Rustonotto and FadeStealer
    - GhostRedirector IIS Module and Rungan Backdoor
    - Hellcat Ransomware
    - Microsoft WSUS CVE-2025-59287
    - MuddyWater
    - Axios Supply Chain Post Compromise
asset_type: Endpoint
mitre_attack_id:
    - T1059.001
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint
tests:
    - name: True Positive Test
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1059.001/powershell_script_block_logging/sbl_xml.log
          source: XmlWinEventLog:Microsoft-Windows-PowerShell/Operational
          sourcetype: XmlWinEventLog
      test_type: unit

Stages and Predicates

Stage 1: search

`powershell` EventCode=4104

Stage 2: eval

| eval DoIt = if(match(ScriptBlockText,"(?i)(\$doit)"), "4", 0)
DoIt =
ifmatch(ScriptBlockText, "(?i)(\$doit)")"4"
else0

Stage 3: eval

| eval enccom=if(match(ScriptBlockText,"[A-Za-z0-9+\/]{44,}([A-Za-z0-9+\/]{4}
  | [A-Za-z0-9+\/]{3}=
  | [A-Za-z0-9+\/]{2}==)") OR match(ScriptBlockText, "(?i)[-]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\s+[^-]"),4,0)
enccom =
ifmatch(ScriptBlockText, "[A-Za-z0-9+\/]{44,}([A-Za-z0-9+\/]{4} | [A-Za-z0-9+\/]{3}= | [A-Za-z0-9+\/]{2}==)") OR match(ScriptBlockText, "(?i)[-]e(nc*o*d*e*d*c*o*m*m*a*n*d*)*\s+[^-]")4
else0

Stage 4: eval

| eval suspcmdlet=if(match(ScriptBlockText, "(?i)Add-Exfiltration
  | Add-Persistence
  | Add-RegBackdoor
  | Add-ScrnSaveBackdoor
  | Check-VM
  | Do-Exfiltration
  | Enabled-DuplicateToken
  | Exploit-Jboss
  | Find-Fruit
  | Find-GPOLocation
  | Find-TrustedDocuments
  | Get-ApplicationHost
  | Get-ChromeDump
  | Get-ClipboardContents
  | Get-FoxDump
  | Get-GPPPassword
  | Get-IndexedItem
  | Get-Keystrokes
  | LSASecret
  | Get-PassHash
  | Get-RegAlwaysInstallElevated
  | Get-RegAutoLogon
  | Get-RickAstley
  | Get-Screenshot
  | Get-SecurityPackages
  | Get-ServiceFilePermission
  | Get-ServicePermission
  | Get-ServiceUnquoted
  | Get-SiteListPassword
  | Get-System
  | Get-TimedScreenshot
  | Get-UnattendedInstallFile
  | Get-Unconstrained
  | Get-VaultCredential
  | Get-VulnAutoRun
  | Get-VulnSchTask
  | Gupt-Backdoor
  | HTTP-Login
  | Install-SSP
  | Install-ServiceBinary
  | Invoke-ACLScanner
  | Invoke-ADSBackdoor
  | Invoke-ARPScan
  | Invoke-AllChecks
  | Invoke-BackdoorLNK
  | Invoke-BypassUAC
  | Invoke-CredentialInjection
  | Invoke-DCSync
  | Invoke-DllInjection
  | Invoke-DowngradeAccount
  | Invoke-EgressCheck
  | Invoke-Inveigh
  | Invoke-InveighRelay
  | Invoke-Mimikittenz
  | Invoke-NetRipper
  | Invoke-NinjaCopy
  | Invoke-PSInject
  | Invoke-Paranoia
  | Invoke-PortScan
  | Invoke-PoshRat
  | Invoke-PostExfil
  | Invoke-PowerDump
  | Invoke-PowerShellTCP
  | Invoke-PsExec
  | Invoke-PsUaCme
  | Invoke-ReflectivePEInjection
  | Invoke-ReverseDNSLookup
  | Invoke-RunAs
  | Invoke-SMBScanner
  | Invoke-SSHCommand
  | Invoke-Service
  | Invoke-Shellcode
  | Invoke-Tater
  | Invoke-ThunderStruck
  | Invoke-Token
  | Invoke-UserHunter
  | Invoke-VoiceTroll
  | Invoke-WScriptBypassUAC
  | Invoke-WinEnum
  | MailRaider
  | New-HoneyHash
  | Out-Minidump
  | Port-Scan
  | PowerBreach
  | PowerUp
  | PowerView
  | Remove-Update
  | Set-MacAttribute
  | Set-Wallpaper
  | Show-TargetScreen
  | Start-CaptureServer
  | VolumeShadowCopyTools
  | NEEEEWWW
  | (Computer
  | User)Property
  | CachedRDPConnection
  | get-net\S+
  | invoke-\S+hunter
  | Install-Service
  | get-\S+(credent
  | password)
  | remoteps
  | Kerberos.*(policy
  | ticket)
  | netfirewall
  | Uninstall-Windows
  | Verb\s+Runas
  | AmsiBypass
  | nishang
  | Invoke-Interceptor
  | EXEonRemote
  | NetworkRelay
  | PowerShelludp
  | PowerShellIcmp
  | CreateShortcut
  | copy-vss
  | invoke-dll
  | invoke-mass
  | out-shortcut
  | Invoke-ShellCommand"),1,0)
suspcmdlet =
ifmatch(ScriptBlockText, "(?i)Add-Exfiltration | Add-Persistence | Add-RegBackdoor | Add-ScrnSaveBackdoor | Check-VM | Do-Exfiltration | Enabled-DuplicateToken | Exploit-Jboss | Find-Fruit | Find-GPOLocation | Find-TrustedDocuments | Get-ApplicationHost | Get-ChromeDump | Get-ClipboardContents | Get-FoxDump | Get-GPPPassword | Get-IndexedItem | Get-Keystrokes | LSASecret | Get-PassHash | Get-RegAlwaysInstallElevated | Get-RegAutoLogon | Get-RickAstley | Get-Screenshot | Get-SecurityPackages | Get-ServiceFilePermission | Get-ServicePermission | Get-ServiceUnquoted | Get-SiteListPassword | Get-System | Get-TimedScreenshot | Get-UnattendedInstallFile | Get-Unconstrained | Get-VaultCredential | Get-VulnAutoRun | Get-VulnSchTask | Gupt-Backdoor | HTTP-Login | Install-SSP | Install-ServiceBinary | Invoke-ACLScanner | Invoke-ADSBackdoor | Invoke-ARPScan | Invoke-AllChecks | Invoke-BackdoorLNK | Invoke-BypassUAC | Invoke-CredentialInjection | Invoke-DCSync | Invoke-DllInjection | Invoke-DowngradeAccount | Invoke-EgressCheck | Invoke-Inveigh | Invoke-InveighRelay | Invoke-Mimikittenz | Invoke-NetRipper | Invoke-NinjaCopy | Invoke-PSInject | Invoke-Paranoia | Invoke-PortScan | Invoke-PoshRat | Invoke-PostExfil | Invoke-PowerDump | Invoke-PowerShellTCP | Invoke-PsExec | Invoke-PsUaCme | Invoke-ReflectivePEInjection | Invoke-ReverseDNSLookup | Invoke-RunAs | Invoke-SMBScanner | Invoke-SSHCommand | Invoke-Service | Invoke-Shellcode | Invoke-Tater | Invoke-ThunderStruck | Invoke-Token | Invoke-UserHunter | Invoke-VoiceTroll | Invoke-WScriptBypassUAC | Invoke-WinEnum | MailRaider | New-HoneyHash | Out-Minidump | Port-Scan | PowerBreach | PowerUp | PowerView | Remove-Update | Set-MacAttribute | Set-Wallpaper | Show-TargetScreen | Start-CaptureServer | VolumeShadowCopyTools | NEEEEWWW | (Computer | User)Property | CachedRDPConnection | get-net\S+ | invoke-\S+hunter | Install-Service | get-\S+(credent | password) | remoteps | Kerberos.*(policy | ticket) | netfirewall | Uninstall-Windows | Verb\s+Runas | AmsiBypass | nishang | Invoke-Interceptor | EXEonRemote | NetworkRelay | PowerShelludp | PowerShellIcmp | CreateShortcut | copy-vss | invoke-dll | invoke-mass | out-shortcut | Invoke-ShellCommand")1
else0

Stage 5: eval

| eval base64 = if(match(lower(ScriptBlockText),"frombase64"), "4", 0)
base64 =
ifmatch(lower(ScriptBlockText), "frombase64")"4"
else0

Stage 6: eval

| eval empire=if(match(lower(ScriptBlockText),"system.net.webclient") AND match(lower(ScriptBlockText), "frombase64string") ,5,0)
empire =
ifmatch(lower(ScriptBlockText), "system.net.webclient") AND match(lower(ScriptBlockText), "frombase64string")5
else0

Stage 7: eval

| eval mimikatz=if(match(lower(ScriptBlockText),"mimikatz") OR match(lower(ScriptBlockText), "-dumpcr") OR match(lower(ScriptBlockText), "SEKURLSA::Pth") OR match(lower(ScriptBlockText), "kerberos::ptt") OR match(lower(ScriptBlockText), "kerberos::golden") ,5,0)
mimikatz =
ifmatch(lower(ScriptBlockText), "mimikatz") OR match(lower(ScriptBlockText), "-dumpcr") OR match(lower(ScriptBlockText), "SEKURLSA::Pth") OR match(lower(ScriptBlockText), "kerberos::ptt") OR match(lower(ScriptBlockText), "kerberos::golden")5
else0

Stage 8: eval

| eval iex=if(match(ScriptBlockText, "(?i)iex
  | invoke-expression"),2,0)
iex =
ifmatch(ScriptBlockText, "(?i)iex | invoke-expression")2
else0

Stage 9: eval

| eval webclient=if(match(lower(ScriptBlockText),"http") OR match(lower(ScriptBlockText),"web(client
  | request)") OR match(lower(ScriptBlockText),"socket") OR match(lower(ScriptBlockText),"download(file
  | string)") OR match(lower(ScriptBlockText),"bitstransfer") OR match(lower(ScriptBlockText),"internetexplorer.application") OR match(lower(ScriptBlockText),"xmlhttp"),5,0)
webclient =
ifmatch(lower(ScriptBlockText), "http") OR match(lower(ScriptBlockText), "web(client | request)") OR match(lower(ScriptBlockText), "socket") OR match(lower(ScriptBlockText), "download(file | string)") OR match(lower(ScriptBlockText), "bitstransfer") OR match(lower(ScriptBlockText), "internetexplorer.application") OR match(lower(ScriptBlockText), "xmlhttp")5
else0

Stage 10: eval

| eval get = if(match(lower(ScriptBlockText),"get-"), "1", 0)
get =
ifmatch(lower(ScriptBlockText), "get-")"1"
else0

Stage 11: eval

| eval rundll32 = if(match(lower(ScriptBlockText),"rundll32"), "4", 0)
rundll32 =
ifmatch(lower(ScriptBlockText), "rundll32")"4"
else0

Stage 12: eval

| eval suspkeywrd=if(match(ScriptBlockText, "(?i)(bitstransfer
  | mimik
  | metasp
  | AssemblyBuilderAccess
  | Reflection\.Assembly
  | shellcode
  | injection
  | cnvert
  | shell\.application
  | start-process
  | Rc4ByteStream
  | System\.Security\.Cryptography
  | lsass\.exe
  | localadmin
  | LastLoggedOn
  | hijack
  | BackupPrivilege
  | ngrok
  | comsvcs
  | backdoor
  | brute.?force
  | Port.?Scan
  | Exfiltration
  | exploit
  | DisableRealtimeMonitoring
  | beacon)"),1,0)
suspkeywrd =
ifmatch(ScriptBlockText, "(?i)(bitstransfer | mimik | metasp | AssemblyBuilderAccess | Reflection\.Assembly | shellcode | injection | cnvert | shell\.application | start-process | Rc4ByteStream | System\.Security\.Cryptography | lsass\.exe | localadmin | LastLoggedOn | hijack | BackupPrivilege | ngrok | comsvcs | backdoor | brute.?force | Port.?Scan | Exfiltration | exploit | DisableRealtimeMonitoring | beacon)")1
else0

Stage 13: eval

| eval syswow64 = if(match(lower(ScriptBlockText),"syswow64"), "3", 0)
syswow64 =
ifmatch(lower(ScriptBlockText), "syswow64")"3"
else0

Stage 14: eval

| eval httplocal = if(match(lower(ScriptBlockText),"http://127.0.0.1"), "4", 0)
httplocal =
ifmatch(lower(ScriptBlockText), "http://127.0.0.1")"4"
else0

Stage 15: eval

| eval reflection = if(match(lower(ScriptBlockText),"reflection"), "1", 0)
reflection =
ifmatch(lower(ScriptBlockText), "reflection")"1"
else0

Stage 16: eval

| eval invokewmi=if(match(lower(ScriptBlockText), "(?i)(wmiobject
  | WMIMethod
  | RemoteWMI
  | PowerShellWmi
  | wmicommand)"),5,0)
invokewmi =
ifmatch(lower(ScriptBlockText), "(?i)(wmiobject | WMIMethod | RemoteWMI | PowerShellWmi | wmicommand)")5
else0

Stage 17: eval

| eval downgrade=if(match(ScriptBlockText, "(?i)([-]ve*r*s*i*o*n*\s+2)") OR match(lower(ScriptBlockText),"powershell -version"),3,0)
downgrade =
ifmatch(ScriptBlockText, "(?i)([-]ve*r*s*i*o*n*\s+2)") OR match(lower(ScriptBlockText), "powershell -version")3
else0

Stage 18: eval

| eval compressed=if(match(ScriptBlockText, "(?i)GZipStream
  | ::Decompress
  | IO.Compression
  | write-zip
  | (expand
  | compress)-Archive"),5,0)
compressed =
ifmatch(ScriptBlockText, "(?i)GZipStream | ::Decompress | IO.Compression | write-zip | (expand | compress)-Archive")5
else0

Stage 19: eval

| eval invokecmd = if(match(lower(ScriptBlockText),"invoke-command"), "4", 0)
invokecmd =
ifmatch(lower(ScriptBlockText), "invoke-command")"4"
else0

Stage 20: addtotals

| addtotals fieldname=Score DoIt, enccom, suspcmdlet, suspkeywrd, compressed, downgrade, mimikatz, iex, empire, rundll32, webclient, syswow64, httplocal, reflection, invokewmi, invokecmd, base64, get

Stage 21: stats

| stats values(Score)
    BY UserID, Computer, DoIt,
       enccom, compressed, downgrade,
       iex, mimikatz, rundll32,
       empire, webclient, syswow64,
       httplocal, reflection, invokewmi,
       invokecmd, base64, get,
       suspcmdlet, suspkeywrd

Stage 22: rename

| rename Computer as dest, UserID as user

Stage 23: search

| `powershell_4104_hunting_filter`

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
EventCodeeq
  • 4104 corpus 268 (splunk 268)