Response playbooks, investigation guides, and Atomic Red Team tests are Pro-only. Upgrade to unlock the full detection package for THREAT-Recon-DNSSubdomainWordlistEnumeration.

Upgrade to Pro
THREAT-Recon-DNSSubdomainWordlistEnumeration Microsoft Sentinel · KQL

Detect DNS Subdomain Wordlist Brute-Force Enumeration in Microsoft Sentinel

Adversaries iteratively query an organization's authoritative or recursive DNS infrastructure with large wordlists of candidate subdomain labels (dev, staging, vpn, mail-old, api-internal, etc.) to discover hostnames that were never intentionally published — forgotten staging environments, internal-only services accidentally exposed, or third-party integrations. Unlike the HTTP directory/file wordlist scanning covered by generic Active Scanning detections, this technique operates entirely at the DNS layer using tools such as massdns, puredns, gobuster's dns mode, dnsrecon, fierce, and amass's active enumeration mode, which resolve thousands of candidate FQDNs per minute and rely on the high NXDOMAIN response rate as an intrinsic side effect of brute-forcing an unknown namespace. Because these queries never touch a web server or generate an HTTP log line, they are invisible to WAF- and web-access-log-based scanning detections and require dedicated visibility into DNS server query logs (authoritative nameserver, recursive resolver, or DNS security gateway) plus endpoint process telemetry for internal pivot scanning.

MITRE ATT&CK

Tactic
Reconnaissance

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let SubdomainWordlistTools = dynamic([
    "massdns", "gobuster", "puredns", "dnsrecon", "fierce", "amass",
    "dnsx", "altdns", "dnscan", "subbrute", "assetfinder"
]);
// Branch 1: Authoritative/recursive DNS server query logs (BIND, PowerDNS, Unbound, Infoblox via syslog/CEF)
let DNSWordlistBruteforce =
    CommonSecurityLog
    | where TimeGenerated > ago(24h)
    | where DeviceEventClassID has_any ("dns", "query") or Activity has_any ("DNS Query", "Query")
    | where Message has "NXDOMAIN" or AdditionalExtensions has "NXDOMAIN"
    | extend QueriedFQDN = extract(@"query:\s*([a-zA-Z0-9\-\.]+)", 1, Message)
    | where isnotempty(QueriedFQDN)
    | extend BaseDomain = extract(@"([a-zA-Z0-9\-]+\.[a-zA-Z]{2,})$", 1, QueriedFQDN)
    | summarize
        NXDomainCount = count(),
        UniqueSubdomains = dcount(QueriedFQDN),
        UniqueBaseDomains = dcount(BaseDomain),
        SampleSubdomains = make_set(QueriedFQDN, 20),
        FirstQuery = min(TimeGenerated),
        LastQuery = max(TimeGenerated)
      by SourceIP, BaseDomain, DeviceVendor, DeviceProduct
    | where UniqueSubdomains >= 50 and NXDomainCount >= 50
    | extend
        DetectionBranch = "DNSServerQueryLog",
        ScanDurationMinutes = datetime_diff('minute', LastQuery, FirstQuery),
        QueryRatePerMinute = round(toreal(NXDomainCount) / iff(datetime_diff('minute', LastQuery, FirstQuery) > 0, datetime_diff('minute', LastQuery, FirstQuery), 1), 1)
    | project FirstQuery, LastQuery, ScanDurationMinutes, SourceIP, BaseDomain,
        NXDomainCount, UniqueSubdomains, QueryRatePerMinute, SampleSubdomains,
        DeviceVendor, DeviceProduct, DetectionBranch;
