Query Details

12 DNS NXDOMAIN DGA Flood

Query

id: a1b2c3d4-0012-4a5b-8c9d-dns012nxdomain
name: DGA Confirmed — NXDOMAIN Flood with High-Entropy Domain Pattern
description: |
  HIGH CONFIDENCE DGA detection that combines two signals into one rule:
    1. NXDOMAIN volume: >200 NXDOMAIN responses in 1 hour with >40% failure rate
    2. Domain entropy: the failed domains exhibit DGA-typical consonant ratio
       (>65%) and embedded digits — characteristic of pseudo-random generation
  A client must satisfy BOTH conditions to trigger. This eliminates the high
  false-positive rate of checking either signal alone.
  Deduplication vs Sentinel built-ins:
  - "Excessive NXDOMAIN DNS Queries (Normalized DNS)" fires on volume alone
  - "Potential DGA via Repetitive Failures (Normalized DNS)" fires on failure
    rate alone, without character-level domain analysis
  This rule requires BOTH — providing higher confidence with fewer false positives.
  Malware families: Emotet, QakBot, Dridex, TrickBot, SolarWinds Sunburst,
  Nymaim, Banjori, Murofet. Disable the two built-ins above when using this rule
  to avoid duplicate alerts on confirmed DGA events.
severity: High
requiredDataConnectors:
  - connectorId: WindowsDnsAma
    dataTypes:
      - ASimDnsActivityLogs
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
  - CommandAndControl
relevantTechniques:
  - T1568.002
tags:
  - DGA
  - NXDOMAIN
  - Emotet
  - QakBot
  - TrickBot
  - Dridex
  - DNS flood
query: |
  // Signal 1: High NXDOMAIN volume with high failure rate
  let NxdomainClients =
      ASimDnsActivityLogs
      | where TimeGenerated > ago(1h)
      | summarize
          TotalQueries  = count(),
          NxdomainCount = countif(DnsResponseCodeName =~ "NXDOMAIN" or DnsResponseCode == 3),
          UniqueDomains = dcount(DnsQuery),
          FirstSeen     = min(TimeGenerated),
          LastSeen      = max(TimeGenerated)
        by SrcIpAddr, SrcHostname
      | where NxdomainCount > 200
      | extend NxdomainRate = round(todouble(NxdomainCount) / todouble(TotalQueries) * 100.0, 1)
      | where NxdomainRate > 40;
  // Signal 2: The failed domains exhibit DGA-typical consonant ratio + digits
  let DgaEntropyClients =
      ASimDnsActivityLogs
      | where TimeGenerated > ago(1h)
      | where DnsResponseCodeName =~ "NXDOMAIN" or DnsResponseCode == 3
      | extend SLD = tostring(split(DnsQuery, ".")[-2])
      | where strlen(SLD) between (10 .. 40)
      | extend
          ConsonantCount = countof(SLD, "b") + countof(SLD, "c") + countof(SLD, "d")
                         + countof(SLD, "f") + countof(SLD, "g") + countof(SLD, "h")
                         + countof(SLD, "j") + countof(SLD, "k") + countof(SLD, "l")
                         + countof(SLD, "m") + countof(SLD, "n") + countof(SLD, "p")
                         + countof(SLD, "q") + countof(SLD, "r") + countof(SLD, "s")
                         + countof(SLD, "t") + countof(SLD, "v") + countof(SLD, "w")
                         + countof(SLD, "x") + countof(SLD, "y") + countof(SLD, "z"),
          HasDigits = SLD matches regex @"\d"
      | extend ConsonantRatio = todouble(ConsonantCount) / todouble(strlen(SLD))
      | where ConsonantRatio > 0.65 and HasDigits == true
      | summarize
          DgaLikeDomains = dcount(DnsQuery),
          SampleDomains  = make_set(DnsQuery, 15)
        by SrcIpAddr, SrcHostname
      | where DgaLikeDomains > 5;
  // Both signals must match the same client — high confidence DGA
  NxdomainClients
  | join kind=inner DgaEntropyClients on SrcIpAddr
  | project
      SrcIpAddr,
      SrcHostname,
      NxdomainCount,
      NxdomainRate,
      UniqueDomains,
      DgaLikeDomains,
      SampleDomains,
      FirstSeen,
      LastSeen
entityMappings:
  - entityType: Host
    fieldMappings:
      - identifier: HostName
        columnName: SrcHostname
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: SrcIpAddr
alertDetailsOverride:
  alertDisplayNameFormat: "DGA/NXDOMAIN Flood — {{SrcHostname}} got {{NxdomainCount}} NXDOMAIN responses ({{NxdomainRate}}%)"
  alertDescriptionFormat: "{{SrcHostname}} ({{SrcIpAddr}}) received {{NxdomainCount}} NXDOMAIN responses ({{NxdomainRate}}% failure rate) across {{UniqueDomains}} unique domains in 1 hour. This pattern is characteristic of DGA malware. Sample domains: {{SampleDomains}}"
customDetails:
  NxdomainCount: NxdomainCount
  NxdomainRate: NxdomainRate
  DgaLikeDomains: DgaLikeDomains

Explanation

This query is designed to detect high-confidence Domain Generation Algorithm (DGA) activity by combining two specific signals. Here's a simplified breakdown:

  1. Purpose: The query aims to identify potential DGA-related malicious activity by analyzing DNS query patterns that are typical of malware using DGAs.

  2. Signals Used:

    • NXDOMAIN Volume: It checks for clients that receive more than 200 NXDOMAIN (non-existent domain) responses within an hour, with a failure rate exceeding 40%. This indicates a high volume of failed DNS queries.
    • Domain Entropy: It looks for failed domains that have a high consonant ratio (over 65%) and contain digits, which are characteristics of pseudo-randomly generated domains typical of DGA.
  3. Detection Criteria: A client must meet both conditions (high NXDOMAIN volume and DGA-like domain patterns) to trigger an alert. This dual-condition approach reduces false positives compared to using either signal alone.

  4. Malware Families: The rule is particularly relevant for detecting malware families known to use DGAs, such as Emotet, QakBot, Dridex, TrickBot, and others.

  5. Alerting: When both conditions are met, an alert is generated with details about the source IP, hostname, number of NXDOMAIN responses, failure rate, and sample domains.

  6. Operational Details:

    • The query runs every hour and checks data from the past hour.
    • It uses data from Windows DNS logs.
    • The alert severity is set to high due to the strong indication of malicious activity.
  7. Recommendations: Disable other built-in alerts that check only for high NXDOMAIN volume or failure rate alone to avoid duplicate alerts, as this rule provides a more comprehensive detection method.

Overall, this query is a sophisticated method to detect potential DGA-based attacks by analyzing DNS query patterns and characteristics.

Details

David Alonso profile picture

David Alonso

Released: March 26, 2026

Tables

ASimDnsActivityLogs

Keywords

DnsActivityLogsHostIpAddressHostnameDgaNxdomainDomainsQueriesResponsesMalwareEmotetQakbotTrickbotDridex

Operators

letwheresummarizecount()countif()dcount()min()max()extendround()todouble()split()tostring()strlen()countof()matches regexsummarizemake_set()joinproject

Actions