Skip to content

CIM: consumerbindings() Only scans default subscription namespace #1382

@nbareil

Description

@nbareil

Summary

The consumerbindings method in the Windows CIM plugin currently only inspects the default subscription namespace:

self._subscription_ns = self._repo.root.namespace("subscription")

As a result, it misses legitimate or malicious __FilterToConsumerBinding instances created in other namespaces (e.g. root/another).

This anti-forensic TTP enables the threat actor to remain invisible on most security tools.

Steps to Reproduce

You can reproduce the issue by creating a WMI event binding in a non-standard namespace:

1. Create Event Filter in a custom namespace
   $FilterArgs = @{
       Name = 'Pentestlab-WMI'
       EventNameSpace = 'root/another'
       QueryLanguage = 'WQL'
       Query = "SELECT \* FROM __InstanceCreationEvent WITHIN 3 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'msedge.exe'"
   }
   $Filter = Get-CimInstance -Namespace 'root/another' -ClassName __EventFilter |
       Where-Object {
           $_.Name -eq 'Pentestlab-WMI' -and
           $_.Query -match "msedge.exe"
       }

1. Create Command Line Consumer
   $ConsumerArgs = @{
       Name = 'Pentestlab-WMI'
       CommandLineTemplate = "$($Env:SystemRoot)
   System32
   shell64.exe"
   }
   $Consumer = New-CimInstance -Namespace 'root/default' -ClassName CommandLineEventConsumer -Property $ConsumerArgs

1. Create Filter-to-Consumer Binding in the same custom namespace
   $FilterToConsumerArgs = @{
       Filter = [Ref] $Filter
       Consumer = [Ref] $Consumer
   }
   $FilterToConsumerBinding = New-CimInstance -Namespace 'root/another' -ClassName __FilterToConsumerBinding -Property $FilterToConsumerArgs

Attached is the resulting WMI repository: sample.zip

Test Script

Using the test script reproduce_cim_error.py:

% python /tmp/reproduce_cim_error.py /tmp/sample.zip
Extracted files: ['MAPPING1.MAP', 'MAPPING2.MAP', 'MAPPING3.MAP', 'OBJECTS.DATA', 'INDEX.BTR']
CIM repository opened successfully
Found 0 consumer bindings

Expected Behavior

The output should list bindings found in all namespaces, not just the default one.
For example:

% python /tmp/reproduce_cim_error.py /tmp/sample.zip
Extracted files: ['MAPPING1.MAP', 'MAPPING2.MAP', 'MAPPING3.MAP', 'OBJECTS.DATA', 'INDEX.BTR']
CIM repository opened successfully
Found 3 consumer bindings
Filter: SCM Event Log Filter, Consumer: <dissect.cim.cim.Instance object at 0x10255c550>
Filter: Pentestlab-WMI, Consumer: <dissect.cim.cim.Instance object at 0x1025582b0>
Filter: Pentestlab-WMI, Consumer: <dissect.cim.cim.Instance object at 0x102610dd0>

Suggested Fix

Iterate over *all available namespaces* rather than assuming subscription as the default.
This could be done by dynamically discovering namespaces in the plugin logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions