Detection Playbook: DNS (T1071.004)

T1071.004 · 2026-07-12

DNS

Command And Control
ESXi Linux macOS Network Devices
MITRE ATT&CK →
Technique DNS (T1071.004)
Tactic Command And Control
Platforms ESXi, Linux, macOS, Network Devices, Windows

Overview

DNS tunneling (T1071.004) is a command-and-control technique where adversaries embed data — including commands and exfiltrated output — inside DNS query and response packets. Because DNS is a foundational network protocol, most firewalls and proxies permit it freely, allowing attackers to establish covert channels that bypass traditional egress controls and reach attacker-controlled nameservers anywhere on the internet.

Every security team needs visibility into this technique because DNS traffic is almost universally allowed, even on hardened networks, making it one of the most reliable C2 channels available to attackers. Threat actors including OilRig, APT groups using Cobalt Strike DNS listeners, and ransomware operators have all weaponized DNS tunneling to maintain persistent, low-profile communication with compromised hosts. Without active DNS monitoring, this traffic is effectively invisible.

Attacker Perspective

Attackers abuse DNS because it is allowed through nearly every network boundary by default and blends seamlessly with legitimate resolver traffic.

  • DNS tunneling for full C2 channel: Tools like iodine, dns2tcp, and dnscat2 encode arbitrary TCP/IP traffic inside DNS TXT, CNAME, or NULL record queries, creating a bidirectional shell over port 53 without needing any other outbound access.
  • Cobalt Strike DNS beacon: Cobalt Strike’s DNS listener mode sends short check-in beacons as A-record lookups to attacker-controlled domains (e.g., a1b2c3.stager.evil.com) and receives tasking embedded in the response, with configurable jitter to defeat interval-based detection.
  • Data exfiltration via DNS queries: Tools like DNSExfiltrator and custom Python scripts Base64-encode file chunks into subdomains (e.g., dmFsdWU=.chunk01.attacker.com), querying the attacker’s authoritative NS to silently extract data without a direct TCP connection.
  • DNS beaconing with low frequency: Malware families such as BONDUPDATER and OilRig implants beacon infrequently — sometimes every 30–60 minutes — querying randomized subdomains under a registered domain to receive encoded commands in TXT record responses, deliberately staying below alerting thresholds tied to frequency.

DNS tunneling is particularly attractive because it requires only outbound UDP/TCP port 53 access to any resolver, a condition that is satisfied on virtually every corporate, cloud, and OT network in existence.

Detection Strategy

Required Telemetry

  • Windows DNS Client Logs: Enable the Microsoft-Windows-DNS-Client ETW provider. In Event Viewer this appears under Applications and Services Logs → Microsoft → Windows → DNS-Client → Operational. Enable via PowerShell: wevtutil sl Microsoft-Windows-DNS-Client/Operational /e:true. Generates Event ID 3008 (DNS query initiated by process) and 3020 (DNS response received). These events include the querying process ID, which is critical for tying DNS queries to specific processes.
  • Windows DNS Server Logs (if running Windows DNS): Enable DNS Debug Logging on the Windows DNS Server via dnscmd /config /loglevel 0x8100F331 or via DNS Manager → Server Properties → Debug Logging. Alternatively, forward DNS Server Analytical logs: Microsoft-Windows-DNSServer/Analytical, Event ID 256 (query received). Include client IP, query name, query type, and response code.
  • Sysmon on Windows: Deploy Sysmon with a configuration that captures Event ID 22 (DNSEvent — DNS query). This is the single most valuable Windows telemetry for this technique. Requires Sysmon v11+ and a config that does not filter out DNS events. Fields include QueryName, QueryResults, Image (process path), ProcessId. Enable via Sysmon config: <DnsQuery onmatch="exclude"></DnsQuery> (capture all by default then tune).
  • Network DNS Traffic (Passive DNS / Network Sensor): Deploy a network-based DNS sensor (Zeek/Bro, Suricata with DNS logging, or a commercial NDR). Zeek generates dns.log with fields: ts, uid, id.orig_h (client IP), query (queried domain), qtype_name (record type), answers, TTL. This captures DNS traffic from all devices including Linux, macOS, ESXi, and network devices that don’t generate host-based events.
  • Linux/macOS — auditd or osquery: On Linux, auditd does not natively log DNS queries; instead deploy osquery with the dns_resolvers and process_open_sockets tables, or use an EDR agent. Alternatively, capture DNS at the network layer using Zeek. On macOS, enable EndpointSecurity framework via EDR, or use dnssdutil query logs.
  • Firewall / DNS Resolver Query Logs: Collect query logs from your recursive resolvers (Infoblox, BlueCat, Cisco Umbrella, Pi-hole, or Windows DNS) and from perimeter firewalls. These logs capture DNS queries that reach the resolver and are essential for detecting queries from hosts without endpoint agents.
  • Proxy / Web Gateway Logs: Some DNS-over-HTTPS (DoH) tunneling may appear as HTTPS to known DoH providers (8.8.8.8, 1.1.1.1, 9.9.9.9). Web proxy logs should capture these connections for review alongside DNS telemetry.

