Detection rules › Kusto

Possible Resource-Based Constrained Delegation Abuse

Severity
medium
Time window
1h
Group by
AttributeLDAPDisplayName, Computer, ObjectDN, SubjectAccount, SubjectDomainName, SubjectLogonId, SubjectUserName, SubjectUserSid
Author
Vasileios Paschalidis
Source
github.com/Azure/Azure-Sentinel

This query identifies Active Directory computer objects modifications that allow an adversary to abuse the Resource-based constrained delegation. This query checks for event id 5136 that the Object Class field is "computer" and the LDAP Display Name is "msDS-AllowedToActOnBehalfOfOtherIdentity" which is an indicator of Resource-based constrained delegation. Ref: https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html

MITRE ATT&CK coverage

TacticTechniques
Privilege Escalation

Telemetry coverage

Rule body

id: 2937bc6b-7cda-4fba-b452-ea43ba8e835f
name:  Possible Resource-Based Constrained Delegation Abuse
description: |
  'This query identifies Active Directory computer objects modifications that allow an adversary to abuse the Resource-based constrained delegation. 
  This query checks for event id 5136 that the Object Class field is "computer" and the LDAP Display Name is "msDS-AllowedToActOnBehalfOfOtherIdentity" which is an indicator of Resource-based constrained delegation.
  Ref: https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html'
severity: Medium
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - PrivilegeEscalation
relevantTechniques:
  - T1134
query: |
  SecurityEvent
  | where EventID == 5136 
  | parse EventData with * 'ObjectClass">' ObjectClass "<" *
  | parse EventData with * 'AttributeLDAPDisplayName">' AttributeLDAPDisplayName "<" *
  | where ObjectClass == "computer" and AttributeLDAPDisplayName == "msDS-AllowedToActOnBehalfOfOtherIdentity"
  | parse EventData with * 'ObjectDN">' ObjectDN "<" *
  | summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Computer, SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid, SubjectLogonId, ObjectDN, AttributeLDAPDisplayName
  | extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
  | extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
  | project-away DomainIndex
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: SubjectAccount
      - identifier: Name
        columnName: SubjectUserName
      - identifier: NTDomain
        columnName: SubjectDomainName
  - entityType: Account
    fieldMappings:
      - identifier: Sid
        columnName: SubjectUserSid
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Computer
      - identifier: HostName
        columnName: HostName
      - identifier: DnsDomain
        columnName: HostNameDomain
version: 1.0.3
kind: Scheduled
metadata:
    source:
        kind: Community
    author:
        name: Vasileios Paschalidis
    support:
        tier: Community
    categories:
        domains: [ "Security - Others", "Identity" ]

Stages and Predicates

Stage 1: source

SecurityEvent

Stage 2: where

| where EventID == 5136

Stage 3: parse

| parse EventData with * 'ObjectClass">' ObjectClass "<" *

Stage 4: parse

| parse EventData with * 'AttributeLDAPDisplayName">' AttributeLDAPDisplayName "<" *

Stage 5: where

| where ObjectClass == "computer" and AttributeLDAPDisplayName == "msDS-AllowedToActOnBehalfOfOtherIdentity"

Stage 6: parse

| parse EventData with * 'ObjectDN">' ObjectDN "<" *

Stage 7: summarize

| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by Computer, SubjectAccount, SubjectUserName, SubjectDomainName, SubjectUserSid, SubjectLogonId, ObjectDN, AttributeLDAPDisplayName

Stage 8: extend

| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))

Stage 9: extend

| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
HostNameDomain =
ifDomainIndex != -1substring(Computer, (DomainIndex + 1))
elseComputer

Stage 10: project-away

| project-away DomainIndex

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
AttributeLDAPDisplayNameeq
  • msDS-AllowedToActOnBehalfOfOtherIdentity corpus 3 (sigma 2, kusto 1)
field:"AttributeLDAPDisplayName" kind:eq value:"msDS-AllowedToActOnBehalfOfOtherIdentity"
EventIDeq
  • 5136 corpus 45 (splunk 24, kusto 18, elastic 3)
field:"EventID" kind:eq value:"5136"
ObjectClasseq
  • computer corpus 2 (sigma 1, kusto 1)
field:"ObjectClass" kind:eq value:"computer"

Output fields

These fields are emitted when the rule matches.

FieldSource
AttributeLDAPDisplayNamesummarize
Computersummarize
EndTimesummarize
ObjectDNsummarize
StartTimesummarize
SubjectAccountsummarize
SubjectDomainNamesummarize
SubjectLogonIdsummarize
SubjectUserNamesummarize
SubjectUserSidsummarize
HostNameextend
HostNameDomainextend