Detection rules › Kusto

CiscoISE - Device changed IP in last 24 hours

Status
available
Severity
medium
Time window
1h
Group by
DvcHostname
Source
github.com/Azure/Azure-Sentinel

'Detects when device changes IP address in last 24 hours.'

MITRE ATT&CK coverage

TacticTechniques
Command & ControlT1568 Dynamic Resolution

Rule body kusto

id: 0c509e9b-121e-4951-9f9b-43722e052b4f
name: CiscoISE - Device changed IP in last 24 hours
description: |
  'Detects when device changes IP address in last 24 hours.'
severity: Medium
status: Available
requiredDataConnectors:
  - connectorId: SyslogAma
    datatypes:
      - Syslog
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CommandAndControl
relevantTechniques:
  - T1568
query: |
  let lbtime_48h = 48h;
  let lbtime_24h = 24h;
  CiscoISEEvent
  | where TimeGenerated between (ago(lbtime_48h) .. ago(lbtime_24h))
  | where notempty(DvcIpAddr) and notempty(DvcHostname)
  | summarize knownIPs = make_set(DvcIpAddr) by DvcHostname
  | join (CiscoISEEvent
        | where TimeGenerated > ago(lbtime_24h)
        | where notempty(DvcIpAddr) and notempty(DvcHostname)
        | summarize evts = count() by DvcHostname, DvcIpAddr
        | project-away evts) on DvcHostname
  | project-away DvcHostname1
  | where knownIPs !contains DvcIpAddr
  | extend HostCustomEntity = DvcHostname
  | extend IPCustomEntity = DvcIpAddr
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: HostCustomEntity
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPCustomEntity
version: 1.0.3
kind: Scheduled

Stages and Predicates

Parameters

let lbtime_48h = 48h;
let lbtime_24h = 24h;

Stage 1: source

CiscoISEEvent

Stage 2: where

| where TimeGenerated between (ago(lbtime_48h) .. ago(lbtime_24h))

Stage 3: where

| where notempty(DvcIpAddr) and notempty(DvcHostname)

Stage 4: summarize

| summarize knownIPs = make_set(DvcIpAddr) by DvcHostname

Stage 5: join

| join (CiscoISEEvent
      | where TimeGenerated > ago(lbtime_24h)
      | where notempty(DvcIpAddr) and notempty(DvcHostname)
      | summarize evts = count() by DvcHostname, DvcIpAddr
      | project-away evts) on DvcHostname

Stage 6: project-away

| project-away DvcHostname1

Stage 7: where

| where knownIPs !contains DvcIpAddr

Stage 8: extend

| extend HostCustomEntity = DvcHostname

Stage 9: extend

| extend IPCustomEntity = DvcIpAddr

Exclusions

Top-level NOT(...) conjuncts: predicates this rule actively suppresses.

FieldKindExcluded values
knownIPscontainsDvcIpAddr

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.

FieldKindValues
DvcHostnameis_not_null
  • (no value, null check)
DvcIpAddris_not_null
  • (no value, null check)

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.

FieldSource
DvcHostnamesummarize
knownIPssummarize
HostCustomEntityextend
IPCustomEntityextend