Key Indicators

  • Excessively long subdomain labels: In Zeek dns.log or Sysmon Event ID 22, check query field length. Legitimate DNS queries rarely exceed 50–60 characters. Tunneling tools encode data in subdomains, producing values like dmFsdWU=Y2h1bmswMQ==.evil.com. Flag queries where len(query) > 52 or where any single subdomain label exceeds 32 characters.
  • High entropy subdomain names: Tunneling tools generate subdomains with high Shannon entropy due to Base64 or hex encoding. Calculate entropy on the subdomain portion (everything left of the registered domain). Entropy above 3.5 bits/character for a label longer than 15 characters is a strong indicator. Tools like freq.py or SIEM-native entropy functions can calculate this.
  • Unusual DNS record types: In Zeek dns.log, check qtype_name. Legitimate enterprise traffic is overwhelmingly A and AAAA. Flag queries for TXT, NULL, CNAME, MX record types from workstations or servers that have no business reason to query these. Especially flag TXT queries to newly registered or unknown domains.
  • Abnormal query volume per domain: In resolver or Zeek logs, aggregate query by registrable domain per source IP per hour. Legitimate domains rarely receive more than 50–100 distinct subdomain queries per hour from a single host. DNS tunneling can produce hundreds to thousands of unique subdomain queries to the same parent domain. Alert when a single host generates more than 200 unique subdomains under one parent domain in one hour.
  • Unexpected process making DNS queries (Sysmon Event ID 22): Check Image field. Processes such as cmd.exe, powershell.exe, wscript.exe, mshta.exe, rundll32.exe, or any process running from %TEMP%, %APPDATA%, or C:\Users\Public making DNS queries to external domains is highly suspicious. Legitimate DNS queries from these processes are rare in most environments.
  • Low TTL values in responses: In Zeek dns.log, check the TTL field on responses. Attacker-controlled nameservers often set very low TTLs (0–30 seconds) to ensure fresh data delivery per query. Flag DNS responses with TTL < 10 combined with a high query frequency to the same domain.
  • Consistent periodic beaconing intervals: In resolver or Zeek logs, compute query intervals per source-domain pair. DNS beacons produce a regular query pattern (e.g., every 30 minutes ± jitter). Flag source IPs that query the same domain at statistically regular intervals over a 24-hour period — this is distinct from browser or application DNS caching behavior.
  • Queries to newly registered or low-reputation domains: Enrich query fields with WHOIS domain age and threat intelligence. Domains registered within the last 30 days receiving TXT or repeated unique-subdomain queries from internal hosts are high-priority alerts.
  • DNS queries bypassing the corporate resolver: In firewall logs, flag UDP/TCP port 53 traffic from internal hosts destined for any IP other than the approved internal DNS server IPs. This indicates the host is querying an external or attacker-controlled resolver directly to avoid monitoring.

