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
  4ScriptBlockText IN (
  5    "*-dumpcr*", "* -version *", "*::decompress*",
  6    "*Add-Exfiltration*", "*Add-Persistence*", "*Add-RegBackdoor*",
  7    "*Add-ScrnSaveBackdoor*", "*AmsiBypass*", "*assemblybuilderaccess*", "*backdoor*",
  8    "*backupprivilege*", "*beacon*", "*bitstransfer*", "*Brute-Force*", "*BruteForce*",
  9    "*CachedRDPConnection*", "*Check-VM*", "*cnvert*", "*compress-archive*", "*ComputerProperty*",
 10    "*comsvcs*", "*copy-vss*", "*CreateShortcut*", "*disablerealtimemonitoring*",
 11    "*Do-Exfiltration*", "*downloadfile*", "*downloadstring*", "*Enabled-DuplicateToken*",
 12    "*EXEonRemote*", "*exfiltration*", "*expand-archive*", "*Exploit-*", "*exploit*",
 13    "*Find-*", "*Frombase64*", "*Get-ApplicationHost*", "*Get-ChromeDump*",
 14    "*Get-ClipboardContents*", "*Get-*Credent*", "*Get-FoxDump*", "*Get-GPPPassword*", "*Get-IndexedItem*",
 15    "*Get-Keystrokes*", "*Get-PassHash*", "*Get-*Password*", "*Get-RegAlwaysInstallElevated*", "*Get-RegAutoLogon*",
 16    "*Get-RickAstley*", "*Get-Screenshot*", "*Get-SecurityPackages*", "*Get-ServiceFilePermission*",
 17    "*Get-ServicePermission*", "*Get-ServiceUnquoted*", "*Get-SiteListPassword*",
 18    "*Get-System*", "*Get-TimedScreenshot*", "*Get-UnattendedInstallFile*",
 19    "*Get-Unconstrained*", "*Get-VaultCredential*", "*Get-VulnAutoRun*",
 20    "*Get-VulnSchTask*", "*Gupt-Backdoor*", "*gzipstream*", "*hijack*",
 21    "*HTTP-Login*", "*IEX *", "*injection*", "*Install-Service*",
 22    "*Install-ServiceBinary*", "*Install-SSP*", "*internetexplorer.application*",
 23    "*Invoke-*", "*io.compression*", "*kerberos::*", "*lastloggedon*",
 24    "*localadmin*", "*LSASecret*", "*lsass.exe*", "*MailRaider*", "*metasp*",
 25    "*mimikatz*", "*NEEEEWWW*", "*netfirewall*", "*NetworkRelay*",
 26    "*New-HoneyHash*", "*ngrok*", "*nishang*", "*Out-Minidump*",
 27    "*out-shortcut*", "*Port-Scan*", "*PortScan*", "*PowerBreach*",
 28    "*PowerShellIcmp*", "*PowerShelludp*", "*powershellwmi*", "*PowerUp*", "*PowerView*",
 29    "*rc4bytestream*", "*reflection.assembly*", "*remoteps*", "*remotewmi*",
 30    "*Remove-Update*", "*SEKURLSA::*", "*Set-MacAttribute*", "*Set-Wallpaper*",
 31    "*shell.application*", "*shellcode*", "*Show-TargetScreen*", "*Start-CaptureServer*",
 32    "*start-process*", "*system.security.cryptography*", "*Uninstall-Windows*", "*UserProperty*",
 33    "*VolumeShadowCopyTools*", "*WebClient*", "*webrequest*", "*wmicommand*",
 34    "*wmimethod*", "*wmiobject*", "*write-zip*", "*xmlhttp*",
 35)
 36
 37
 38| eval script_lower=lower(ScriptBlockText)
 39
 40
 41| eval ecnoded_command_keyword=if(match(ScriptBlockText,"(?i)(?:^
 42|\\s)(?:/(?!/)
 43|--?
 44|{1,2}
 45|{1,2}
 46|{1,2})(?:ec
 47|encodedcommand
 48|encodedcomman
 49|encodedcomma
 50|encodedcomm
 51|encodedcom
 52|encodedco
 53|encodedc
 54|encoded
 55|encode
 56|encod
 57|enco
 58|enc
 59|en
 60|e(?=\\s))\\s+['\\\"]?[A-Za-z0-9+/=]{5,}['\\\"]?"), 4, 0)
 61
 62
 63| eval suspicious_cmdlets=if(match(ScriptBlockText, "(?i)Add-Exfiltration
 64|Add-Persistence
 65|Add-RegBackdoor
 66|Add-ScrnSaveBackdoor
 67|Check-VM
 68|Do-Exfiltration
 69|Enabled-DuplicateToken
 70|Exploit-
 71|Find-Fruit
 72|Find-GPOLocation
 73|Find-TrustedDocuments
 74|Get-ApplicationHost
 75|Get-ChromeDump
 76|Get-ClipboardContents
 77|Get-FoxDump
 78|Get-GPPPassword
 79|Get-IndexedItem
 80|Get-Keystrokes
 81|LSASecret
 82|Get-PassHash
 83|Get-RegAlwaysInstallElevated
 84|Get-RegAutoLogon
 85|Get-RickAstley
 86|Get-Screenshot
 87|Get-SecurityPackages
 88|Get-ServiceFilePermission
 89|Get-ServicePermission
 90|Get-ServiceUnquoted
 91|Get-SiteListPassword
 92|Get-System
 93|Get-TimedScreenshot
 94|Get-UnattendedInstallFile
 95|Get-Unconstrained
 96|Get-VaultCredential
 97|Get-VulnAutoRun
 98|Get-VulnSchTask
 99|Gupt-Backdoor
100|HTTP-Login
101|Install-SSP
102|Install-ServiceBinary
103|Invoke-ACLScanner
104|Invoke-ADSBackdoor
105|Invoke-ARPScan
106|Invoke-AllChecks
107|Invoke-BackdoorLNK
108|Invoke-BypassUAC
109|Invoke-CredentialInjection
110|Invoke-DCSync
111|Invoke-DllInjection
112|Invoke-DowngradeAccount
113|Invoke-EgressCheck
114|Invoke-Inveigh
115|Invoke-InveighRelay
116|Invoke-Mimikittenz
117|Invoke-NetRipper
118|Invoke-NinjaCopy
119|Invoke-PSInject
120|Invoke-Paranoia
121|Invoke-PortScan
122|Invoke-PoshRat
123|Invoke-PostExfil
124|Invoke-PowerDump
125|Invoke-PowerShellTCP
126|Invoke-PsExec
127|Invoke-PsUaCme
128|Invoke-ReflectivePEInjection
129|Invoke-ReverseDNSLookup
130|Invoke-RunAs
131|Invoke-SMBScanner
132|Invoke-SSHCommand
133|Invoke-Service
134|Invoke-Shellcode
135|Invoke-Tater
136|Invoke-ThunderStruck
137|Invoke-Token
138|Invoke-UserHunter
139|Invoke-VoiceTroll
140|Invoke-WScriptBypassUAC
141|Invoke-WinEnum
142|MailRaider
143|New-HoneyHash
144|Out-Minidump
145|Port-Scan
146|PowerBreach
147|PowerUp
148|PowerView
149|Remove-Update
150|Set-MacAttribute
151|Set-Wallpaper
152|Show-TargetScreen
153|Start-CaptureServer
154|VolumeShadowCopyTools
155|NEEEEWWW
156|(Computer
157|User)Property
158|CachedRDPConnection
159|invoke-\S+hunter
160|Install-Service
161|get-\S+(credent
162|password)
163|remoteps
164|netfirewall
165|Uninstall-Windows
166|AmsiBypass
167|nishang
168|Invoke-Interceptor
169|EXEonRemote
170|NetworkRelay
171|PowerShelludp
172|PowerShellIcmp
173|CreateShortcut
174|copy-vss
175|invoke-dll
176|invoke-mass
177|out-shortcut
178|Invoke-ShellCommand"),1,0)
179
180
181| eval base64_keyword=if(like(script_lower,"%frombase64%"), 4, 0)
182
183
184| eval empire=if(like(script_lower,"%system.net.webclient%") AND like(script_lower,"%frombase64%"),5,0)
185
186
187| eval mimikatz=if(like(script_lower,"%mimikatz%") OR like(script_lower,"%-dumpcr%") OR like(script_lower,"%sekurlsa::pth%") OR like(script_lower,"%kerberos::ptt%") OR like(script_lower,"%kerberos::golden%"),5,0)
188
189
190| eval invoke_expression_keyword=if(like(script_lower,"%iex %") OR like(script_lower,"%invoke-expression %"),2,0)
191
192
193| eval webclient=if(like(script_lower,"%webclient%") OR like(script_lower,"%webrequest%") OR like(script_lower,"%downloadfile%") OR like(script_lower,"%downloadstring%") OR like(script_lower,"%bitstransfer%") OR like(script_lower,"%internetexplorer.application%") OR like(script_lower,"%xmlhttp%"),5,0)
194
195
196| eval suspicious_keyword=if(match(script_lower, "(metasp
197|assemblybuilderaccess
198|reflection\.assembly
199|shellcode
200|injection
201|cnvert
202|shell\.application
203|start-process 
204|rc4bytestream
205|system\.security\.cryptography
206|lsass\.exe
207|localadmin
208|lastloggedon
209|hijack
210|backupprivilege
211|ngrok
212|comsvcs
213|backdoor
214|brute.?force
215|port.?scan
216|exfiltration
217|exploit
218|disablerealtimemonitoring
219|beacon)"),1,0)
220
221
222| eval invoke_wmi_keyword=if(like(script_lower,"%wmiobject%") OR like(script_lower,"%wmimethod%") OR like(script_lower,"%remotewmi%") OR like(script_lower,"%powershellwmi%") OR like(script_lower,"%wmicommand%"),5,0)
223
224
225| eval downgrade_version=if(like(script_lower, "% -version 2%"),3,0)
226
227
228| eval compression_keyword=if(match(script_lower, "gzipstream
229|::decompress
230|io.compression
231|write-zip
232|(expand
233|compress)-archive"),5,0)
234
235
236| eval invoke_command_keyword=if(like(script_lower,"%invoke-command%"), 4, 0)
237
238
239| eval Score=ecnoded_command_keyword
240    + suspicious_cmdlets
241    + suspicious_keyword
242    + compression_keyword
243    + downgrade_version
244    + mimikatz
245    + invoke_expression_keyword
246    + empire
247    + webclient
248    + invoke_wmi_keyword
249    + invoke_command_keyword
250    + base64_keyword
251
252
253| where Score>=4 OR mimikatz>0 OR suspicious_cmdlets>0 OR suspicious_keyword>0
254
255
256| eval matched_rules=mvappend(
257    if(ecnoded_command_keyword>0, "Encoded Command Keywords", null()),
258    if(suspicious_cmdlets>0, "Suspicious Cmdlets", null()),
259    if(base64_keyword>0, "Base64 Keyword", null()),
260    if(empire>0, "Empire Framework Commands", null()),
261    if(mimikatz>0, "Mimikatz Keywords or Strings", null()),
262    if(invoke_expression_keyword>0, "Invoke Expression Keywords", null()),
263    if(webclient>0, "Webclient Keywords", null()),
264    if(suspicious_keyword>0, "Potentially Suspicious Keywords or Strings", null()),
265    if(invoke_wmi_keyword>0, "Invoke WMI Keywords", null()),
266    if(downgrade_version>0, "PowerShell Downgrade Version Attempt", null()),
267    if(compression_keyword>0, "Compression Keywords", null()),
268    if(invoke_command_keyword>0, "Invoke Command Keywords", null())
269)
270
271
272| eval matched_rules=mvfilter(isnotnull(matched_rules))
273
274
275| rename Computer as dest, UserID as user
276
277
278| stats max(Score) as Score values(matched_rules) as matched_rules
279  BY user dest ScriptBlockId
280
281
282| eval matched_rules=mvjoin(matched_rules, ", ")
283
284
285| `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 ingested with ScriptBlockLogging enabled. Modify the powershell macro as needed to match the sourcetype or add index. This analytic is specific to EventID 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: 29