Detection: PowerShell 4104 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.

  1`powershell`
  2EventCode=4104
  3
  4| eval DoIt = if(match(ScriptBlockText,"(?i)(\$doit)"), "4", 0)
  5
  6| eval enccom=if(match(ScriptBlockText,"[A-Za-z0-9+\/]{44,}([A-Za-z0-9+\/]{4}
  7|[A-Za-z0-9+\/]{3}=
  8|[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)
  9
 10| eval suspcmdlet=if(match(ScriptBlockText, "(?i)Add-Exfiltration
 11|Add-Persistence
 12|Add-RegBackdoor
 13|Add-ScrnSaveBackdoor
 14|Check-VM
 15|Do-Exfiltration
 16|Enabled-DuplicateToken
 17|Exploit-Jboss
 18|Find-Fruit
 19|Find-GPOLocation
 20|Find-TrustedDocuments
 21|Get-ApplicationHost
 22|Get-ChromeDump
 23|Get-ClipboardContents
 24|Get-FoxDump
 25|Get-GPPPassword
 26|Get-IndexedItem
 27|Get-Keystrokes
 28|LSASecret
 29|Get-PassHash
 30|Get-RegAlwaysInstallElevated
 31|Get-RegAutoLogon
 32|Get-RickAstley
 33|Get-Screenshot
 34|Get-SecurityPackages
 35|Get-ServiceFilePermission
 36|Get-ServicePermission
 37|Get-ServiceUnquoted
 38|Get-SiteListPassword
 39|Get-System
 40|Get-TimedScreenshot
 41|Get-UnattendedInstallFile
 42|Get-Unconstrained
 43|Get-VaultCredential
 44|Get-VulnAutoRun
 45|Get-VulnSchTask
 46|Gupt-Backdoor
 47|HTTP-Login
 48|Install-SSP
 49|Install-ServiceBinary
 50|Invoke-ACLScanner
 51|Invoke-ADSBackdoor
 52|Invoke-ARPScan
 53|Invoke-AllChecks
 54|Invoke-BackdoorLNK
 55|Invoke-BypassUAC
 56|Invoke-CredentialInjection
 57|Invoke-DCSync
 58|Invoke-DllInjection
 59|Invoke-DowngradeAccount
 60|Invoke-EgressCheck
 61|Invoke-Inveigh
 62|Invoke-InveighRelay
 63|Invoke-Mimikittenz
 64|Invoke-NetRipper
 65|Invoke-NinjaCopy
 66|Invoke-PSInject
 67|Invoke-Paranoia
 68|Invoke-PortScan
 69|Invoke-PoshRat
 70|Invoke-PostExfil
 71|Invoke-PowerDump
 72|Invoke-PowerShellTCP
 73|Invoke-PsExec
 74|Invoke-PsUaCme
 75|Invoke-ReflectivePEInjection
 76|Invoke-ReverseDNSLookup
 77|Invoke-RunAs
 78|Invoke-SMBScanner
 79|Invoke-SSHCommand
 80|Invoke-Service
 81|Invoke-Shellcode
 82|Invoke-Tater
 83|Invoke-ThunderStruck
 84|Invoke-Token
 85|Invoke-UserHunter
 86|Invoke-VoiceTroll
 87|Invoke-WScriptBypassUAC
 88|Invoke-WinEnum
 89|MailRaider
 90|New-HoneyHash
 91|Out-Minidump
 92|Port-Scan
 93|PowerBreach
 94|PowerUp
 95|PowerView
 96|Remove-Update
 97|Set-MacAttribute
 98|Set-Wallpaper
 99|Show-TargetScreen
100|Start-CaptureServer
101|VolumeShadowCopyTools
102|NEEEEWWW
103|(Computer
104|User)Property
105|CachedRDPConnection
106|get-net\S+
107|invoke-\S+hunter
108|Install-Service
109|get-\S+(credent
110|password)
111|remoteps
112|Kerberos.*(policy
113|ticket)
114|netfirewall
115|Uninstall-Windows
116|Verb\s+Runas
117|AmsiBypass
118|nishang
119|Invoke-Interceptor
120|EXEonRemote
121|NetworkRelay
122|PowerShelludp
123|PowerShellIcmp
124|CreateShortcut
125|copy-vss
126|invoke-dll
127|invoke-mass
128|out-shortcut
129|Invoke-ShellCommand"),1,0)
130
131| eval base64 = if(match(lower(ScriptBlockText),"frombase64"), "4", 0)
132
133| eval empire=if(match(lower(ScriptBlockText),"system.net.webclient") AND match(lower(ScriptBlockText), "frombase64string") ,5,0)
134
135| 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)
136
137| eval iex=if(match(ScriptBlockText, "(?i)iex
138|invoke-expression"),2,0)
139
140| eval webclient=if(match(lower(ScriptBlockText),"http") OR match(lower(ScriptBlockText),"web(client
141|request)") OR match(lower(ScriptBlockText),"socket") OR match(lower(ScriptBlockText),"download(file
142|string)") OR match(lower(ScriptBlockText),"bitstransfer") OR match(lower(ScriptBlockText),"internetexplorer.application") OR match(lower(ScriptBlockText),"xmlhttp"),5,0)
143
144| eval get = if(match(lower(ScriptBlockText),"get-"), "1", 0)
145
146| eval rundll32 = if(match(lower(ScriptBlockText),"rundll32"), "4", 0)
147
148| eval suspkeywrd=if(match(ScriptBlockText, "(?i)(bitstransfer
149|mimik
150|metasp
151|AssemblyBuilderAccess
152|Reflection\.Assembly
153|shellcode
154|injection
155|cnvert
156|shell\.application
157|start-process
158|Rc4ByteStream
159|System\.Security\.Cryptography
160|lsass\.exe
161|localadmin
162|LastLoggedOn
163|hijack
164|BackupPrivilege
165|ngrok
166|comsvcs
167|backdoor
168|brute.?force
169|Port.?Scan
170|Exfiltration
171|exploit
172|DisableRealtimeMonitoring
173|beacon)"),1,0)
174
175| eval syswow64 = if(match(lower(ScriptBlockText),"syswow64"), "3", 0)
176
177| eval httplocal = if(match(lower(ScriptBlockText),"http://127.0.0.1"), "4", 0)
178
179| eval reflection = if(match(lower(ScriptBlockText),"reflection"), "1", 0)
180
181| eval invokewmi=if(match(lower(ScriptBlockText), "(?i)(wmiobject
182|WMIMethod
183|RemoteWMI
184|PowerShellWmi
185|wmicommand)"),5,0)
186
187| eval downgrade=if(match(ScriptBlockText, "(?i)([-]ve*r*s*i*o*n*\s+2)") OR match(lower(ScriptBlockText),"powershell -version"),3,0)
188
189| eval compressed=if(match(ScriptBlockText, "(?i)GZipStream
190|::Decompress
191|IO.Compression
192|write-zip
193|(expand
194|compress)-Archive"),5,0)
195
196| eval invokecmd = if(match(lower(ScriptBlockText),"invoke-command"), "4", 0)
197
198| addtotals fieldname=Score DoIt, enccom, suspcmdlet, suspkeywrd, compressed, downgrade, mimikatz, iex, empire, rundll32, webclient, syswow64, httplocal, reflection, invokewmi, invokecmd, base64, get
199
200| stats values(Score)
201    BY UserID, Computer, DoIt,
202       enccom, compressed, downgrade,
203       iex, mimikatz, rundll32,
204       empire, webclient, syswow64,
205       httplocal, reflection, invokewmi,
206       invokecmd, base64, get,
207       suspcmdlet, suspkeywrd
208  
209| rename Computer as dest, UserID as user
210  
211| `powershell_4104_hunting_filter`

Data Source

Name Platform Sourcetype Source
Powershell Script Block Logging 4104 Windows icon Windows 'XmlWinEventLog' 'XmlWinEventLog:Microsoft-Windows-PowerShell/Operational'

Macros Used

Name Value
powershell (source=WinEventLog:Microsoft-Windows-PowerShell/Operational OR source="XmlWinEventLog:Microsoft-Windows-PowerShell/Operational" OR source=WinEventLog:PowerShellCore/Operational OR source="XmlWinEventLog:PowerShellCore/Operational")
powershell_4104_hunting_filter search *
powershell_4104_hunting_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.

Annotations

Default Configuration

This detection is configured by default in Splunk Enterprise Security to run with the following settings:

Setting Value
Disabled true
Cron Schedule 0 * * * *
Earliest Time -70m@m
Latest Time -10m@m
Schedule Window auto
Creates Finding (Notable) No
Creates Intermediate Finding (Risk Event) No
Hunting detections do not generate a Finding (Notable) or Intermediate Findings (Risk Events).

Implementation

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.

Associated Analytic Story

References

Detection Testing

Test Type Status Dataset Source Sourcetype
Validation Passing N/A N/A N/A
Unit Passing Dataset XmlWinEventLog:Microsoft-Windows-PowerShell/Operational XmlWinEventLog

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI. Alternatively you can replay a dataset into a Splunk Attack Range


Source: GitHub | Version: 26