Detection Logic

Rule 1 (Broad — High Sensitivity): High Volume of Unique Subdomains per Parent Domain
IF dns.log source_ip = internal_subnet AND count(DISTINCT subdomain(query)) > 200 WITHIN 1 hour GROUP BY source_ip, registrable_domain THEN alert("DNS Tunneling — High Subdomain Volume")

This catches active DNS tunneling sessions (iodine, dnscat2, dns2tcp) where bulk data transfer generates large numbers of unique subdomain queries. Expected volume in most environments: 0–2 alerts per day; will fire on some CDN edge cases — tune threshold up if needed. Also catches early-stage Cobalt Strike DNS stagers.

Rule 2 (Medium — Behavioral): Long or High-Entropy DNS Query Names
IF dns.log query_length > 52 AND entropy(leftmost_label(query)) > 3.5 AND NOT registrable_domain IN [known_cdn_allowlist] THEN alert("DNS Tunneling — High Entropy Subdomain")

This detects data-in-subdomain encoding even at low query rates, catching slow exfiltration and low-frequency beacons that evade volume-based rules. Expected volume: 1–5 per day in most environments; primary false positives are CDN and cloud services using hash-based subdomains (e.g., Akamai, Fastly, AWS).

Rule 3 (Medium — Process-Based): Suspicious Process Issuing DNS Queries — Sysmon EID 22
IF sysmon EventID = 22 AND Image IN ["cmd.exe","powershell.exe","wscript.exe","mshta.exe","rundll32.exe","regsvr32.exe"] AND QueryName NOT IN [internal_domain_list] AND QueryName NOT IN [known_good_domains] THEN alert("Suspicious Process DNS Query")

This catches malware that directly invokes DNS resolution from scripting or LOLBin processes — a common pattern for dnscat2 clients, BONDUPDATER, and PowerShell-based C2 implants. Expected volume: low, 0–3 per day; the main tuning challenge is PowerShell-based IT automation.

Rule 4 (Narrow — High Precision): DNS TXT/NULL Query from Workstation to Low-Reputation Domain
IF dns.log qtype_name IN ["TXT","NULL"] AND source_ip IN [workstation_subnet] AND domain_age(registrable_domain) < 30_days AND NOT registrable_domain IN [allowlist] THEN alert("DNS C2 — Suspicious Record Type from Workstation")

This is a high-precision rule targeting command receipt via TXT records — the most common mechanism in OilRig/BONDUPDATER-style implants and many Cobalt Strike configurations. Expected volume: very low, 0–1 per day; new SaaS onboarding is the main false positive source.

Tuning Guidance

  • CDN and cloud services with hash-based subdomains: Services like Akamai (*.akamaiedge.net), AWS CloudFront (*.cloudfront.net), Fastly, and Azure CDN generate high-entropy subdomains as part of normal routing. Build and maintain a known_cdn_allowlist and exclude these registrable domains from entropy and length-based rules.
  • Software update mechanisms: Applications like Chrome, Firefox, Windows Update, and Office 365 can generate bursts of DNS queries during update checks. Exclude known update endpoints (e.g., *.windowsupdate.com, *.office365.com, *.google.com) from volume-based rules. Correlate with patch schedule windows to further suppress.
  • SCCM / endpoint management DNS queries: SCCM, Tanium, and similar management tools running as svchost.exe or dedicated agent processes generate frequent, legitimate DNS queries. Exclude parent_process = ccmexec.exe and management tool process names from process-based rules. Do not exclude from network-layer rules.
  • DNS-over-HTTPS (DoH) suppressing endpoint telemetry: Modern browsers (Chrome, Firefox, Edge) use DoH by default, which means DNS queries appear as HTTPS to resolver IPs rather than DNS traffic. This can cause false negatives in DNS-based detections. Detect and block unauthorized DoH usage at the firewall level to ensure all DNS flows through monitored resolvers.
  • Legitimate TXT record queries: Email clients and security tools query TXT records for SPF, DKIM, and DMARC validation. These will come from mail servers and security scanners, not from workstations. Exclude source_ip IN [mail_server_list, security_scanner_list] from TXT-query rules rather than excluding the query type globally.
  • IT automation and scripting: PowerShell-based automation and Ansible/Puppet/Chef agents frequently issue DNS queries. Create a known_automation_accounts and known_automation_hosts list and exclude these from process-based rules only — not from network-layer rules, since a compromised automation account issuing tunneling traffic is a high-value detection.

