Detection rules › Kusto

Semperis DSP Failed Logons

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

'Alerts when there are failed logons in the DSP system.'

MITRE ATT&CK coverage

TacticTechniques
Initial AccessT1078 Valid Accounts
Credential AccessT1110 Brute Force

Rule body kusto

id: "0e105444-fe13-4ce6-9239-21880076a3f9"
name: Semperis DSP Failed Logons
description: | 
  'Alerts when there are failed logons in the DSP system.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: SemperisDSP
    dataTypes:
      - dsp_parser
queryFrequency: 30m
queryPeriod: 30m
tactics:
  - InitialAccess
  - CredentialAccess
relevantTechniques:
  - T1078
  - T1110
triggerOperator: gt
triggerThreshold: 0
query: |
  SecurityEvent
  | where EventSourceName == 'Semperis-Operation-Log' and EventID == 20002
  | sort by TimeGenerated desc 
  | 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)
  | extend det = column_ifexists('details', '')
  | parse det with * "Trustee Name: " TrusteeName " Correlation ID: " * " Source: " HostIP "WebSite Target" *
  | extend host = tostring(HostIP)
  | extend HostIP = trim_end(":", HostIP)
  | project TimeGenerated, TrusteeName, HostIP, _ResourceId
  | extend NTDomain = tostring(split(TrusteeName, '\\', 0)[0]), Name = tostring(split(TrusteeName, '\\', 1)[0]) 
entityMappings:
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: HostIP
  - entityType: Account
    fieldMappings:
      - identifier: Name
        columnName: Name
      - identifier: NTDomain
        columnName: NTDomain
eventGroupingSettings:
  aggregationKind: SingleAlert
alertDetailsOverride:
  alertDisplayNameFormat: Failed Logon -- Alert from Semperis Directory Services Protector
  alertDescriptionFormat: A failed logon was detected to the DSP system.
version: 2.0.7
kind: Scheduled

Stages and Predicates

Stage 1: source

SecurityEvent

Stage 2: where

| where EventSourceName == 'Semperis-Operation-Log' and EventID == 20002

Stage 3: sort

| sort by TimeGenerated desc

Stage 4: extend

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

Stage 5: mv-expand

| mv-expand bagexpansion=array p1Xml

Stage 6: evaluate

| evaluate bag_unpack(p1Xml)

Stage 7: extend

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

Stage 8: evaluate

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

Stage 9: extend

| extend det = column_ifexists('details', '')

Stage 10: parse

| parse det with * "Trustee Name: " TrusteeName " Correlation ID: " * " Source: " HostIP "WebSite Target" *

Stage 11: extend

| extend host = tostring(HostIP)

Stage 12: extend

| extend HostIP = trim_end(":", HostIP)

Stage 13: project

| project TimeGenerated, TrusteeName, HostIP, _ResourceId

Stage 14: extend

| extend NTDomain = tostring(split(TrusteeName, '\\', 0)[0]), Name = tostring(split(TrusteeName, '\\', 1)[0])

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
  • 20002 transforms: cased
EventSourceNameeq
  • Semperis-Operation-Log transforms: cased corpus 2 (kusto 2)

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
HostIPproject
TimeGeneratedproject
TrusteeNameproject
_ResourceIdproject
NTDomainextend
Nameextend