Detection rules › Kusto

M2131_LogRetentionLessThan1Year

Status
available
Severity
medium
Time window
14d
Group by
AssessedResourceId, RecommendationDisplayName
Source
github.com/Azure/Azure-Sentinel

'This alert is designed to monitor log retention within the Maturity Model for Event Log Management (M-21-31) standard. The alert triggers when a log analytics workspace in active storage is configured for less than 1 year.'

MITRE ATT&CK coverage

TacticTechniques
Discovery

Rule body

id: 8178a514-1270-4e31-a1d9-aaafeb40122f
name: M2131_LogRetentionLessThan1Year
description: |
  'This alert is designed to monitor log retention within the Maturity Model for Event Log Management (M-21-31) standard. The alert triggers when a log analytics workspace in active storage is configured for less than 1 year.'
severity: Medium
status: Available
requiredDataConnectors: []
queryFrequency: 1d
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Discovery
relevantTechniques:
  - T1082
query: |
  SecurityRecommendation
  | summarize arg_max(TimeGenerated, *) by RecommendationDisplayName, AssessedResourceId
  | where RecommendationDisplayName == "Activity log should be retained for at least one year"
  | summarize Failed = countif(RecommendationState == "Unhealthy"), Passed = countif(RecommendationState == "Healthy"), Total = countif(RecommendationState == "Healthy" or RecommendationState == "Unhealthy") by RecommendationDisplayName, AssessedResourceId
  | extend PassedControls = (Passed/todouble(Total))*100
  | extend RemediationLink = strcat('https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22')
  | project RecommendationDisplayName, AssessedResourceId, Total, PassedControls, Passed, Failed, RemediationLink, LastObserved=now()
  | where Failed > 0
  | sort by Failed desc
  | extend URLCustomEntity = RemediationLink, ResourceId = AssessedResourceId
entityMappings:
  - entityType: URL
    fieldMappings:
      - identifier: Url
        columnName: URLCustomEntity
  - entityType: AzureResource
    fieldMappings:
      - identifier: ResourceId
        columnName: AssessedResourceId
version: 1.0.0
kind: Scheduled

Stages and Predicates

Stage 1: source

SecurityRecommendation

Stage 2: summarize

| summarize arg_max(TimeGenerated, *) by RecommendationDisplayName, AssessedResourceId

Stage 3: where

| where RecommendationDisplayName == "Activity log should be retained for at least one year"

Stage 4: summarize

| summarize Failed = countif(RecommendationState == "Unhealthy"), Passed = countif(RecommendationState == "Healthy"), Total = countif(RecommendationState == "Healthy" or RecommendationState == "Unhealthy") by RecommendationDisplayName, AssessedResourceId

Stage 5: extend

| extend PassedControls = (Passed/todouble(Total))*100

Stage 6: extend

| extend RemediationLink = strcat('https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/22')

Stage 7: project

| project RecommendationDisplayName, AssessedResourceId, Total, PassedControls, Passed, Failed, RemediationLink, LastObserved=now()

Stage 8: where

| where Failed > 0

Stage 9: sort

| sort by Failed desc

Stage 10: extend

| extend URLCustomEntity = RemediationLink, ResourceId = AssessedResourceId

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
AssessedResourceIdproject
Failedproject
LastObservedproject
Passedproject
PassedControlsproject
RecommendationDisplayNameproject
RemediationLinkproject
Totalproject
ResourceIdextend
URLCustomEntityextend