When the Alert Fires: Investigation Steps

  1. Verify the alert is real: Pull the raw DNS event from its source — Sysmon Event ID 22 in your SIEM or the raw Zeek dns.log entry — and confirm the QueryName, source_ip, timestamp, and process fields are present and not artifacts of log parsing. Check that the queried domain actually resolves to an external IP, not an internal split-horizon response.
  2. Identify the affected host and user: Use the source IP and process ID from the DNS event to identify the hostname via your DHCP/IPAM logs or Active Directory. Check whether the associated user account is a privileged account (domain admin, service account, or tier-0 asset) — if so, treat this as high priority immediately.
  3. Pull the full command-line and parent process chain: In Sysmon, correlate the ProcessId from Event ID 22 with Event ID 1 (Process Create) to get the full CommandLine, ParentImage, and ParentCommandLine. In an EDR console, pull the full process tree — look for unusual parent-child relationships such as winword.exe → cmd.exe → powershell.exe or processes spawned from temp directories.
  4. Check for network connections and files written to disk: Review Sysmon Event ID 3 (Network Connection) and Event ID 11 (File Created) for the same ProcessId around the same timestamp. Look for outbound connections to external IPs on port 53 to non-corporate resolvers, and for any dropped binaries, scripts, or DLLs written to %TEMP%, %APPDATA%, or C:\Users\Public.
  5. Enumerate all unique domains queried by the affected host: In your SIEM, query all DNS events (Sysmon EID 22 or Zeek dns.log) from the affected source IP over the past 7 days. Identify any consistent beaconing pattern (regular interval queries to the same domain), bulk unique subdomain queries, or TXT/NULL record queries. Pivot on any new domains to threat intelligence platforms (VirusTotal, Shodan, PassiveDNS) to establish attacker infrastructure.
  6. Look for lateral movement from this host: Search Windows Security Event ID 4624 (logon) and 4648 (explicit credential use) for authentication events originating from the affected host to other internal systems, particularly after the first DNS tunnel event. Check Sysmon Event ID 3 for SMB (port 445), RDP (port 3389), or WinRM (port 5985) connections initiated from the host. In Zeek conn.log, look for internal east-west connections from the compromised host.
  7. Search for persistence mechanisms: On the affected host, check Sysmon Event ID 13 (Registry Value Set) for Run/RunOnce key modifications, Event ID 11 for files dropped to startup folders, and Windows Event ID 4698 (Scheduled Task Created) or 7045 (Service Installed) in the System log. Use EDR or autoruns remotely if accessible. If the host runs Linux, check /etc/cron*, ~/.bashrc, /etc/rc.local, and new systemd unit files.

Response Playbook

