| ID | Technique | Tactic |
|---|---|---|
| T1059.001 | PowerShell | Execution |
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` EventCode=4104
2
3| eval DoIt = if(match(ScriptBlockText,"(?i)(\$doit)"), "4", 0)
4
5| eval enccom=if(match(ScriptBlockText,"[A-Za-z0-9+\/]{44,}([A-Za-z0-9+\/]{4}
6
7| [A-Za-z0-9+\/]{3}=
8
9| [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)
10
11| eval suspcmdlet=if(match(ScriptBlockText, "(?i)Add-Exfiltration
12
13| Add-Persistence
14
15| Add-RegBackdoor
16
17| Add-ScrnSaveBackdoor
18
19| Check-VM
20
21| Do-Exfiltration
22
23| Enabled-DuplicateToken
24
25| Exploit-Jboss
26
27| Find-Fruit
28
29| Find-GPOLocation
30
31| Find-TrustedDocuments
32
33| Get-ApplicationHost
34
35| Get-ChromeDump
36
37| Get-ClipboardContents
38
39| Get-FoxDump
40
41| Get-GPPPassword
42
43| Get-IndexedItem
44
45| Get-Keystrokes
46
47| LSASecret
48
49| Get-PassHash
50
51| Get-RegAlwaysInstallElevated
52
53| Get-RegAutoLogon
54
55| Get-RickAstley
56
57| Get-Screenshot
58
59| Get-SecurityPackages
60
61| Get-ServiceFilePermission
62
63| Get-ServicePermission
64
65| Get-ServiceUnquoted
66
67| Get-SiteListPassword
68
69| Get-System
70
71| Get-TimedScreenshot
72
73| Get-UnattendedInstallFile
74
75| Get-Unconstrained
76
77| Get-VaultCredential
78
79| Get-VulnAutoRun
80
81| Get-VulnSchTask
82
83| Gupt-Backdoor
84
85| HTTP-Login
86
87| Install-SSP
88
89| Install-ServiceBinary
90
91| Invoke-ACLScanner
92
93| Invoke-ADSBackdoor
94
95| Invoke-ARPScan
96
97| Invoke-AllChecks
98
99| Invoke-BackdoorLNK
100
101| Invoke-BypassUAC
102
103| Invoke-CredentialInjection
104
105| Invoke-DCSync
106
107| Invoke-DllInjection
108
109| Invoke-DowngradeAccount
110
111| Invoke-EgressCheck
112
113| Invoke-Inveigh
114
115| Invoke-InveighRelay
116
117| Invoke-Mimikittenz
118
119| Invoke-NetRipper
120
121| Invoke-NinjaCopy
122
123| Invoke-PSInject
124
125| Invoke-Paranoia
126
127| Invoke-PortScan
128
129| Invoke-PoshRat
130
131| Invoke-PostExfil
132
133| Invoke-PowerDump
134
135| Invoke-PowerShellTCP
136
137| Invoke-PsExec
138
139| Invoke-PsUaCme
140
141| Invoke-ReflectivePEInjection
142
143| Invoke-ReverseDNSLookup
144
145| Invoke-RunAs
146
147| Invoke-SMBScanner
148
149| Invoke-SSHCommand
150
151| Invoke-Service
152
153| Invoke-Shellcode
154
155| Invoke-Tater
156
157| Invoke-ThunderStruck
158
159| Invoke-Token
160
161| Invoke-UserHunter
162
163| Invoke-VoiceTroll
164
165| Invoke-WScriptBypassUAC
166
167| Invoke-WinEnum
168
169| MailRaider
170
171| New-HoneyHash
172
173| Out-Minidump
174
175| Port-Scan
176
177| PowerBreach
178
179| PowerUp
180
181| PowerView
182
183| Remove-Update
184
185| Set-MacAttribute
186
187| Set-Wallpaper
188
189| Show-TargetScreen
190
191| Start-CaptureServer
192
193| VolumeShadowCopyTools
194
195| NEEEEWWW
196
197| (Computer
198
199| User)Property
200
201| CachedRDPConnection
202
203| get-net\S+
204
205| invoke-\S+hunter
206
207| Install-Service
208
209| get-\S+(credent
210
211| password)
212
213| remoteps
214
215| Kerberos.*(policy
216
217| ticket)
218
219| netfirewall
220
221| Uninstall-Windows
222
223| Verb\s+Runas
224
225| AmsiBypass
226
227| nishang
228
229| Invoke-Interceptor
230
231| EXEonRemote
232
233| NetworkRelay
234
235| PowerShelludp
236
237| PowerShellIcmp
238
239| CreateShortcut
240
241| copy-vss
242
243| invoke-dll
244
245| invoke-mass
246
247| out-shortcut
248
249| Invoke-ShellCommand"),1,0)
250
251| eval base64 = if(match(lower(ScriptBlockText),"frombase64"), "4", 0)
252
253| eval empire=if(match(lower(ScriptBlockText),"system.net.webclient") AND match(lower(ScriptBlockText), "frombase64string") ,5,0)
254
255| 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)
256
257| eval iex=if(match(ScriptBlockText, "(?i)iex
258
259| invoke-expression"),2,0)
260
261| eval webclient=if(match(lower(ScriptBlockText),"http") OR match(lower(ScriptBlockText),"web(client
262
263| request)") OR match(lower(ScriptBlockText),"socket") OR match(lower(ScriptBlockText),"download(file
264
265| string)") OR match(lower(ScriptBlockText),"bitstransfer") OR match(lower(ScriptBlockText),"internetexplorer.application") OR match(lower(ScriptBlockText),"xmlhttp"),5,0)
266
267| eval get = if(match(lower(ScriptBlockText),"get-"), "1", 0)
268
269| eval rundll32 = if(match(lower(ScriptBlockText),"rundll32"), "4", 0)
270
271| eval suspkeywrd=if(match(ScriptBlockText, "(?i)(bitstransfer
272
273| mimik
274
275| metasp
276
277| AssemblyBuilderAccess
278
279| Reflection\.Assembly
280
281| shellcode
282
283| injection
284
285| cnvert
286
287| shell\.application
288
289| start-process
290
291| Rc4ByteStream
292
293| System\.Security\.Cryptography
294
295| lsass\.exe
296
297| localadmin
298
299| LastLoggedOn
300
301| hijack
302
303| BackupPrivilege
304
305| ngrok
306
307| comsvcs
308
309| backdoor
310
311| brute.?force
312
313| Port.?Scan
314
315| Exfiltration
316
317| exploit
318
319| DisableRealtimeMonitoring
320
321| beacon)"),1,0)
322
323| eval syswow64 = if(match(lower(ScriptBlockText),"syswow64"), "3", 0)
324
325| eval httplocal = if(match(lower(ScriptBlockText),"http://127.0.0.1"), "4", 0)
326
327| eval reflection = if(match(lower(ScriptBlockText),"reflection"), "1", 0)
328
329| eval invokewmi=if(match(lower(ScriptBlockText), "(?i)(wmiobject
330
331| WMIMethod
332
333| RemoteWMI
334
335| PowerShellWmi
336
337| wmicommand)"),5,0)
338
339| eval downgrade=if(match(ScriptBlockText, "(?i)([-]ve*r*s*i*o*n*\s+2)") OR match(lower(ScriptBlockText),"powershell -version"),3,0)
340
341| eval compressed=if(match(ScriptBlockText, "(?i)GZipStream
342
343| ::Decompress
344
345| IO.Compression
346
347| write-zip
348
349| (expand
350
351| compress)-Archive"),5,0)
352
353| eval invokecmd = if(match(lower(ScriptBlockText),"invoke-command"), "4", 0)
354
355| addtotals fieldname=Score DoIt, enccom, suspcmdlet, suspkeywrd, compressed, downgrade, mimikatz, iex, empire, rundll32, webclient, syswow64, httplocal, reflection, invokewmi, invokecmd, base64, get
356
357| stats values(Score)
358 BY UserID, Computer, DoIt,
359 enccom, compressed, downgrade,
360 iex, mimikatz, rundll32,
361 empire, webclient, syswow64,
362 httplocal, reflection, invokewmi,
363 invokecmd, base64, get,
364 suspcmdlet, suspkeywrd
365
366| rename Computer as dest, UserID as user
367
368| `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 Risk Event | False |
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
-
https://github.com/inodee/threathunting-spl/blob/master/hunt-queries/powershell_qualifiers.md
-
https://github.com/marcurdy/dfir-toolset/blob/master/Powershell%20Blueteam.txt
-
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 |
| Integration | ✅ 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: 22