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