CIM: `consumerbindings()` Only scans default `subscription` namespace
Summary
The consumerbindings method in the Windows CIM plugin currently only inspects the default subscription namespace:
https://github.com/fox-it/dissect.target/blob/69c908a42bf3e988b7e0e18bd16910c7389c77d2/dissect/target/plugins/os/windows/cim.py#L122
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.