T1568.002
Domain Generation Algorithms
What it is
Malware needs a way to find its command and control server, but hardcoding one fixed domain or IP address is fragile: block or seize that one address and the malware goes silent forever. A domain generation algorithm solves this by having the malware compute a long list of candidate domain names on its own, from a seed value, and try them in sequence until one resolves and answers.
The attacker only needs to register a small number of these domains ahead of time, rotating which one is active. A defender trying to block the malware would need to predict and block thousands of domains that mostly never even get registered.
How adversaries use it
Once malware with a DGA is running on a host, it periodically generates a fresh batch of candidate hostnames and queries DNS for each one, looking for a response. Most resolve to nothing, since the attacker has only registered a handful of the possible domains. When one does resolve, the malware connects to it for its actual command and control traffic.
This is attractive specifically because it is resilient. Taking down or blocklisting one domain does nothing to the algorithm generating the next one, and the malware will simply move on to trying the next candidate on its own schedule.
Detect it in Elastic
Data source: DNS query logs, or proxy access logs where egress is proxied. One client reaching many distinct hostnames under one parent, none returning a response
Key fields
A DGA client's lookups go unanswered far more often than normal traffic, since most generated hostnames are never registered. In DNS logs that shows as response code NXDOMAIN; in proxy logs it shows as requests that end without a normal response, under whatever result code that proxy records for a lookup that never resolved. Key fields: dns.question.name or url.domain (the requested hostname, keyword; count this, not url.original, which counts paths and would misread ten pages on one site as ten hostnames), dns.response_code or the proxy's own result field (the lookup's real outcome), source.ip (ip-typed, CIDR-queryable), and host.name.
Example event
{
"dns": {
"question": {
"name": "kq3vx8ztrw1m.example"
},
"response_code": "NXDOMAIN"
},
"host": {
"name": "ws-303.corp.example"
},
"source": {
"ip": "192.0.2.33"
}
}Prebuilt Elastic rule: Machine Learning Detected a DNS Request With a High DGA Probability Score (requires the DGA Detection integration); huntable directly via per-client NXDOMAIN cardinality without it
Hunt guidance
The signature is cardinality, not content. Count distinct queried hostnames per client per time window, and separately the ratio that come back NXDOMAIN. A host suddenly issuing dozens or hundreds of queries for hostnames nobody has ever seen before, most of which fail to resolve, is the pattern, regardless of what any individual hostname looks like.
Generated domain names can also stand out when you read them: atypical label length, random-looking character sequences and no dictionary words. Treat that as a secondary, confirming signal rather than the primary one. A lookup that never produced an answer is still evidence on its own: the host asked for the name, and that request is what you are counting.
In practice, count distinct queried domains per source address in a time window, and separately the share of those lookups that end without an answer. Depending on where you collect, an unanswered lookup may appear as an NXDOMAIN response in DNS logs, or as a proxy request that ended with no status code because the client gave up waiting on DNS. Normal hosts query a small, fairly steady set of domains, set by what their software actually needs to reach; a host far outside that range, especially with a high unanswered share, is the signal. Do not lean on an internal-versus-external split: where all traffic leaves through one egress point, destinations can look equally external, and query cardinality and the unanswered share are the discriminators that remain.
Ruling out legitimate activity
High-cardinality DNS querying is not unique to malware. Content delivery networks, ad and analytics networks, and telemetry or update-check SDKs embedded in ordinary software all legitimately generate large numbers of distinct, often short-lived hostnames as a normal part of how they operate.
The distinguishing signal is error rate combined with client context: legitimate high-volume DNS traffic mostly resolves successfully, while DGA traffic is defined by a high proportion of failed lookups, since only a small fraction of generated names are ever actually registered. A client that is not expected to run any of the known legitimate high-cardinality services, showing this error-heavy pattern, is a much stronger story than volume alone.
Telemetry needed
The log events that help detect this technique, from the Telemetry reference: which log source to collect, which event in it, and how to enable each one.
- ESXi and vCenter logs (the log as a whole)
- Linux audit framework (auditd)
- SYSCALL:connect SYSCALL record for connect
- SYSCALL:socket SYSCALL record for socket
- syslog / journald (auth, secure, messages, cron) (the log as a whole)
- macOS unified log (the log as a whole)
- Windows Security event log
- 4688 A new process has been created.
- Sysmon
References
Practice it
1 scenario in this catalog covers T1568.002. We don't name it, because identifying the technique is part of what a scenario grades. Explore the Range →