This artifact reports suspicious WMI Event Consumers and their associated Filters that may indicate a malicious abuse for persistence.
NOTE: This artifact uses the same logic as Windows.Persistence.PermanentWMIEvents however, this artifact narrows down the reported results based on a research by SANS.
name: Windows.Analysis.SuspiciousWMIConsumers
description: |
This artifact reports suspicious WMI Event Consumers and their associated Filters
that may indicate a malicious abuse for persistence.
NOTE: This artifact uses the same logic as Windows.Persistence.PermanentWMIEvents
however, this artifact narrows down the reported results based on a research by SANS.
reference:
- https://youtu.be/aBQ1vEjK6v4
author: Amged Wageh - @amgdgocha
parameters:
- name: AllRootNamespaces
description: Select to scan all ROOT namespaces. This setting over rides specific namespaces configured below.
type: bool
- name: Namespaces
description: Add a list of target namespaces.
type: csv
default: |
namespace
root/subscription
root/default
- name: InterstingConsumerTypes
description: A list of the most abused event consumer types.
type: csv
default: |
consumer_types
ActiveScriptEventConsumer
CommandLineEventConsumer
- name: KnownGoodFilters
description: A list of known good filter names.
type: csv
default: |
filter_name
BVTFilter
TSLogonFilter
RmAssistEventFilter
- name: KnownGoodConsumers
description: A list of known good consumer names.
type: csv
default: |
consumer_name
NTEventLogConsumer
"SCM Event Log Consumer"
- name: KnownBadKeywords
description: A list of known bad keywords.
type: csv
default: |
keyword
.exe
.vbs
.ps1
.dll
.eval
activexobject
powershell
commandLinetemplate
scripttext
wscript
- name: KnownGoodKeywords
description: A list of known good scripts and executables.
type: csv
default: |
keyword
TSLogonEvents.vbs
RAevent.vbs
KernCap.vbs
WSCEAA.exe
- name: ScriptingEngines
description: A list of the ActiveScriptEventConsumer scripting engines.
type: csv
default: |
scripting_engine
VBScript
JScript
sources:
- precondition:
SELECT OS From info() where OS = 'windows'
query: |
LET namespaces <= SELECT * FROM if(condition=AllRootNamespaces,
then= {
SELECT 'root/' + Name as namespace
FROM wmi(namespace='ROOT',query='SELECT * FROM __namespace')
WHERE namespace
},
else= Namespaces)
LET FilterToConsumerBinding <= SELECT * FROM foreach(
row=namespaces,
query={
SELECT parse_string_with_regex(string=Consumer,
regex=['((?P<namespace>^[^:]+):)?(?P<Type>.+?)\\.Name="(?P<Name>.+)"']) as Consumer,
parse_string_with_regex(string=Filter,regex=['((?P<namespace>^[^:]+):)?(?P<Type>.+?)\\.Name="(?P<Name>.+)"']) as Filter
FROM wmi(
query="SELECT * FROM __FilterToConsumerBinding",namespace=namespace)
},workers=len(list=namespaces))
WHERE Consumer.Type IN InterstingConsumerTypes.consumer_types
LET FilterToConsumerBindingLookup <= SELECT * FROM foreach(
row=namespaces,
query={
SELECT {
SELECT * FROM wmi(
query="SELECT * FROM " + Consumer.Type, namespace=Consumer.namespace || namespace)
WHERE Name = Consumer.Name AND NOT
Name IN KnownGoodConsumers.consumer_name
} AS ConsumerDetails,
{
SELECT * FROM wmi(
query="SELECT * FROM " + Filter.Type, namespace=Filter.namespace || namespace)
WHERE Name = Filter.Name AND NOT
Name IN KnownGoodFilters.filter_name
} AS FilterDetails,
namespace as Namespace
FROM FilterToConsumerBinding
WHERE (FilterDetails AND ConsumerDetails)
},workers=len(list=namespaces))
LET SuspiciousFilterToConsumerBindingLookup <= SELECT * FROM foreach(
row=KnownBadKeywords,
query={
SELECT ConsumerDetails, FilterDetails
FROM FilterToConsumerBindingLookup
WHERE lowcase(string=ConsumerDetails.CommandLineTemplate) =~ keyword OR
lowcase(string=ConsumerDetails.ScriptText) =~ keyword OR
ConsumerDetails.ScriptingEngine IN ScriptingEngines.scripting_engine
}
) GROUP BY ConsumerDetails, FilterDetails
SELECT * FROM foreach(
row=KnownGoodKeywords,
query={
SELECT ConsumerDetails, FilterDetails
FROM SuspiciousFilterToConsumerBindingLookup
WHERE NOT ConsumerDetails.CommandLineTemplate =~ keyword
}
) GROUP BY ConsumerDetails, FilterDetails