Detection rules › Kusto
PROD (TM011.1) - LAPS - Tier Level Computer Object LAPS Password Expiration Time Set Manually
Alert if a Tier Model computer object LAPS password was manually expired.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Discovery |
Telemetry coverage
| Provider | Record / event type |
|---|---|
| Security-Auditing | Event ID 5136: A directory service object was modified. |
Rule body
id: daf2b9f7-dcf2-4b45-831a-d7142318c7e9
name: 'PROD (TM011.1) - LAPS - Tier Level Computer Object LAPS Password Expiration Time Set Manually'
description: |
Alert if a Tier Model computer object LAPS password was manually expired.
severity: Low
requiredDataConnectors:
- connectorId: SecurityEvents
dataTypes:
- SecurityEvent
- connectorId: WindowsSecurityEvents
dataTypes:
- SecurityEvent
queryFrequency: 5h
queryPeriod: 5h
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
- Discovery
relevantTechniques:
- T1087.001
query: |
SecurityEvent
| where EventID == 5136
and (EventData matches regex @"(?i)OU=Domain Controllers"
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"
or EventData matches regex @"(?i)OU=Tier 0 Member Servers"
or EventData matches regex @"(?i)OU=Tier 1 Member Servers")
and AccountType == "User"
| extend AttributeLDAP = extract("<Data Name=\"AttributeLDAPDisplayName\">([^<]+)</Data>", 1, EventData)
| where AttributeLDAP has "msLAPS-PasswordExpirationTime"
| extend ObjectName_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)
| extend ObjectName = extract("(?i)CN=([^,]+)", 1, ObjectName_e)
| extend ObjectTier = case(
ObjectName_e has "Tier 0", "Tier 0",
ObjectName_e has "Tier 1", "Tier 1",
ObjectName_e has "Tier Model Administration", "Tier 0",
ObjectName_e has "Tier Model Computer Quarantine", "Tier 0",
ObjectName_e has "Domain Controllers", "Tier 0",
"Unknown")
| extend ActivityType = extract("([a-zA-Z]+)\\.$", 1, Activity)
| extend Domain = extract("([^.]+\\.[^.]+)$", 1, Computer)
| extend OperationType = iff(EventData has 'OperationType">%%14674', "Added", tostring(OperationType))
| project TimeGenerated
, ObjectName
, ObjectTier
, AttributeLDAP
, ActivityType
, Account
, Domain
, Computer
, Channel
, EventID
, EventData
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ObjectName
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: Computer
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: Account
customDetails:
ObjectName: ObjectName
ObjectTier: ObjectTier
AttributeLDAP: AttributeLDAP
ActivityType: ActivityType
Account: Account
Domain: Domain
Computer: Computer
Channel: Channel
EventID: EventID
EventData: EventData
eventGroupingSettings:
aggregationKind: AlertPerResult
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: false
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AllEntities
alertDetailsOverride:
alertDisplayNameFormat: '(TM011.1) A {{ObjectTier}} LAPS password was expired by {{Account}} manually.'
alertDescriptionFormat: 'The LAPS password for {{ObjectName}} was expired manually.'
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
SecurityEvent
Stage 2: where
| where EventID == 5136
and (EventData matches regex @"(?i)OU=Domain Controllers"
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"
or EventData matches regex @"(?i)OU=Tier 0 Member Servers"
or EventData matches regex @"(?i)OU=Tier 1 Member Servers")
and AccountType == "User"
Stage 3: extend
| extend AttributeLDAP = extract("<Data Name=\"AttributeLDAPDisplayName\">([^<]+)</Data>", 1, EventData)
Stage 4: where
| where AttributeLDAP has "msLAPS-PasswordExpirationTime"
Stage 5: extend (6 consecutive steps)
| extend ObjectName_e = extract("<Data Name=\"ObjectDN\">([^<]+)</Data>", 1, EventData)
| extend ObjectName = extract("(?i)CN=([^,]+)", 1, ObjectName_e)
| extend ObjectTier = case(
ObjectName_e has "Tier 0", "Tier 0",
ObjectName_e has "Tier 1", "Tier 1",
ObjectName_e has "Tier Model Administration", "Tier 0",
ObjectName_e has "Tier Model Computer Quarantine", "Tier 0",
ObjectName_e has "Domain Controllers", "Tier 0",
"Unknown")
| extend ActivityType = extract("([a-zA-Z]+)\\.$", 1, Activity)
| extend Domain = extract("([^.]+\\.[^.]+)$", 1, Computer)
| extend OperationType = iff(EventData has 'OperationType">%%14674', "Added", tostring(OperationType))
Stage 6: project
| project TimeGenerated
, ObjectName
, ObjectTier
, AttributeLDAP
, ActivityType
, Account
, Domain
, Computer
, Channel
, EventID
, EventData
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
AccountType | eq |
| field:"AccountType" kind:eq value:"User" |
AttributeLDAP | match |
| field:"AttributeLDAP" kind:match value:"msLAPS-PasswordExpirationTime" |
EventData | regex_match |
| field:"EventData" kind:regex_match |
EventID | eq |
| field:"EventID" kind:eq value:"5136" |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
Account | project |
ActivityType | project |
AttributeLDAP | project |
Channel | project |
Computer | project |
Domain | project |
EventData | project |
EventID | project |
ObjectName | project |
ObjectTier | project |
TimeGenerated | project |