// Branch 2: Internal endpoint executing DNS subdomain wordlist/brute-force tooling
let InternalToolExecution =
    DeviceProcessEvents
    | where Timestamp > ago(24h)
    | where FileName has_any (SubdomainWordlistTools)
        or ProcessCommandLine has_any (
            "massdns -r", "gobuster dns", "puredns bruteforce", "dnsrecon -D",
            "fierce --domain", "amass enum -active", "dnsx -d", "altdns -i")
    | summarize
        AlertCount = count(),
        Commands = make_set(ProcessCommandLine, 5),
        Tools = make_set(FileName, 10),
        FirstSeen = min(Timestamp),
        LastSeen = max(Timestamp)
      by AccountName, DeviceName, FileName
    | extend
        DetectionBranch = "InternalDNSEnumTool",
        SourceIP = DeviceName,
        BaseDomain = "internal-pivot",
        NXDomainCount = AlertCount,
        UniqueSubdomains = AlertCount,
        QueryRatePerMinute = 0.0,
        SampleSubdomains = Commands,
        DeviceVendor = "MicrosoftDefenderEndpoint",
        DeviceProduct = FileName,
        ScanDurationMinutes = datetime_diff('minute', LastSeen, FirstSeen)
    | project FirstQuery = FirstSeen, LastQuery = LastSeen, ScanDurationMinutes, SourceIP, BaseDomain,
        NXDomainCount, UniqueSubdomains, QueryRatePerMinute, SampleSubdomains,
        DeviceVendor, DeviceProduct, DetectionBranch;
DNSWordlistBruteforce
| union InternalToolExecution
| sort by NXDomainCount desc
medium severity medium confidence

Detects DNS subdomain wordlist brute-forcing through two complementary branches. Branch 1 queries CommonSecurityLog for CEF-normalized DNS server query events (authoritative nameserver, recursive resolver, or DNS security gateway such as Infoblox) and flags source IPs generating a high volume of NXDOMAIN responses across many distinct subdomains of the same base domain within a rolling window — the intrinsic signature of brute-forcing an unknown DNS namespace with a wordlist. Branch 2 queries DeviceProcessEvents for execution of named DNS subdomain enumeration tools (massdns, gobuster dns mode, puredns, dnsrecon, fierce, amass active mode, dnsx, altdns) on monitored endpoints, covering internal pivot scanning or red team activity. Results are unioned for a unified triage view across both the DNS-server and endpoint-process detection surfaces.

Data Sources

Network Traffic: Network Traffic ContentNetwork Traffic: Network Traffic FlowProcess: Process CreationCommonSecurityLog (authoritative/recursive DNS query logs via CEF/syslog)Microsoft Defender for Endpoint DeviceProcessEvents

Required Tables

CommonSecurityLogDeviceProcessEvents

False Positives & Tuning

  • Authorized attack-surface management or external ASM vendors (e.g., contracted bug bounty platforms) running scheduled subdomain discovery scans from documented IP ranges
  • Internal DNS infrastructure teams or DevOps performing zone audits, cache-warming scripts, or DNS migration validation that queries many candidate hostnames in sequence
  • Approved penetration testing or red team engagements actively enumerating the DNS namespace during the engagement window
  • Certificate transparency monitoring or subdomain-discovery SaaS tooling that resolves large candidate lists to validate live hosts before issuing scan reports
  • Misconfigured internal applications or scripts performing rapid repeated DNS lookups against a typo'd or deprecated base domain (self-inflicted NXDOMAIN storms, not adversarial)

Other platforms for THREAT-Recon-DNSSubdomainWordlistEnumeration


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Simulated DNS Subdomain Wordlist Query Burst

    Expected signal: Authoritative/recursive DNS server query log entries showing 60 sequential NXDOMAIN responses for distinct subdomains of example.com from the executing host's source IP within a short window.

  2. Test 2gobuster DNS Mode Execution

    Expected signal: Process creation event for gobuster with CommandLine containing 'dns -d example.com -w' and the wordlist file path.

  3. Test 3massdns Bulk Subdomain Resolution

    Expected signal: Process creation event for massdns with CommandLine containing '-r' and '-t A' flags; DNS query log entries for the listed candidate subdomains.

Unlock playbooks & atomic tests with Pro

Get the full detection package for THREAT-Recon-DNSSubdomainWordlistEnumeration — response playbook and atomic red team tests, plus investigation guidance and hunting queries.

df00tech Pro — £29/user/month

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections