THREAT-Recon-SubdomainBruteforceNXDOMAINStorm Microsoft Sentinel · KQL

Detect Subdomain Bruteforce Causing NXDOMAIN Storm in Microsoft Sentinel

Before selecting a phishing pretext, staging infrastructure, or an external-facing service to target, adversaries frequently brute-force an organization's DNS namespace with a wordlist of common subdomain labels (vpn, mail, sso, dev, staging, api, remote, citrix, owa, etc.) to enumerate hosts that are not otherwise advertised. Tools such as dnsx, massdns, puredns, gobuster (dns mode), dnsrecon, and fierce resolve tens of thousands of candidate labels per minute against the target's authoritative or recursive DNS servers. Because most guessed labels do not correspond to a real record, this activity produces a highly distinctive footprint at the DNS server: a single source issuing an extremely high volume of queries against the organization's domain(s) within a short window, the overwhelming majority of which return NXDOMAIN, with very little repetition between query names (each guess is unique, unlike a caching resolver replaying the same handful of hostnames). This is distinct from the broader DNS/passive-DNS reconnaissance techniques already covered on the parent T1596.001 page (which include zone-transfer attempts and tool-execution detection) in that it isolates the specific volumetric NXDOMAIN-ratio signature that a bruteforce sweep leaves on the DNS server itself, catching enumeration even when the querying tool cannot be observed on an endpoint (e.g., run from an external host, a compromised third-party network, or a VPS with no EDR visibility) and regardless of which specific tool was used to generate the wordlist traffic. Scattered Spider and other access brokers routinely run this style of sweep against a target's public domain ahead of helpdesk-vishing and SSO-phishing campaigns to build a list of live internal-sounding hostnames to reference for pretext and targeting.

MITRE ATT&CK

Tactic
Reconnaissance

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// THREAT: Subdomain Bruteforce NXDOMAIN Storm (Reconnaissance, T1596.001)
// Detects wordlist-driven subdomain enumeration against the organization's own
// DNS servers: a single client IP generating a very high query volume with an
// overwhelming NXDOMAIN ratio and near-1:1 unique-name-to-query ratio (each
// guess is a distinct label, unlike normal caching resolver traffic).
// Source: DnsEvents (Azure DNS Analytics solution / Microsoft DNS Server connector)
let LookbackWindow = 15m;
let MinTotalQueries = 200;
let MinNxDomainRatio = 0.85;
let MinUniqueLabelRatio = 0.90;
DnsEvents
| where TimeGenerated > ago(LookbackWindow)
| where QueryType in ("A", "AAAA", "CNAME", "MX", "TXT", "SRV", "NS")
| summarize
    TotalQueries = count(),
    UniqueSubdomains = dcount(Name),
    NxDomainCount = countif(ResultCode =~ "NXDOMAIN"),
    QueryTypes = make_set(QueryType, 10),
    SampleQueries = make_set(Name, 5),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
  by ClientIP, bin(TimeGenerated, LookbackWindow)
| extend NxDomainRatio = round(NxDomainCount * 1.0 / TotalQueries, 2)
| extend UniqueLabelRatio = round(UniqueSubdomains * 1.0 / TotalQueries, 2)
| where TotalQueries >= MinTotalQueries and NxDomainRatio >= MinNxDomainRatio and UniqueLabelRatio >= MinUniqueLabelRatio
| extend ThreatType = "SubdomainBruteforce_NXDOMAINStorm"
| extend Severity = iff(TotalQueries >= 2000, "High", "Medium")
| sort by TotalQueries desc
medium severity medium confidence

Aggregates DNS queries per client IP over 15-minute windows using the DnsEvents table (requires Azure DNS Analytics or the Microsoft DNS Server connector) and flags a source once it crosses 200+ queries in the window with an NXDOMAIN ratio of 85%+ and a unique-query-name ratio of 90%+ — the combination that distinguishes wordlist-driven subdomain bruteforce from normal resolver traffic (which repeats a small set of cached names and rarely returns majority NXDOMAIN). Tune thresholds down for smaller DNS estates and up for high-traffic public resolvers.

Data Sources

DNS Server: DNS TrafficMicrosoft DNS Server (via Azure Monitor / DNS Analytics solution)Recursive resolver and authoritative nameserver query logs

Required Tables

DnsEvents

False Positives & Tuning

  • Authorized attack-surface management or vulnerability scanning platforms (Censys, Shodan Enterprise, Tenable ASM, BitSight) performing scheduled subdomain discovery sweeps against the organization's own domains
  • Internal red team or pentest engagements running subdomain enumeration as part of an authorized reconnaissance phase
  • Misconfigured internal applications or scripts with a typo'd or stale hostname list that retry against many non-existent names in a tight loop
  • Wildcard DNS misconfiguration or a recently decommissioned subdomain still being queried at volume by clients with stale cached configuration
  • DNS-based security research crawlers (e.g., certificate transparency monitors, threat-intel feeds) validating large candidate-subdomain lists against public zones

