Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Potential DGA detected (ASIM DNS Schema)

Back
Id983a6922-894d-413c-9f04-d7add0ecc307
RulenamePotential DGA detected (ASIM DNS Schema)
DescriptionIdentifies clients with a high NXDomain count which could be indicative of a DGA (cycling through possible C2 domains

where most C2s are not live). Alert is generated when a new IP address is seen (based on not being seen associated with

NXDomain records in prior 10-day baseline period).

This analytic rule uses ASIM and supports any built-in or custom source that supports the ASIM DNS schema
SeverityMedium
TacticsCommandAndControl
TechniquesT1568
T1008
Required data connectorsAzureFirewall
CiscoUmbrellaDataConnector
Corelight
DNS
GCPDNSDataConnector
InfobloxNIOS
NXLogDnsLogs
Zscaler
KindScheduled
Query frequency1d
Query period10d
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Detections/ASimDNS/imDns_HighNXDomainCount_detection.yaml
Version1.3.2
Arm template983a6922-894d-413c-9f04-d7add0ecc307.json
Deploy To Azure
let referencestarttime = 10d;
let referenceendtime = 1d;
let threshold = 100;
let nxDomainDnsEvents = (stime:datetime, etime:datetime) 
  {_Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)
  | where DnsQueryTypeName in ("A", "AAAA")
  | where ipv4_is_match("127.0.0.1", SrcIpAddr) == False
  | where DnsQuery !contains "/" and  DnsQuery contains "."};
nxDomainDnsEvents (stime=ago(referenceendtime) ,etime=now())
  | extend sld = tostring(split(DnsQuery, ".")[-2])
  | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), dcount(sld) by SrcIpAddr
  | where dcount_sld > threshold
  // Filter out previously seen IPs
  | join kind=leftanti (nxDomainDnsEvents (stime=ago(referencestarttime), etime=ago(referenceendtime))
    | extend sld = tostring(split(DnsQuery, ".")[-2])
    | summarize dcount(sld) by SrcIpAddr
    | where dcount_sld > threshold ) on SrcIpAddr
// Pull out sample NXDomain responses for those remaining potentially infected IPs
| join kind = inner (nxDomainDnsEvents (stime=ago(referencestarttime), etime=now()) | summarize by DnsQuery, SrcIpAddr) on SrcIpAddr
| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), sampleNXDomainList=make_list(DnsQuery, 100)  by SrcIpAddr, dcount_sld
| extend timestamp = StartTimeUtc, IPCustomEntity = SrcIpAddr
tactics:
- CommandAndControl
severity: Medium
requiredDataConnectors:
- 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: Corelight
  dataTypes:
  - Corelight_CL
triggerOperator: gt
query: |
  let referencestarttime = 10d;
  let referenceendtime = 1d;
  let threshold = 100;
  let nxDomainDnsEvents = (stime:datetime, etime:datetime) 
    {_Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)
    | where DnsQueryTypeName in ("A", "AAAA")
    | where ipv4_is_match("127.0.0.1", SrcIpAddr) == False
    | where DnsQuery !contains "/" and  DnsQuery contains "."};
  nxDomainDnsEvents (stime=ago(referenceendtime) ,etime=now())
    | extend sld = tostring(split(DnsQuery, ".")[-2])
    | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), dcount(sld) by SrcIpAddr
    | where dcount_sld > threshold
    // Filter out previously seen IPs
    | join kind=leftanti (nxDomainDnsEvents (stime=ago(referencestarttime), etime=ago(referenceendtime))
      | extend sld = tostring(split(DnsQuery, ".")[-2])
      | summarize dcount(sld) by SrcIpAddr
      | where dcount_sld > threshold ) on SrcIpAddr
  // Pull out sample NXDomain responses for those remaining potentially infected IPs
  | join kind = inner (nxDomainDnsEvents (stime=ago(referencestarttime), etime=now()) | summarize by DnsQuery, SrcIpAddr) on SrcIpAddr
  | summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), sampleNXDomainList=make_list(DnsQuery, 100)  by SrcIpAddr, dcount_sld
  | extend timestamp = StartTimeUtc, IPCustomEntity = SrcIpAddr  
triggerThreshold: 0
name: Potential DGA detected (ASIM DNS Schema)
kind: Scheduled
version: 1.3.2
description: |
  'Identifies clients with a high NXDomain count which could be indicative of a DGA (cycling through possible C2 domains
  where most C2s are not live). Alert is generated when a new IP address is seen (based on not being seen associated with 
  NXDomain records in prior 10-day baseline period).
  This analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema'  
