Network Intermediate Network / DNS / Threat Hunting

DNS Threat Hunting

A practical guide to hunting threats through DNS � covering record types, suspicious patterns, DGA detection, DNS tunneling, C2 over DNS, and hunting queries.

15 min read 15+ techniques Blue Team

// Why DNS?

DNS is the internet's phone book � it resolves domain names to IP addresses. Critically for defenders, almost every network connection starts with a DNS query. This makes DNS logs an exceptionally rich data source for threat hunting: you can see what domains endpoints are resolving, detect malware C2 communication, identify data exfiltration via DNS tunneling, and spot DGA (Domain Generation Algorithm) malware before it successfully reaches a live C2 server.

DNS is also frequently overlooked. Many organisations have robust firewall and endpoint logging but sparse or no DNS query logging, creating a significant blind spot that attackers exploit.

Sysmon Event ID 22 captures DNS queries on Windows endpoints. For network-level DNS, enable logging on your DNS resolver (Windows DNS Server, Pi-hole, BIND) or use a cloud DNS service with logging such as Cloudflare Gateway or Route 53 Resolver Query Logging.

// DNS Record Types

RecordPurposeAbuse Potential
AMaps hostname to IPv4 addressMost common for C2; watch for fast-flux (A records rotating every few seconds)
AAAAMaps hostname to IPv6 addressIPv6 C2 often bypasses IPv4-only firewall rules
CNAMEAlias pointing to another hostnameUsed in domain fronting; long CNAME chains can obscure real destination
MXMail exchange recordLow abuse, but querying unexpected MX records may indicate mail-related recon
TXTFreeform text � used for SPF, DKIM, domain verificationHigh: TXT records commonly used for DNS tunneling data exfiltration and C2
NSNameserver for a domainAttacker-controlled NS can reroute queries; watch for rare NS changes
PTRReverse DNS (IP to hostname)Reconnaissance � reverse lookups of internal IPs may indicate lateral movement
ANYRequest all record typesUsed in DNS amplification DDoS; endpoints querying ANY are unusual

// Suspicious Patterns

PatternIndicatorWhy It's Suspicious
High-entropy domain namesx7kqpz2m.evil.comDGA � algorithmically generated names have high Shannon entropy
Very short TTLTTL < 60 secondsFast-flux � rotating IPs to evade blocklists and attribution
Very long subdomain labelsAAAAAAAAAAAAAAAAAAAAAA.evil.comDNS tunneling � data encoded in the subdomain portion of the query
High query volume to one domain1000+ queries/hour from one hostDNS beaconing � malware polling C2 via frequent DNS requests
Queries to non-existent domains (NXDOMAIN storms)Many NXDOMAIN responses in sequenceDGA malware failing to reach live C2 domains � still highly diagnostic
Newly registered domainDomain registered < 30 days agoAttackers often register domains shortly before use
Direct IP resolution bypassing DNSOutbound connection to IP with no prior DNS queryMalware hardcoding C2 IP � bypasses DNS-based controls
TXT record queries from endpointsInternal host querying TXT recordsLegitimate apps rarely query TXT; common in DNS tunneling

// DGA Detection

Domain Generation Algorithms (DGAs) are used by malware to generate thousands of pseudo-random domain names. Only the attacker knows which domains are live on a given day � this makes blocklisting impractical. Detection relies on spotting the statistical properties of DGA names.

DGA indicators

IndicatorNormal RangeDGA Range
Shannon entropy of domain name2.0�3.5 bits3.5�5.0+ bits
Consonant-to-vowel ratio1.5�2.54.0+ (lots of consonants)
Presence in Alexa/Tranco top 1MYesNo
Trigram frequencyHigh (real words)Low (random character sequences)
NXDOMAIN rate for the domainLowHigh � most DGA domains don't resolve

NXDOMAIN storms are often more diagnostic than the domains themselves. If a host generates 500 NXDOMAIN responses in an hour for domains that look like xkqvzrpml.com, it's likely running DGA malware � even if you can't identify the specific family.

// DNS Tunneling

DNS tunneling encodes arbitrary data (commands, stolen files, C2 traffic) inside DNS queries and responses � exploiting the fact that DNS is almost never blocked at the perimeter. Tools like iodine, dnscat2, and DNSExfiltrator are commonly used.

Detection indicators

IndicatorDescription
Long subdomain labelsLabels approaching the 63-character limit packed with base32/base64 encoded data
High query volume per domainHundreds of queries per minute to the same authoritative domain
Large TXT or NULL record responsesResponse payload carrying encoded commands or shell output
Uncommon record typesTXT, NULL, CNAME, MX used for data exfil instead of A/AAAA
Unique subdomains per queryEvery query has a different subdomain � each carrying a unique data chunk
Data rate anomalyDNS data volume far exceeds what resolution alone would require

// C2 over DNS

Beyond full tunneling, many malware families use DNS for lightweight C2 beaconing � periodically resolving a domain and using the returned IP address as an encoded command. This is harder to detect because each individual query looks legitimate.

Beaconing detection

Look for regularity � malware beacons on a fixed schedule while humans browse irregularly. A host querying the same domain every 60 seconds for hours is a strong beacon signal. Use jitter analysis (standard deviation of query intervals) to separate malware from legitimate polling software.

// Hunting Queries

High-volume DNS queries from single endpoint (beaconing)

// Endpoints making unusually high number of DNS queries � Sysmon Event ID 22
Event
| where Source == "Microsoft-Windows-Sysmon"
| where EventID == 22
| where TimeGenerated > ago(1h)
| extend QueryName = extract(@"QueryName: ([^\s]+)", 1, RenderedDescription)
| summarize QueryCount = count(), Domains = dcount(QueryName) by Computer
| where QueryCount > 500
| sort by QueryCount desc

Long subdomain labels (DNS tunneling)

// Queries where the subdomain portion is unusually long
Event
| where Source == "Microsoft-Windows-Sysmon" and EventID == 22
| extend QueryName = extract(@"QueryName: ([^\s]+)", 1, RenderedDescription)
| extend NameLen = strlen(QueryName)
| where NameLen > 60
| project TimeGenerated, Computer, QueryName, NameLen
| sort by NameLen desc

NXDOMAIN storm detection (DGA)

// DNS queries returning NXDOMAIN in high volume � potential DGA
// Requires DNS server logs with response codes ingested into Sentinel
DnsEvents
| where TimeGenerated > ago(1h)
| where ResultCode == 3 // NXDOMAIN
| summarize NXCount = count() by ClientIP
| where NXCount > 100
| sort by NXCount desc