| ID | Technique | Tactic |
|---|---|---|
| T1003 | OS Credential Dumping | Credential Access |
| T1059.001 | PowerShell | Execution |
| T1689 | Downgrade Attack | Defense Impairment |
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.
Search
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 | '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 |
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
-
https://github.com/marcurdy/dfir-toolset/blob/master/Powershell%20Blueteam.txt
-
https://github.com/inodee/threathunting-spl/blob/master/hunt-queries/powershell_qualifiers.md
-
https://devblogs.microsoft.com/powershell/powershell-the-blue-team/
-
https://hurricanelabs.com/splunk-tutorials/how-to-use-powershell-transcription-logs-in-splunk/
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