relevantTechniques:
- T1568
- T1008
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/ASimDNS/imDns_HighNXDomainCount_detection.yaml
tags:
- version: 1.0.0
  ParentAlert: https://github.com/Azure/Azure-Sentinel/blob/master/Detections/DnsEvents/DNS_HighNXDomainCount_detection.yaml
- Schema: ASIMDns
  SchemaVersion: 0.1.1
entityMappings:
- entityType: IP
  fieldMappings:
  - identifier: Address
    columnName: IPCustomEntity
queryFrequency: 1d
queryPeriod: 10d
metadata:
  support:
    tier: Community
  categories:
    domains:
    - Security - Network
  source:
    kind: Community
  author:
    name: Yaron
id: 983a6922-894d-413c-9f04-d7add0ecc307
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/983a6922-894d-413c-9f04-d7add0ecc307')]",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/983a6922-894d-413c-9f04-d7add0ecc307')]",
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules",
      "kind": "Scheduled",
      "apiVersion": "2022-11-01",
      "properties": {
        "displayName": "Potential DGA detected (ASIM DNS Schema)",
        "description": "'Identifies clients with a high NXDomain count which could be indicative of a DGA (cycling through possible C2 domains\nwhere most C2s are not live). Alert is generated when a new IP address is seen (based on not being seen associated with \nNXDomain records in prior 10-day baseline period).\nThis analytic rule uses [ASIM](https://aka.ms/AboutASIM) and supports any built-in or custom source that supports the ASIM DNS schema'\n",
        "severity": "Medium",
        "enabled": true,
        "query": "let referencestarttime = 10d;\nlet referenceendtime = 1d;\nlet threshold = 100;\nlet nxDomainDnsEvents = (stime:datetime, etime:datetime) \n  {_Im_Dns(responsecodename='NXDOMAIN', starttime=stime, endtime=etime)\n  | where DnsQueryTypeName in (\"A\", \"AAAA\")\n  | where ipv4_is_match(\"127.0.0.1\", SrcIpAddr) == False\n  | where DnsQuery !contains \"/\" and  DnsQuery contains \".\"};\nnxDomainDnsEvents (stime=ago(referenceendtime) ,etime=now())\n  | extend sld = tostring(split(DnsQuery, \".\")[-2])\n  | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), dcount(sld) by SrcIpAddr\n  | where dcount_sld > threshold\n  // Filter out previously seen IPs\n  | join kind=leftanti (nxDomainDnsEvents (stime=ago(referencestarttime), etime=ago(referenceendtime))\n    | extend sld = tostring(split(DnsQuery, \".\")[-2])\n    | summarize dcount(sld) by SrcIpAddr\n    | where dcount_sld > threshold ) on SrcIpAddr\n// Pull out sample NXDomain responses for those remaining potentially infected IPs\n| join kind = inner (nxDomainDnsEvents (stime=ago(referencestarttime), etime=now()) | summarize by DnsQuery, SrcIpAddr) on SrcIpAddr\n| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), sampleNXDomainList=make_list(DnsQuery, 100)  by SrcIpAddr, dcount_sld\n| extend timestamp = StartTimeUtc, IPCustomEntity = SrcIpAddr\n",
        "queryFrequency": "P1D",
        "queryPeriod": "P10D",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0,
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "CommandAndControl"
        ],
        "techniques": [
          "T1568",
          "T1008"
        ],
        "alertRuleTemplateName": "983a6922-894d-413c-9f04-d7add0ecc307",
        "customDetails": null,
        "entityMappings": [
          {
            "fieldMappings": [
              {
                "columnName": "IPCustomEntity",
                "identifier": "Address"
              }
            ],
            "entityType": "IP"
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/ASimDNS/imDns_HighNXDomainCount_detection.yaml",
        "templateVersion": "1.3.2",
        "tags": [
          {
            "version": "1.0.0",
            "ParentAlert": "https://github.com/Azure/Azure-Sentinel/blob/master/Detections/DnsEvents/DNS_HighNXDomainCount_detection.yaml"
          },
          {
            "Schema": "ASIMDns",
            "SchemaVersion": "0.1.1"
          }
        ]
      }
    }
  ]
}