Query Details

DGA Confirmed — NXDOMAIN Flood with High-Entropy Domain Pattern

12 DNS NXDOMAIN DGA 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 > 500
    | 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

Explanation

This query is designed to detect high-confidence Domain Generation Algorithm (DGA) activity by analyzing DNS logs for specific patterns. It combines two main signals to identify potential DGA-related threats:

  1. High NXDOMAIN Volume: It looks for clients that receive more than 500 NXDOMAIN (non-existent domain) responses in one hour, with a failure rate exceeding 40%. This indicates a high volume of failed DNS queries, which is suspicious.

  2. DGA-Typical Domain Patterns: It checks if the failed domains have a high consonant ratio (over 65%) and contain digits, which are characteristics of pseudo-randomly generated domains often used by DGA malware.

Both conditions must be met for a client to trigger an alert, reducing false positives compared to using either condition alone. This approach is more reliable for detecting DGA-related activities associated with malware families like Emotet, QakBot, and TrickBot.

The query runs every hour and generates alerts for clients that match both criteria, providing details such as the number of NXDOMAIN responses, failure rate, and sample domains. It suggests disabling certain built-in alerts to avoid duplicates when using this rule.

Details

David Alonso profile picture

David Alonso

Released: July 28, 2026

Tables

ASimDnsActivityLogs

Keywords

DnsActivityLogsHostIpAddressDgaNxdomainEmotetQakbotTrickbotDridexCommandAndControl

Operators

letwheresummarizecountcountifdcountminmaxextendroundtodoubletostringsplitstrlencountofmatchesregexmake_setjoinproject

Severity

High

Tactics

CommandAndControl

MITRE Techniques

Frequency: 1h

Period: 1h

Actions

GitHub