Sustained TXT Queries from a Finance Workstation
At a 1,800-endpoint manufacturer, Zeek DNS logs and the internal resolver feed a SIEM. A scheduled hunt surfaces WS-4471, a finance workstation whose user has been on leave for two weeks, issuing roughly 9,400 DNS queries in six hours - about 26 per minute, sustained. Almost all go to subdomains of a domain registered 11 days ago; labels average 48 characters in a base32-like alphabet; record types are TXT and NULL; responses average 180 bytes. The internal resolver forwards to two public resolvers and recursion succeeds. Nothing else in the DNS log is anomalous: no NXDOMAIN burst, no odd resolver behaviour. EDR on WS-4471 shows no unsigned binaries and no suspicious parent-child pairs, but it does show an Excel file with macros opened three days earlier. At 02:14 the same host uploaded 2.1 MB over HTTPS to a cloud VPS address that appears in no threat feed. NetFlow shows no other internal host talking to that VPS. The workstation holds finance SharePoint access and a mapped drive to the ERP file share.
1. What in the DNS and flow evidence separates tunnelling from a legitimate CDN or telemetry pattern, and what additional telemetry would you pull before declaring an incident?
Read the worked answer
What actually discriminates
- Query shape. 9,400 queries in six hours from one host, flat at ~26/min, against a single domain. Legitimate telemetry and CDN traffic is fan-out across many customers and domains, and it is bursty rather than metronomic.
- Label structure. A 48-character average label in a base32 alphabet is payload, not a hostname. Real CDN labels are short, dictionary-like, or fixed-length vendor hashes.
- Record type. Sustained TXT and NULL queries are rare. Bulk TXT is how tunnels move data out and receive short tasking; normal endpoints ask for A, AAAA, HTTPS, or SVCB.
- Response asymmetry. ~180-byte answers to nearly every query means the authoritative server answers everything - a tunnel endpoint, not a recursive cache returning NXDOMAIN or CNAME chains.
- Domain age and reach. 11 days old, no passive-DNS history, and no other client in the estate resolves it.
- Secondary channel. A 2.1 MB HTTPS upload to a VPS with no fleet-wide peers, twelve hours later, fits tasking or a fallback exfil path.
Before declaring, pull: the exact query names from resolver logs and decode the labels; Zeek dns/conn records for TTLs, answer counts, and query-response timing; proxy and firewall logs for the VPS; EDR network events and the macro document's hash and origin; DHCP and host inventory plus the leave record; passive DNS and certificate transparency for the domain; and a fleet-wide search for any other host resolving it.
The combination is strong enough to treat as probable DNS tunnelling with a secondary HTTPS channel. What is still missing - decoded payload content and whether anything on the host staged data - determines scope, not whether to act.
2. Sequence containment and evidence preservation given that the resolver cannot be blocked globally and the ERP file share is business-critical.
Read the worked answer
Order matters more than the choice of control
- Preserve first (10 minutes). Capture volatile state: memory image if you have the tooling,
ipconfig /displaydns, netstat, running processes, and the macro document. EDR containment does not destroy state; a reboot or shutdown does. Do not power off. - Contain the host, not the resolver. EDR network containment on WS-4471 blocks all traffic except the management channel while the machine stays powered and observable. Global DNS blocking is unnecessary - only one host queries the domain - and blocking at the resolver early costs you the ability to watch a beacon change.
- Protect the ERP share path. Containment already kills the SMB session. Check 5140/5145 on the file server for WS-4471 access in the last 72 hours. If the mapped drive was touched, treat it as a potential data-loss path and pull file-access auditing.
- Handle credentials. The user is on leave, so any authenticated activity is suspect. Reset the user's password, revoke sessions, and check for cached credentials or a service account the macro may use. Hunt 4624 type 3/10 from WS-4471 to other hosts.
- Then block the domain at egress, add it to threat intel, and retro-hunt 30–90 days of DNS logs for the same pattern.
Why not block first: it is fast and low-risk to the business, but it tips the operator, who may rotate infrastructure. Capturing beacon cadence and decoded query names is worth fifteen minutes - unless the tunnel is still transferring at volume, in which case block egress immediately and work from the capture already taken.
Notify the finance application owner and the ERP share owner before containment affects the workstation, since it holds a mapped drive.
3. Convert this hunt into a production detection that will not reproduce the same false-positive load, and state its validation plan and known gaps.
Read the worked answer
Do not ship 'queries > X' as a standalone rule. A single threshold on DNS volume against one domain will be dominated by endpoint agents, updaters, and CDN telemetry - the base-rate problem is the whole design constraint.
A defensible v2 scores a host/domain pair over a one-hour window, requiring at least four of:
- one host generating more than 300 queries to a single domain;
- mean label length above 25 with high character entropy;
- more than 70% non-address record types (TXT, NULL, CNAME-heavy);
- domain first observed less than 30 days ago (passive DNS or WHOIS enrichment);
- no other internal host resolving the domain.
Score rather than OR the conditions, and maintain an exclusion list for known security-agent and CDN telemetry domains - vendor-documented, owned by a named person, reviewed monthly. Hand-edited ad hoc exclusions become the blind spot an attacker inherits.
Validation: replay 90 days of resolver logs. You need two numbers - how many distinct hosts the rule fires on (should be single digits per week) and whether it would have caught WS-4471 within the first hour at 26 queries/min. Seed a purple-team test: a controlled query loop to a tunnel-shaped domain you own should fire; a normal browser session should not.
Document the gaps: DNS over HTTPS or direct-to-public-resolver traffic bypasses Zeek entirely, so add endpoint DNS telemetry or block 53 and 853 egress except to the internal resolver. Low-entropy encoding will evade the entropy component; that is tolerable only if the volume and domain-age components still fire.