Detection rules › Kusto

COM Registry Key Modified to Point to File in Color Profile Folder

Severity
medium
Time window
1d
Author
Microsoft Security Research
Source
github.com/Azure/Azure-Sentinel

This query looks for changes to COM registry keys to point to files in C:\Windows\System32\spool\drivers\color. This can be used to enable COM hijacking for persistence. Ref: https://www.microsoft.com/security/blog/2022/07/27/untangling-knotweed-european-private-sector-offensive-actor-using-0-day-exploits/

MITRE ATT&CK coverage

Event coverage

Rule body kusto

id: ed8c9153-6f7a-4602-97b4-48c336b299e1
name: COM Registry Key Modified to Point to File in Color Profile Folder
description: |
  'This query looks for changes to COM registry keys to point to files in C:\Windows\System32\spool\drivers\color\.
    This can be used to enable COM hijacking for persistence.
    Ref: https://www.microsoft.com/security/blog/2022/07/27/untangling-knotweed-european-private-sector-offensive-actor-using-0-day-exploits/'
severity: Medium
requiredDataConnectors:
  - connectorId: MicrosoftThreatProtection
    dataTypes:
      - DeviceRegistryEvents
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvents
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Persistence
relevantTechniques:
  - T1574
tags:
  - KNOTWEED
query: |
  let guids = dynamic(["{ddc05a5a-351a-4e06-8eaf-54ec1bc2dcea}","{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}","{4590f811-1d3a-11d0-891f-00aa004b2e24}", "{4de225bf-cf59-4cfc-85f7-68b90f185355}", "{F56F6FDD-AA9D-4618-A949-C1B91AF43B1A}"]);
    let mde_data = DeviceRegistryEvents
    | where ActionType =~ "RegistryValueSet"
    | where RegistryKey contains "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID"
    | where RegistryKey has_any (guids)
    | where RegistryValueData has "System32\\spool\\drivers\\color";
    let event_data = SecurityEvent
    | where EventID == 4657
    | where ObjectName contains "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID"
    | where ObjectName has_any (guids)
    | where NewValue has "System32\\spool\\drivers\\color"
    | extend RegistryKey = ObjectName, RegistryValueData = NewValue, DeviceName=Computer, InitiatingProcessFileName = Process, InitiatingProcessAccountName=SubjectUserName, InitiatingProcessAccountDomain = SubjectDomainName;
    union mde_data, event_data
    | extend HostName = tostring(split(DeviceName, ".")[0]), DomainIndex = toint(indexof(DeviceName, '.'))
    | extend HostNameDomain = iff(DomainIndex != -1, substring(DeviceName, DomainIndex + 1), DeviceName)
entityMappings:
  - entityType: RegistryKey
    fieldMappings:
      - identifier: Key
        columnName: RegistryKey
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: DeviceName
      - identifier: HostName
        columnName: HostName
      - identifier: NTDomain
        columnName: HostNameDomain
  - entityType: Process
    fieldMappings:
      - identifier: ProcessId
        columnName: InitiatingProcessFileName
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: InitiatingProcessAccountName
      - identifier: NTDomain
        columnName: InitiatingProcessAccountName
version: 1.1.1
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Microsoft Security Research
    support:
        tier: Community
    categories:
        domains: [ "Security - Others" ]

Stages and Predicates

Let binding: guids

let guids = dynamic(["{ddc05a5a-351a-4e06-8eaf-54ec1bc2dcea}","{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}","{4590f811-1d3a-11d0-891f-00aa004b2e24}", "{4de225bf-cf59-4cfc-85f7-68b90f185355}", "{F56F6FDD-AA9D-4618-A949-C1B91AF43B1A}"]);

Let binding: mde_data

let mde_data = DeviceRegistryEvents
  | where ActionType =~ "RegistryValueSet"
  | where RegistryKey contains "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID"
  | where RegistryKey has_any (guids)
  | where RegistryValueData has "System32\\spool\\drivers\\color";

Derived from guids.

Let binding: event_data

let event_data = SecurityEvent
  | where EventID == 4657
  | where ObjectName contains "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID"
  | where ObjectName has_any (guids)
  | where NewValue has "System32\\spool\\drivers\\color"
  | extend RegistryKey = ObjectName, RegistryValueData = NewValue, DeviceName=Computer, InitiatingProcessFileName = Process, InitiatingProcessAccountName=SubjectUserName, InitiatingProcessAccountDomain = SubjectDomainName;

Derived from guids.

union (2 sources)

Each leg below queries one source; the rule matches if any leg does. Sources: mde_data, event_data

Leg 1: mde_data

Leg 2: event_data

Applied to the combined result

| extend HostName = tostring(split(DeviceName, ".")[0]), DomainIndex = toint(indexof(DeviceName, '.')) | extend HostNameDomain = iff(DomainIndex != -1, substring(DeviceName, DomainIndex + 1), DeviceName)

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
ActionTypeeq
  • RegistryValueSet corpus 4 (kusto 4)
EventIDeq
  • 4657 transforms: cased corpus 17 (splunk 14, kusto 3)
NewValuematch
  • System32\\spool\\drivers\\color transforms: term
ObjectNamecontains
  • HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID
ObjectNamematch
  • {1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}
  • {4590f811-1d3a-11d0-891f-00aa004b2e24}
  • {4de225bf-cf59-4cfc-85f7-68b90f185355}
  • {F56F6FDD-AA9D-4618-A949-C1B91AF43B1A}
  • {ddc05a5a-351a-4e06-8eaf-54ec1bc2dcea}
RegistryKeycontains
  • HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID
RegistryKeymatch
  • {1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}
  • {4590f811-1d3a-11d0-891f-00aa004b2e24}
  • {4de225bf-cf59-4cfc-85f7-68b90f185355}
  • {F56F6FDD-AA9D-4618-A949-C1B91AF43B1A}
  • {ddc05a5a-351a-4e06-8eaf-54ec1bc2dcea}
RegistryValueDatamatch
  • System32\\spool\\drivers\\color transforms: term

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
DeviceNameextend
InitiatingProcessAccountDomainextend
InitiatingProcessAccountNameextend
InitiatingProcessFileNameextend
RegistryKeyextend
RegistryValueDataextend
DomainIndexextend
HostNameextend
HostNameDomainextend