Detection rules › Kusto

PROD (TM001.1) - GROUP - Added to Group Outside the Object Tier Level

Status
available
Severity
high
Time window
5m
Source
github.com/Azure/Azure-Sentinel

Added an object to a member of a Tier Model group that is outside of the same Tier. Example a Tier 0 user added to a Tier 1 group.

MITRE ATT&CK coverage

TacticTechniques
Privilege Escalation

Telemetry coverage

Rule body

id: b300c7f8-dc5e-4fc6-879b-63f0013358ce
name: 'PROD (TM001.1) - GROUP - Added to Group Outside the Object Tier Level'
description: |
  Added an object to a member of a Tier Model group that is outside of the same Tier. Example a Tier 0 user added to a Tier 1 group.
severity: High
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes:
      - SecurityEvent
queryFrequency: 5m
queryPeriod: 5m
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
  - PrivilegeEscalation
relevantTechniques:
  - T1078.002
query: |
  SecurityEvent 
  | where EventID == 5136
      and Activity has "modified"
      and (EventData matches regex @"(?i)OU=Tier 0 Accounts" 
           or EventData matches regex @"(?i)OU=Tier 1 Accounts" 
           or EventData matches regex @"(?i)OU=Tier 2 Accounts"
           or EventData matches regex @"(?i)OU=Tier 0 Service Accounts" 
           or EventData matches regex @"(?i)OU=Tier 1 Service Accounts" 
           or EventData matches regex @"(?i)OU=Tier 2 Service Accounts"
           or EventData matches regex @"(?i)OU=Tier 0 Groups"
           or EventData matches regex @"(?i)OU=Tier 1 Groups"
           or EventData matches regex @"(?i)OU=Tier 2 Groups"
           or EventData matches regex @"(?i)OU=Tier 0 PAW"
           or EventData matches regex @"(?i)OU=Tier 1 PAW"
           or EventData matches regex @"(?i)OU=Tier 2 PAW")
      and EventData has '"AttributeLDAPDisplayName">member'
      and EventData has 'OperationType">%%14674'
  | extend GroupName_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)
  | extend GroupName = extract("(?i)CN=([^,]+)", 1, GroupName_e)
  | where GroupName != "Protected Users"
  | where GroupName != "Allowed RODC Password Replication Group"
  | extend GroupTier_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)
  | extend GroupTier = extract("(?i)OU=(Tier [^ ]+)", 1, GroupTier_e)
  | extend GroupTier = iff(isempty(GroupTier), "Outside Tier Model", GroupTier)
  | extend ObjectName_e = extract("<Data Name=\"AttributeValue\">([^<]+)</Data>", 1, EventData)
  | extend ObjectName = extract("(?i)CN=([^,]+)", 1, ObjectName_e)
  | extend ObjectTier_e = extract("<Data Name=\"AttributeValue\">([^<]+)</Data>", 1, EventData)
  | extend ObjectTier = extract("(?i)OU=(Tier [^ ]+)", 1, ObjectTier_e)
  | extend ObjectTier = iff(isempty(ObjectTier), "Outside Tier Model", ObjectTier)
  | extend Domain = extract("([^.]+\\.[^.]+)$", 1, Computer)
  | extend ActivityType = extract("([a-zA-Z]+)\\.$", 1, Activity)
  | extend OperationType = iff(EventData has 'OperationType">%%14674', "Added", tostring(OperationType))
  | where GroupTier != ObjectTier
  | project TimeGenerated 
          , ObjectName
          , ObjectTier
          , ObjectType = AccountType
          , GroupName
          , GroupTier
          , ActivityType
          , OperationType
          , Account
          , Domain
          , Computer
          , Channel
          , EventID
          , EventData
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: ObjectName
  - entityType: SecurityGroup
    fieldMappings:
      - identifier: DistinguishedName
        columnName: GroupName
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: Account
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: Computer
customDetails:
  ObjectName: ObjectName
  ObjectTier: ObjectTier
  ObjectType: ObjectType
  GroupName: GroupName
  GroupTier: GroupTier
  ActivityType: ActivityType
  OperationType: OperationType
  Account: Account
  Domain: Domain
  Channel: Channel
  EventID: EventID
  EventData: EventData
eventGroupingSettings:
  aggregationKind: AlertPerResult
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: false
    reopenClosedIncident: false
    lookbackDuration: PT5M
    matchingMethod: Selected
    groupByEntities:
      - Account
    groupByCustomDetails:
      - ObjectName
alertDetailsOverride:
  alertDisplayNameFormat: '(TM001.1) A {{ObjectTier}} object was added to non-{{ObjectTier}} group {{GroupName}}'
  alertDescriptionFormat: |
    Tier Model Alert TM001 - A {{ObjectTier}} object was added to non-{{ObjectTier}} group {{GroupName}}.

    Resolution - Remove the object from the group
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

SecurityEvent

Stage 2: where

