Detection rules › Kusto
M2131_EventLogManagementPostureChanged_EL0
'This alert is desinged to monitor Azure policies aligned with the Maturity Model for Event Log Management (M-21-31) standard. The alert triggers when EL0 policy compliance falls below 70% within a 1 week timeframe.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Discovery | T1082 System Information Discovery |
Rule body kusto
id: 1f8fcca5-47ed-409d-a8fa-d49ef821feaf
name: M2131_EventLogManagementPostureChanged_EL0
description: |
'This alert is desinged to monitor Azure policies aligned with the Maturity Model for Event Log Management (M-21-31) standard. The alert triggers when EL0 policy compliance falls below 70% within a 1 week timeframe.'
severity: Medium
status: Available
requiredDataConnectors: []
queryFrequency: 7d
queryPeriod: 7d
triggerOperator: gt
triggerThreshold: 0
tactics:
- Discovery
relevantTechniques:
- T1082
query: |
SecurityRecommendation
| where RecommendationDisplayName <> ""
| extend MaturityLevel=iff(RecommendationDisplayName has_any("agent","extension","retention","logs encryption","collect","retained","log profile","CloudTrail","metric","AWS","GCP","DNS","Auditing","Flow","logging","usage"), "Event Logging (EL0)",
iff(RecommendationDisplayName has_any("container registries","logic apps","Enhanced monitoring","IoT Hub","Event Hub","App Service", "Kubernetes","updates","email", "automation", "adaptive"), "Advanced Event Logging (EL3)",
iff(RecommendationDisplayName has_any("signatures","CMK","CMEK","double encryption","managed key","KMS","container","Watcher"), "Intermediate Event Logging (EL2)",
iff(RecommendationDisplayName has_any("Exploit Guard","endpoint protection","Antimalware","health","VPC","Defender","Vulnerabilities","vulnerability","diagnostic","Key","activity log alert",""), "Basic Event Logging (EL1)","Other"))))
| summarize arg_max(TimeGenerated, *) by RecommendationDisplayName, AssessedResourceId, MaturityLevel
| summarize Failed = countif(RecommendationState == "Unhealthy"), Passed = countif(RecommendationState == "Healthy"), Total = countif(RecommendationState == "Healthy" or RecommendationState == "Unhealthy") by MaturityLevel
| extend PassedControls = (Passed/todouble(Total))*100
| extend RemediationLink = strcat('https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22')
| project MaturityLevel, Total, PassedControls, Passed, Failed, RemediationLink, LastObserved=now()
| where MaturityLevel <> ''
| where MaturityLevel == "Event Logging (EL0)"
| where PassedControls < 70
//Adjust Either FailedRatePercentage or PasedRatePercentage Thresholds within Organizational Needs
| sort by PassedControls desc
| extend URLCustomEntity = RemediationLink
entityMappings:
- entityType: URL
fieldMappings:
- identifier: Url
columnName: URLCustomEntity
version: 1.0.0
kind: Scheduled
Stages and Predicates
Stage 1: source
SecurityRecommendation
Stage 2: where
| where RecommendationDisplayName <> ""
Stage 3: extend
| extend MaturityLevel=iff(RecommendationDisplayName has_any("agent","extension","retention","logs encryption","collect","retained","log profile","CloudTrail","metric","AWS","GCP","DNS","Auditing","Flow","logging","usage"), "Event Logging (EL0)",
iff(RecommendationDisplayName has_any("container registries","logic apps","Enhanced monitoring","IoT Hub","Event Hub","App Service", "Kubernetes","updates","email", "automation", "adaptive"), "Advanced Event Logging (EL3)",
iff(RecommendationDisplayName has_any("signatures","CMK","CMEK","double encryption","managed key","KMS","container","Watcher"), "Intermediate Event Logging (EL2)",
iff(RecommendationDisplayName has_any("Exploit Guard","endpoint protection","Antimalware","health","VPC","Defender","Vulnerabilities","vulnerability","diagnostic","Key","activity log alert",""), "Basic Event Logging (EL1)","Other"))))
MaturityLevel =(RecommendationDisplayName contains "agent" or RecommendationDisplayName contains "extension" or RecommendationDisplayName contains "retention" or RecommendationDisplayName contains "logs encryption" or RecommendationDisplayName contains "collect" or RecommendationDisplayName contains "retained" or RecommendationDisplayName contains "log profile" or RecommendationDisplayName contains "CloudTrail" or RecommendationDisplayName contains "metric" or RecommendationDisplayName contains "AWS" or RecommendationDisplayName contains "GCP" or RecommendationDisplayName contains "DNS" or RecommendationDisplayName contains "Auditing" or RecommendationDisplayName contains "Flow" or RecommendationDisplayName contains "logging" or RecommendationDisplayName contains "usage")"Event Logging (EL0)"iff((RecommendationDisplayName has_any ("container registries", "logic apps", "Enhanced monitoring", "IoT Hub", "Event Hub", "App Service", "Kubernetes", "updates", "email", "automation", "adaptive")), "Advanced Event Logging (EL3)", iff((RecommendationDisplayName has_any ("signatures", "CMK", "CMEK", "double encryption", "managed key", "KMS", "container", "Watcher")), "Intermediate Event Logging (EL2)", iff((RecommendationDisplayName has_any ("Exploit Guard", "endpoint protection", "Antimalware", "health", "VPC", "Defender", "Vulnerabilities", "vulnerability", "diagnostic", "Key", "activity log alert", "")), "Basic Event Logging (EL1)", "Other")))Stage 4: summarize
| summarize arg_max(TimeGenerated, *) by RecommendationDisplayName, AssessedResourceId, MaturityLevel
Stage 5: summarize
| summarize Failed = countif(RecommendationState == "Unhealthy"), Passed = countif(RecommendationState == "Healthy"), Total = countif(RecommendationState == "Healthy" or RecommendationState == "Unhealthy") by MaturityLevel
Stage 6: extend
| extend PassedControls = (Passed/todouble(Total))*100
Stage 7: extend
| extend RemediationLink = strcat('https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22')
Stage 8: project
| project MaturityLevel, Total, PassedControls, Passed, Failed, RemediationLink, LastObserved=now()
Stage 9: where
| where MaturityLevel <> ''
Stage 10: where
| where MaturityLevel == "Event Logging (EL0)"
Stage 11: where
| where PassedControls < 70
Stage 12: sort
| sort by PassedControls desc
Stage 13: extend
| extend URLCustomEntity = RemediationLink
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.
| Field | Kind | Values |
|---|---|---|
MaturityLevel | eq |
|
PassedControls | lt |
|
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.
| Field | Source |
|---|---|
Failed | project |
LastObserved | project |
MaturityLevel | project |
Passed | project |
PassedControls | project |
RemediationLink | project |
Total | project |
URLCustomEntity | extend |