T1568.002

Domain Generation Algorithms

WindowsLinuxmacOS

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 proxy requests carry event.action: "tcp_miss_aborted" with no status code far more often than normal traffic, since most generated hostnames never resolve. Key fields: 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), event.action (the real outcome, since a DNS failure here often shows no status code at all rather than a clean error), source.ip (ip-typed, CIDR-queryable), and host.name.

Example event

{
  "url": {
    "domain": "example-generated-host.example"
  },
  "host": {
    "name": "proxy01"
  },
  "event": {
    "action": "tcp_miss_aborted"
  },
  "source": {
    "ip": "10.0.0.101"
  }
}

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.

Algorithmically generated names often also look different on inspection: unusual length, high character randomness, and no dictionary structure, though this is a secondary confirming signal rather than the primary one. A failed connection attempt from this activity is still meaningful evidence on its own, not a non-event just because nothing resolved.

On this range specifically, count distinct url.domain values per source.ip in a window, and separately the proportion returning event.action: "tcp_miss_aborted" (a resolution failure with no status code, since the client times out waiting on DNS rather than receiving a clean error). Normal browsing here tops out at a small, fairly consistent number of distinct hostnames per host, set by what that host's software actually needs to reach; a host far outside that range, especially with a high aborted-resolution share, is the signal. There is no internal-versus-external shortcut on this range: the whole environment sits behind one proxy to a single external segment, so legitimate and malicious destinations look equally external, and cardinality and failure rate are the only discriminators available.

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 failure 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 failure-heavy pattern, is a much stronger story than volume alone.

References

Practice it

1 scenario in this catalog covers T1568.002. We don't name it — identifying the technique is part of what a scenario grades. Explore the dashboard →