Other platforms for THREAT-Recon-SubdomainBruteforceNXDOMAINStorm


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 1Subdomain Bruteforce Simulation via dnsx

    Expected signal: DNS server query logs record several hundred queries within a short window from the test source IP, with the large majority returning NXDOMAIN and each query name unique (near-1:1 unique-name-to-query ratio).

  2. Test 2High-Speed Bruteforce Simulation via massdns

    Expected signal: DNS server logs show a sharp spike in query volume from the test source IP within seconds to minutes, with the overwhelming majority of responses being NXDOMAIN.

  3. Test 3Low-and-Slow Throttled Enumeration Simulation

    Expected signal: DNS server logs record roughly 80 queries spread over about 40 minutes from the test source IP, nearly all returning NXDOMAIN, each with a unique query name.


Response Playbook

Triage

  1. Confirm the DNS server(s) receiving the flagged volume are the organization's own authoritative or recursive nameservers, and identify which of the organization's registered domains the swept queries target.
  2. Pull a sample of the actual query names (not just aggregate counts) — a wordlist pattern (vpn.<domain>, sso.<domain>, dev.<domain>, api.<domain>, mail.<domain>) confirms bruteforce enumeration rather than a benign traffic anomaly.
  3. Check the source IP's reputation and infrastructure type (AbuseIPDB, Shodan, VirusTotal, WHOIS). Bruteforce sweeps commonly originate from VPS hosting or scanning-as-a-service infrastructure (Censys, Shodan, BinaryEdge) rather than residential ranges.
  4. Determine whether the source IP correlates with a known authorized scanner (attack-surface-management vendor, internal red team, vulnerability management platform) before treating as hostile.
  5. Identify any subdomains in the sweep that DID resolve (the small non-NXDOMAIN remainder) — these are the hostnames the adversary successfully discovered and are likely to be referenced in a follow-on phishing or access attempt.
  6. Check whether the same source IP or infrastructure cluster has swept other organizations you have shared visibility into (ISAC feeds, threat intel), indicating a broad, non-targeted reconnaissance campaign versus one aimed specifically at this organization.

Containment

  1. Block the sweeping source IP at the DNS server ACL and at the network perimeter/WAF.
  2. Enable or tighten response-rate limiting (RRL) on authoritative/recursive DNS servers so a single source cannot generate unbounded query volume.
  3. For any newly discovered live hostnames the sweep surfaced (the resolving remainder), verify they are intended to be externally reachable; decommission or restrict access to any stale/forgotten hosts (old staging, dev, or admin panels) uncovered by the enumeration.
  4. If the sweep is tied to a broader campaign (e.g., preceding Scattered Spider-style helpdesk vishing), notify the helpdesk/IT support team to expect social-engineering attempts referencing the discovered hostnames.

Evidence Collection

  1. Full DNS query log export (query name, response code, timestamp) for the flagged source IP across the sweep window
  2. List of query names that resolved successfully (non-NXDOMAIN) during the sweep, to identify what infrastructure the adversary now knows exists
  3. Threat intelligence enrichment on the source IP/ASN and hosting provider
  4. DNS server RRL/rate-limit logs, if enabled, showing whether queries were throttled or dropped

Escalation Criteria

  • !The sweep surfaces a live (resolving) subdomain that exposes an unintended or forgotten service (staging environment, admin panel, legacy VPN endpoint)
  • !The sweep is immediately followed by authentication attempts, phishing, or vishing activity referencing one of the discovered hostnames
  • !The same source infrastructure is observed sweeping multiple business units, subsidiaries, or partner organizations, indicating a large-scale reconnaissance campaign
  • !Enumeration traffic overlaps in time with other reconnaissance techniques (WHOIS lookups, certificate transparency monitoring, employee OSINT) against the same organization, suggesting a coordinated targeting effort

Investigation Guide

Related Techniques

Forensic Artifacts

  • >DNS server query logs (DnsEvents / Windows DNS Server analytical log / Zeek dns.log) showing per-query name, type, response code, and source IP
  • >Source IP/ASN reputation and hosting-provider classification
  • >Response-rate-limiting or DNS firewall logs indicating throttled or blocked query volume
  • >Any resolving (non-NXDOMAIN) query names discovered during the sweep, cross-referenced against the organization's asset inventory

Tuning Guidance

The 200-query / 85% NXDOMAIN / 90% unique-label thresholds are tuned for a mid-size organization's DNS estate over a 15-minute window. High-traffic public resolvers or CDN-fronted domains may need the volume threshold raised substantially to avoid false positives from legitimate high-QPS clients; conversely, small organizations with low baseline DNS traffic can lower the volume threshold to 50-100 to catch throttled, low-and-slow sweeps designed to evade rate limiting. Always allowlist known attack-surface-management vendors and authorized scanning source IPs by exact address rather than by raising thresholds, since a raised threshold risks missing a genuinely throttled adversary sweep. The unique-label ratio is the strongest secondary signal: a caching resolver replaying a small set of real hostnames will have a low ratio, while a wordlist-driven bruteforce tool generates a near-1:1 ratio because almost every guess is unique.