Containment

  • Isolate the affected host immediately but leave it powered on: Use your EDR console (CrowdStrike, Defender for Endpoint, SentinelOne) to network-isolate the host, or place the switch port in a quarantine VLAN via your NAC solution. Do not power off the machine — volatile memory may contain decrypted C2 traffic, encryption keys, or injected shellcode that will be lost.
  • Block identified C2 domains and IPs at all enforcement points: Add the attacker-controlled domain(s) identified in investigation step 5 to your DNS sinkhole (Infoblox, Umbrella, Pi-hole), perimeter firewall deny list, and web proxy block list simultaneously. Block the specific external resolver IPs if the host was bypassing the corporate DNS server. Document every IOC blocked with timestamp for the incident record.
  • Disable the affected user account: In Active Directory, disable the account via Disable-ADAccount -Identity username or in Azure AD via the Entra admin portal. If it is a service account, coordinate with the application owner before disabling — but do not delay if the account has admin privileges. Revoke any active Kerberos tickets by resetting the account password twice.
  • Kill the malicious process: If the host is not yet fully isolated and the malicious process is identified, use your EDR's remote response capability or PsExec/WinRM to terminate the process by PID. Record the process hash (SHA256) from Sysmon Event ID 1 before killing it for threat intelligence submission.
  • Block outbound port 53 to non-approved resolvers at the firewall: Implement or verify a firewall rule that blocks all outbound UDP/TCP port 53 traffic from internal subnets to any destination other than your approved internal DNS server IPs. This prevents any remaining infected hosts from establishing new tunnels to attacker nameservers.

Eradication

  • Remove persistence mechanisms discovered in investigation step 7: Delete any identified scheduled tasks (schtasks /delete /tn "TaskName" /f), remove malicious registry Run keys (reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v MaliciousEntry /f), uninstall rogue services (sc delete ServiceName), and remove any malicious startup folder entries. Document each removed artifact.
  • Delete dropped payloads and tooling: Remove all files identified in investigation step 4 from disk. Search for additional copies using the file hash across your EDR fleet — a single compromised host may indicate the same payload was dropped on other systems via lateral movement. Submit hashes to your AV/EDR platform for automatic quarantine across the environment.
  • Reset credentials for all accounts that touched the affected host: Reset the password for the affected user account, any local administrator accounts on the host, and any service accounts whose credentials may have been cached or logged on to the system during the compromise window. If the host had access to a password vault, rotate all secrets it could have accessed.
  • Audit lateral movement targets: For every host the compromised machine authenticated to (identified in investigation step 6), run the same artifact checks — review autoruns, scheduled tasks, and new services. Deploy the identified payload IOCs as detections on those hosts via EDR to check for secondary infections.
  • Rotate API keys and secrets potentially exposed: Identify any secrets, API keys, certificates, or tokens stored on the compromised host (check environment variables, config files, credential manager) and rotate them immediately through the appropriate service portals. Notify application owners of any service accounts that may have been exposed.

Recovery

  • Re-image rather than clean if confidence in eradication is low: If the attacker had prolonged access (days or weeks), or if you cannot confirm all persistence mechanisms were removed, re-image the endpoint from a known-good baseline. Do not reconnect a cleaned-but-not-reimaged host to the production network until a full AV scan and autoruns review confirm it is clean.
  • Re-enable the user account only after confirming no persistence remains: Before re-enabling the account in Active Directory, verify with the host owner that the machine is clean, confirm no other sessions using this account exist on the network, and brief the user on what to watch for. Reset MFA tokens and force a password change on first login.
  • Monitor the previously affected host and user for 72 hours post-remediation: Create a temporary high-sensitivity watchlist rule in your SIEM for the affected hostname and username. Alert on any DNS query to an external domain, any new process creation from a non-standard path, and any new scheduled task or service creation for the 72-hour window following return to production.
  • Document the full attack timeline and close the incident formally: Reconstruct the full timeline from first DNS tunnel event to containment in your ticketing system (ServiceNow, Jira, etc.). Include all IOCs, affected accounts, affected hosts, and actions taken. Share sanitized IOCs with your threat intelligence feeds and ISAC if applicable.
  • Update detection rules based on new IOCs and TTPs observed: Add the specific attacker domain, subdomain pattern, process name, and any unique query characteristics to your existing detection rules as high-confidence indicators. Review your DNS resolver allowlist and sinkhole coverage, and adjust the entropy or volume thresholds based on what generated false positives or false negatives during this incident.

Stay Ahead

Get daily threat intelligence and detection playbooks.

Free. No account. No email. Follow in Feedly, Inoreader, or any RSS reader.