Detection rules › Kusto

TI map IP entity to DNS Events (ASIM DNS schema)

Severity
medium
Time window
14d
Group by
IndicatorId, IoC
Source
github.com/Azure/Azure-Sentinel

This rule identifies DNS requests for which response IP address is a known IoC. This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM DNS schema.

MITRE ATT&CK coverage

TacticTechniques
Command & Control

Telemetry coverage

ProviderRecord / event type
SysmonEvent ID 22: DNSEvent (DNS query)

Rule body

id: 67775878-7f8b-4380-ac54-115e1e828901
name: TI map IP entity to DNS Events (ASIM DNS schema)
description: |
  'This rule identifies DNS requests for which response IP address is a known IoC. This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema.'
severity: Medium
requiredDataConnectors:
  - connectorId: ThreatIntelligence
    dataTypes:
      - ThreatIntelligenceIndicator
  - connectorId: ThreatIntelligenceTaxii
    dataTypes:
      - ThreatIntelligenceIndicator
  - connectorId: DNS
    dataTypes:
      - DnsEvents
  - connectorId: AzureFirewall
    dataTypes: 
      - AzureDiagnostics
  - connectorId: Zscaler
    dataTypes:
      - CommonSecurityLog
  - connectorId: InfobloxNIOS
    dataTypes: 
      - Syslog
  - connectorId: GCPDNSDataConnector
    dataTypes: 
      - GCP_DNS_CL
  - connectorId: NXLogDnsLogs
    dataTypes: 
      - NXLog_DNS_Server_CL
  - connectorId: CiscoUmbrellaDataConnector
    dataTypes: 
      - Cisco_Umbrella_dns_CL
  - connectorId: MicrosoftDefenderThreatIntelligence
    dataTypes:
      - ThreatIntelligenceIndicator
  - connectorId: Corelight
    dataTypes: 
      - Corelight_CL
queryFrequency: 1h
queryPeriod: 14d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - CommandAndControl
relevantTechniques:
  - T1071
tags:
  - ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/ThreatIntelligenceIndicator/IPEntity_DnsEvents.yaml
    version: 1.0.0
  - Schema: ASIMDns
    SchemaVersion: 0.1.1
query: |
  let dt_lookBack = 1h;
  let ioc_lookBack = 14d;
  let IP_TI = 
  ThreatIntelligenceIndicator
  | where TimeGenerated >= ago(ioc_lookBack)
  | extend IoC = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,"NO_IP")
  | where IoC != "NO_IP"
  | summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId
  | where Active == true and ExpirationDateTime > now();
  IP_TI
  | join kind=innerunique // using innerunique to keep perf fast and result set low, we only need one match to indicate potential malicious activity that needs to be investigated
  (
  _Im_Dns(starttime=ago(dt_lookBack))
  | where isnotempty(DnsResponseName)
  | summarize imDns_mintime=min(TimeGenerated), imDns_maxtime=max(TimeGenerated) by SrcIpAddr, DnsQuery, DnsResponseName, Dvc, EventProduct, EventVendor
  | extend addresses = extract_all (@'(\d+\.\d+\.\d+\.\d+)', DnsResponseName)
  | mv-expand IoC = addresses to typeof(string)
  )
  on IoC
  | where imDns_mintime < ExpirationDateTime
  | project imDns_mintime, imDns_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, LatestIndicatorTime, ExpirationDateTime, ConfidenceScore, SrcIpAddr, IoC, Dvc, EventVendor, EventProduct, DnsQuery, DnsResponseName
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: FullName
        columnName: Dvc
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IoC
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SrcIpAddr
customDetails:
  LatestIndicatorTime: LatestIndicatorTime
  Description: Description
  ActivityGroupNames: ActivityGroupNames
  IndicatorId: IndicatorId
  ThreatType: ThreatType
  ExpirationDateTime: ExpirationDateTime
  ConfidenceScore: ConfidenceScore
  DNSRequestTime: imDns_mintime
  SourceIPAddress: SrcIpAddr
  DnsQuery: DnsQuery
alertDetailsOverride:
  alertDisplayNameFormat: The response {{IoC}} to DNS query matched an IoC 
  alertDescriptionFormat: The response address {{IoC}} to a DNS query matched a known indicator of compromise of {{ThreatType}}. Consult the threat intelligence blade for more information on the indicator.
version: 1.2.4
kind: Scheduled

Stages and Predicates

Parameters

let dt_lookBack = 1h;
let ioc_lookBack = 14d;

let IP_TI is inlined into the numbered stages below.

Stages 1 to 6 define let IP_TI (the rule's main pipeline source); stages 7 to 9 run on it.

Stage 1: source

ThreatIntelligenceIndicator

Stage 2: where

| where TimeGenerated >= ago(ioc_lookBack)

Stage 3: extend

| extend IoC = coalesce(NetworkIP, NetworkDestinationIP, NetworkSourceIP,EmailSourceIpAddress,"NO_IP")

Stage 4: where

| where IoC != "NO_IP"

Stage 5: summarize

| summarize LatestIndicatorTime = arg_max(TimeGenerated, *) by IndicatorId

Stage 6: where

| where Active == true and ExpirationDateTime > now()

Stage 7: join

IP_TI
| join kind=innerunique
(
_Im_Dns(starttime=ago(dt_lookBack))
| where isnotempty(DnsResponseName)
| summarize imDns_mintime=min(TimeGenerated), imDns_maxtime=max(TimeGenerated) by SrcIpAddr, DnsQuery, DnsResponseName, Dvc, EventProduct, EventVendor
| extend addresses = extract_all (@'(\d+\.\d+\.\d+\.\d+)', DnsResponseName)
| mv-expand IoC = addresses to typeof(string)
)
on IoC

Stage 8: where

| where imDns_mintime < ExpirationDateTime

Stage 9: project

| project imDns_mintime, imDns_maxtime, Description, ActivityGroupNames, IndicatorId, ThreatType, LatestIndicatorTime, ExpirationDateTime, ConfidenceScore, SrcIpAddr, IoC, Dvc, EventVendor, EventProduct, DnsQuery, DnsResponseName

Indicators

These rows show field, operator, and value matches.

Output fields

These fields are emitted when the rule matches.

FieldSource
ActivityGroupNamesproject
ConfidenceScoreproject
Descriptionproject
DnsQueryproject
DnsResponseNameproject
Dvcproject
EventProductproject
EventVendorproject
ExpirationDateTimeproject
IndicatorIdproject
IoCproject
LatestIndicatorTimeproject
SrcIpAddrproject
ThreatTypeproject
imDns_maxtimeproject
imDns_mintimeproject