Hunting Queries

Broader 7-day hunt using a lower query-volume threshold (50) and relaxed NXDOMAIN ratio (0.70) over wider 1-hour buckets to surface slower, lower-and-slower subdomain enumeration that stays under the main detection's 15-minute/200-query thresholds.

Hunting — KQL
kql
DnsEvents
| where TimeGenerated > ago(7d)
| where QueryType in ("A", "AAAA", "CNAME", "MX", "TXT", "SRV", "NS")
| summarize
    TotalQueries = count(),
    UniqueSubdomains = dcount(Name),
    NxDomainCount = countif(ResultCode =~ "NXDOMAIN")
  by ClientIP, bin(TimeGenerated, 1h)
| extend NxDomainRatio = round(NxDomainCount * 1.0 / TotalQueries, 2)
| extend UniqueLabelRatio = round(UniqueSubdomains * 1.0 / TotalQueries, 2)
| where TotalQueries >= 50 and NxDomainRatio >= 0.70
| sort by TotalQueries desc
Hunting — SPL
spl
index=dns sourcetype=stream:dns
| eval QueryName=coalesce(query, query_name, name, "")
| eval SourceIP=coalesce(src_ip, src, client_ip)
| eval ResponseCode=upper(coalesce(rcode_name, reply_code, ""))
| bin _time span=1h
| stats count AS TotalQueries, dc(QueryName) AS UniqueSubdomains,
    count(eval(ResponseCode="NXDOMAIN")) AS NxDomainCount
  BY SourceIP, _time
| eval NxDomainRatio=round(NxDomainCount/TotalQueries, 2)
| eval UniqueLabelRatio=round(UniqueSubdomains/TotalQueries, 2)
| where TotalQueries >= 50 AND NxDomainRatio >= 0.70
| sort - TotalQueries

Atomic Red Team Tests

Test 1 Subdomain Bruteforce Simulation via dnsx
linux

Simulates a wordlist-driven subdomain enumeration sweep using dnsx against a lab domain, generating a high volume of queries where the majority of guessed labels do not exist. Tests detection of the high-volume, high-NXDOMAIN-ratio, high-unique-label-ratio signature.

Command

bash
cat wordlist.txt | sed 's/$/.<LAB_DOMAIN>/' | dnsx -silent -resp -rcode -t 100 > dnsx_results.txt

Cleanup

bash
rm -f dnsx_results.txt

Expected Telemetry

DNS server query logs record several hundred queries within a short window from the test source IP, with the large majority returning NXDOMAIN and each query name unique (near-1:1 unique-name-to-query ratio).

Expected Detection

Alert fires when TotalQueries >= 200, NxDomainRatio >= 0.85, and UniqueLabelRatio >= 0.90 within the 15-minute aggregation window (lower thresholds in a lab tenant to validate against a smaller wordlist).

Test 2 High-Speed Bruteforce Simulation via massdns
linux

Replays a high-throughput subdomain resolution sweep using massdns against a mock wordlist, mimicking the volumetric query pattern of a fast bruteforce tool rather than a slower single-threaded scanner.

Command

bash
awk '{print $1".""<LAB_DOMAIN>"}' wordlist.txt | massdns -r resolvers.txt -t A -o S -w massdns_output.txt

Cleanup

bash
rm -f massdns_output.txt

Expected Telemetry

DNS server logs show a sharp spike in query volume from the test source IP within seconds to minutes, with the overwhelming majority of responses being NXDOMAIN.

Expected Detection

Alert fires on the aggregate TotalQueries/NxDomainRatio thresholds from the source IP; the Severity field escalates to High if volume exceeds 2000 queries in the window.

Test 3 Low-and-Slow Throttled Enumeration Simulation
linux

Simulates a rate-limit-evading subdomain sweep that throttles query rate to stay below common per-minute alerting thresholds, validating the hunting query's relaxed thresholds over a wider window.

Command

bash
python3 -c "
import socket, time
labels = [f'test{i}' for i in range(1, 80)]
for label in labels:
    try:
        socket.gethostbyname(f'{label}.<LAB_DOMAIN>')
    except socket.gaierror:
        pass
    time.sleep(30)
"

Expected Telemetry

DNS server logs record roughly 80 queries spread over about 40 minutes from the test source IP, nearly all returning NXDOMAIN, each with a unique query name.

Expected Detection

Falls below the primary 15-minute/200-query detection but should be surfaced by the tuning-guidance hunting query using the relaxed 50-query/70% NXDOMAIN/1-hour thresholds.

Related Detections