This Artifact will search and extract ScriptBlock events (Event ID 4104) from Powershell-Operational Event Logs.
Powershell is commonly used by attackers across all stages of the attack lifecycle. A valuable hunt is to search Scriptblock logs for signs of malicious content.
There are several parameter’s available for search leveraging regex.
name: Windows.EventLogs.PowershellScriptblock
author: Matt Green - @mgreen27
description: |
This Artifact will search and extract ScriptBlock events (Event ID 4104) from
Powershell-Operational Event Logs.
Powershell is commonly used by attackers across all stages of the attack
lifecycle. A valuable hunt is to search Scriptblock logs for signs of
malicious content.
There are several parameter's available for search leveraging regex.
- DateAfter enables search for events after this date.
- DateBefore enables search for events before this date.
- SearchStrings enables regex search over scriptblock text field.
- StringWhiteList enables a regex whitelist for scriptblock text field.
- PathWhitelist enables a regex whitelist for path of scriptblock.
- LogLevel enables searching on type of log. Default is Warning level which
is logged even if ScriptBlock logging is turned off when suspicious keywords
detected in Powershell interpreter. See second reference for list of keywords.
- SearchVSS enables VSS search.
reference:
- https://attack.mitre.org/techniques/T1059/001/
- https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs#L1781-L1943
parameters:
- name: EvtxGlob
default: '%SystemRoot%\System32\winevt\logs\Microsoft-Windows-PowerShell%4Operational.evtx'
- name: DateAfter
description: "search for events after this date. YYYY-MM-DDTmm:hh:ss Z"
type: timestamp
- name: DateBefore
description: "search for events before this date. YYYY-MM-DDTmm:hh:ss Z"
type: timestamp
- name: SearchStrings
type: regex
description: "regex search over scriptblock text field."
- name: StringWhitelist
description: "Regex of string to witelist"
type: regex
- name: PathWhitelist
description: "Regex of path to whitelist."
type: regex
- name: LogLevel
description: "Log level. Warning is Powershell default bad keyword list."
type: choices
default: Warning
choices:
- All
- Warning
- Verbose
- name: LogLevelMap
type: hidden
default: |
Choice,Regex
All,"."
Warning,"3"
Verbose,"5"
- name: VSSAnalysisAge
type: int
default: 0
description: |
If larger than zero we analyze VSS within this many days
ago. (e.g 7 will analyze all VSS within the last week). Note
that when using VSS analysis we have to use the ntfs accessor
for everything which will be much slower.
sources:
- query: |
LET VSS_MAX_AGE_DAYS <= VSSAnalysisAge
LET Accessor = if(condition=VSSAnalysisAge > 0, then="ntfs_vss", else="auto")
-- firstly set timebounds for performance
LET DateAfterTime <= if(condition=DateAfter,
then=timestamp(epoch=DateAfter), else=timestamp(epoch="1600-01-01"))
LET DateBeforeTime <= if(condition=DateBefore,
then=timestamp(epoch=DateBefore), else=timestamp(epoch="2200-01-01"))
-- Parse Log level dropdown selection
LET LogLevelRegex <= SELECT format(format="%v", args=Regex) as value
FROM parse_csv(filename=LogLevelMap, accessor="data")
WHERE Choice=LogLevel LIMIT 1
-- expand provided glob into a list of paths on the file system (fs)
LET fspaths = SELECT OSPath
FROM glob(globs=expand(path=EvtxGlob), accessor=Accessor)
-- function returning IOC hits
LET evtxsearch(PathList) = SELECT * FROM foreach(
row=PathList,
query={
SELECT
timestamp(epoch=int(int=System.TimeCreated.SystemTime)) AS EventTime,
System.Computer as Computer,
System.Channel as Channel,
System.EventID.Value as EventID,
System.Security.UserID as SecurityID,
EventData.Path as Path,
EventData.ScriptBlockId as ScriptBlockId,
EventData.ScriptBlockText as ScriptBlockText,
get(field="Message") as Message,
System.EventRecordID as EventRecordID,
System.Level as Level,
System.Opcode as Opcode,
System.Task as Task,
OSPath
FROM parse_evtx(filename=OSPath, accessor=Accessor)
WHERE System.EventID.Value = 4104
AND EventTime < DateBeforeTime
AND EventTime > DateAfterTime
AND format(format="%d", args=System.Level) =~ LogLevelRegex.value[0]
AND if(condition=SearchStrings,
then=ScriptBlockText =~ SearchStrings,
else=TRUE)
AND if(condition=StringWhitelist,
then= NOT ScriptBlockText =~ StringWhitelist,
else=TRUE)
AND if(condition=PathWhitelist,
then= NOT Path =~ PathWhitelist,
else=TRUE)
})
SELECT * FROM evtxsearch(PathList=fspaths)