Detection rules › Kusto

UniFi Site Manager: System log shipping disabled

Status
available
Severity
high
Time window
45m
Group by
Id, id_s
Source
github.com/Azure/Azure-Sentinel

Identifies when a UniFi host transitions cloudSystemLogState from enabled to disabled. This defense-evasion signal may indicate an attacker silencing audit trails.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment

Rule body

id: f32950bc-6553-4c03-2686-a9c29ef318e8
name: "UniFi Site Manager: System log shipping disabled"
description: |
  Identifies when a UniFi host transitions cloudSystemLogState from enabled to disabled. This defense-evasion signal may indicate an attacker silencing audit trails.
severity: High
status: Available
requiredDataConnectors:
  - connectorId: UniFiSiteManagerConnectorDefinition
    dataTypes:
      - Unifi_SiteManager_Hosts_CL
queryFrequency: 15m
queryPeriod: 45m
triggerOperator: gt
triggerThreshold: 0
tactics:
  - DefenseEvasion
relevantTechniques:
  - T1562
subTechniques:
  - T1562.006
  - T1562.008
query: |
  let prev = Unifi_SiteManager_Hosts_CL
            | where TimeGenerated between (ago(30m) .. ago(15m))
            | summarize arg_max(TimeGenerated, *) by Id
            | project id_s = Id, prevState = tostring(ReportedState.cloudSystemLogState);
        Unifi_SiteManager_Hosts_CL
        | where TimeGenerated > ago(15m)
        | summarize arg_max(TimeGenerated, *) by Id
        | extend id_s = Id,
                 SiteName = tostring(ReportedState.name),
                 currentState = tostring(ReportedState.cloudSystemLogState)
        | join kind=inner prev on id_s
        | where currentState == 'disabled' and prevState == 'enabled'
        | extend Activity = strcat('Cloud system log shipping was disabled on host ', SiteName, ' (', prevState, ' -> ', currentState, ')')
        | project TimeGenerated, Id, SiteName, Activity, prevState, currentState
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: Id
      - identifier: DnsDomain
        columnName: SiteName
incidentConfiguration:
  createIncident: true
  groupingConfiguration:
    enabled: true
    reopenClosedIncident: false
    lookbackDuration: PT12H
    matchingMethod: AllEntities
kind: Scheduled
version: 1.0.1

Stages and Predicates

Let binding: prev used in Stage 5

let prev = Unifi_SiteManager_Hosts_CL
          | where TimeGenerated between (ago(30m) .. ago(15m))
          | summarize arg_max(TimeGenerated, *) by Id
          | project id_s = Id, prevState = tostring(ReportedState.cloudSystemLogState);

Stage 1: source

Unifi_SiteManager_Hosts_CL

Stage 2: where

| where TimeGenerated > ago(15m)

Stage 3: summarize

| summarize arg_max(TimeGenerated, *) by Id

Stage 4: extend

| extend id_s = Id,
               SiteName = tostring(ReportedState.name),
               currentState = tostring(ReportedState.cloudSystemLogState)

Stage 5: join

| join kind=inner prev on id_s

Stage 6: where

| where currentState == 'disabled' and prevState == 'enabled'

Stage 7: extend

| extend Activity = strcat('Cloud system log shipping was disabled on host ', SiteName, ' (', prevState, ' -> ', currentState, ')')

Stage 8: project

| project TimeGenerated, Id, SiteName, Activity, prevState, currentState

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
Activityproject
Idproject
SiteNameproject
TimeGeneratedproject
currentStateproject
prevStateproject