| where EventID == 5136
    and Activity has "modified"
    and (EventData matches regex @"(?i)OU=Tier 0 Accounts" 
         or EventData matches regex @"(?i)OU=Tier 1 Accounts" 
         or EventData matches regex @"(?i)OU=Tier 2 Accounts"
         or EventData matches regex @"(?i)OU=Tier 0 Service Accounts" 
         or EventData matches regex @"(?i)OU=Tier 1 Service Accounts" 
         or EventData matches regex @"(?i)OU=Tier 2 Service Accounts"
         or EventData matches regex @"(?i)OU=Tier 0 Groups"
         or EventData matches regex @"(?i)OU=Tier 1 Groups"
         or EventData matches regex @"(?i)OU=Tier 2 Groups"
         or EventData matches regex @"(?i)OU=Tier 0 PAW"
         or EventData matches regex @"(?i)OU=Tier 1 PAW"
         or EventData matches regex @"(?i)OU=Tier 2 PAW")
    and EventData has '"AttributeLDAPDisplayName">member'
    and EventData has 'OperationType">%%14674'

Stage 3: extend

| extend GroupName_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)

Stage 4: extend

| extend GroupName = extract("(?i)CN=([^,]+)", 1, GroupName_e)

Stage 5: where

| where GroupName != "Protected Users"

Stage 6: where

| where GroupName != "Allowed RODC Password Replication Group"

Stage 7: extend (11 consecutive steps)

| extend GroupTier_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)
| extend GroupTier = extract("(?i)OU=(Tier [^ ]+)", 1, GroupTier_e)
| extend GroupTier = iff(isempty(GroupTier), "Outside Tier Model", GroupTier)
| extend ObjectName_e = extract("<Data Name=\"AttributeValue\">([^<]+)</Data>", 1, EventData)
| extend ObjectName = extract("(?i)CN=([^,]+)", 1, ObjectName_e)
| extend ObjectTier_e = extract("<Data Name=\"AttributeValue\">([^<]+)</Data>", 1, EventData)
| extend ObjectTier = extract("(?i)OU=(Tier [^ ]+)", 1, ObjectTier_e)
| extend ObjectTier = iff(isempty(ObjectTier), "Outside Tier Model", ObjectTier)
| extend Domain = extract("([^.]+\\.[^.]+)$", 1, Computer)
| extend ActivityType = extract("([a-zA-Z]+)\\.$", 1, Activity)
| extend OperationType = iff(EventData has 'OperationType">%%14674', "Added", tostring(OperationType))

Stage 8: where

| where GroupTier != ObjectTier

Stage 9: project

| project TimeGenerated 
        , ObjectName
        , ObjectTier
        , ObjectType = AccountType
        , GroupName
        , GroupTier
        , ActivityType
        , OperationType
        , Account
        , Domain
        , Computer
        , Channel
        , EventID
        , EventData

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
Activitymatch
  • modified transforms: term corpus 10 (kusto 10)
field:"Activity" kind:match value:"modified"
EventDatamatch
  • "AttributeLDAPDisplayName">member transforms: term corpus 3 (kusto 3)
  • OperationType">%%14674 transforms: term corpus 4 (kusto 4)
field:"EventData" kind:match
EventDataregex_match
  • (?i)OU=Tier 0 Accounts corpus 4 (kusto 4)
  • (?i)OU=Tier 0 Groups corpus 3 (kusto 3)
  • (?i)OU=Tier 0 PAW corpus 6 (kusto 6)
  • (?i)OU=Tier 0 Service Accounts corpus 4 (kusto 4)
  • (?i)OU=Tier 1 Accounts corpus 4 (kusto 4)
  • (?i)OU=Tier 1 Groups corpus 3 (kusto 3)
  • (?i)OU=Tier 1 PAW corpus 6 (kusto 6)
  • (?i)OU=Tier 1 Service Accounts corpus 4 (kusto 4)
  • (?i)OU=Tier 2 Accounts corpus 4 (kusto 4)
  • (?i)OU=Tier 2 Groups corpus 3 (kusto 3)
  • (?i)OU=Tier 2 PAW corpus 6 (kusto 6)
  • (?i)OU=Tier 2 Service Accounts corpus 4 (kusto 4)
field:"EventData" kind:regex_match
EventIDeq
  • 5136 corpus 45 (splunk 24, kusto 18, elastic 3)
field:"EventID" kind:eq value:"5136"
GroupNamene
  • Allowed RODC Password Replication Group
  • Protected Users
field:"GroupName" kind:ne
GroupTiercross_field_compare
  • ObjectTier transforms: op:ne
field:"GroupTier" kind:cross_field_compare value:"ObjectTier"

Output fields

These fields are emitted when the rule matches.

FieldSource
Accountproject
ActivityTypeproject
Channelproject
Computerproject
Domainproject
EventDataproject
EventIDproject
GroupNameproject
GroupTierproject
ObjectNameproject
ObjectTierproject
ObjectTypeproject
OperationTypeproject
TimeGeneratedproject