| 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`
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 | '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 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/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: 26