Detection rules › Kusto

Semperis DSP Operations Critical Notifications

Status
available
Severity
medium
Time window
30m
Source
github.com/Azure/Azure-Sentinel

'Alerts when there are critical notifications fired in the DSP system.'

MITRE ATT&CK coverage

TacticTechniques
Resource DevelopmentT1584 Compromise Infrastructure
Initial AccessT1133 External Remote Services
Credential AccessT1110 Brute Force

Rule body kusto

id: "8f471e21-3bb2-466f-9bc2-0a0326a60788"
name: Semperis DSP Operations Critical Notifications 
description: |
  'Alerts when there are critical notifications fired in the DSP system.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: SemperisDSP
    dataTypes:
      - dsp_parser
queryFrequency: 30m
queryPeriod: 30m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - InitialAccess
  - CredentialAccess
  - ResourceDevelopment
relevantTechniques:
  - T1133
  - T1110
  - T1584
query: |
  SecurityEvent
  | where EventSourceName == 'Semperis-DSP-Notifications' and EventID == 30001
  | extend p1Xml = parse_xml(EventData).EventData.Data
  | mv-expand bagexpansion=array p1Xml
  | evaluate bag_unpack(p1Xml)
  | extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')
  | evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)
  | parse column_ifexists('objectDN', '') with * "CN=" cnName "," *
  | where "Critical" == column_ifexists('severity', "")
  | extend changedBy = column_ifexists('changedBy', "")
  | extend NTDomain = tostring(split(changedBy, '\\', 0)[0]), LoginUser = tostring(split(changedBy, '\\', 1)[0])
  | extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: LoginUser
      - identifier: NTDomain
        columnName: NTDomain
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: DnsDomain
eventGroupingSettings:
  aggregationKind: SingleAlert
alertDetailsOverride:
  alertDisplayNameFormat: Critical Notification -- Alert from Semperis Directory Services Protector
  alertDescriptionFormat: A critical notification was created in the DSP system.
version: 2.0.7
kind: Scheduled

Stages and Predicates

Stage 1: source

SecurityEvent

Stage 2: where

| where EventSourceName == 'Semperis-DSP-Notifications' and EventID == 30001

Stage 3: extend

| extend p1Xml = parse_xml(EventData).EventData.Data

Stage 4: mv-expand

| mv-expand bagexpansion=array p1Xml

Stage 5: evaluate

| evaluate bag_unpack(p1Xml)

Stage 6: extend

| extend Name=column_ifexists('@Name', ''), Value=column_ifexists('#text', '')

Stage 7: evaluate

| evaluate pivot(Name, any(Value), TimeGenerated, EventSourceName, Channel, Computer, Level, EventLevelName, EventID, Task, Type, _ResourceId)

Stage 8: parse

| parse column_ifexists('objectDN', '') with * "CN=" cnName "," *

Stage 9: where

| where "Critical" == column_ifexists('severity', "")

Stage 10: extend (3 consecutive steps)

| extend changedBy = column_ifexists('changedBy', "")
| extend NTDomain = tostring(split(changedBy, '\\', 0)[0]), LoginUser = tostring(split(changedBy, '\\', 1)[0])
| extend HostName = tostring(split(Computer, '.', 0)[0]), DnsDomain = tostring(strcat_array(array_slice(split(Computer, '.'), 1, -1), '.'))

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
EventIDeq
  • 30001 transforms: cased
EventSourceNameeq
  • Semperis-DSP-Notifications transforms: cased

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
p1Xmlextend
Nameextend
Valueextend
changedByextend
LoginUserextend
NTDomainextend
DnsDomainextend
HostNameextend