Windows.Analysis.SuspiciousWMIConsumers

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