logo
cd ..

dga domains: how malware finds its c2 without hardcoding an ip

Comments
3 min

dga domains: how malware finds its c2 without hardcoding an ip

imagine you write malware and hardcode your command and control server as an IP. one day someone blocks it, or it gets taken down, and every infected machine you ever compromised goes dark forever. that's a terrible business model for a criminal. so modern malware solved it with one of the sneakiest tricks in the book: instead of storing where the server is, it computes it. hundreds or thousands of candidate domains per day, and the attacker only needs to register one

dga domains: how malware finds its c2 without hardcoding an ip

a DGA (domain generation algorithm) takes a seed, usually the date, sometimes a magic number baked into the binary, and runs it through a deterministic function to spit out a list of domains. the key word is deterministic: same seed, same list, on every infected machine and on the attacker's machine too.

so today both sides compute the same 1000 domains. the attacker registers one. every infected host tries all 1000 until one resolves, and that's the live C2. tomorrow the seed changes, all 1000 domains are different, and the cycle repeats.

seed = today's date (2026-07-29)
     |
  hash function
     |
[ x8fj20dla.com, qz91mvnb.net, ... 1000 more ]
     |
     > attacker registers one of these
         bots try all of them, the one that answers wins

a tiny demo of the "deterministic" part, so the concept stops being abstract:

import hashlib, datetime

def dga(date, count=5):
    out = []
    for i in range(count):
        seed = f"{date}-{i}".encode()
        h = hashlib.sha256(seed).hexdigest()[:12]
        out.append(h + ".com")
    return out

print(dga("2026-07-29"))
print(dga("2026-04-01"))   # identical, every time
print(dga("2026-05-10"))   # tomorrow: a completely new world

that's the whole concept. the actual malware versions use the same pattern with a custom hash, and often thousands of domains per day instead of 5.

why it breaks every defense you have

  • you can't block an IP: there is no fixed IP. the domain is computed fresh each day
  • you can't take it down permanently: seize today's domain and tomorrow's is already being generated. the classic example is Conficker, which generated 250 domains a day initially and later 50,000. stopping it permanently meant predicting the domains and pre-registering them, which is exactly what the defenders ended up doing
  • blocklists lag: by the time a threat feed has today's domain, it's already the next day
  • and the attacker only has to win once: thousands of candidates, one registration, and every bot in the world finds it

how it gets caught

DGA traffic is invisible as content but loud as shape. the tells:

  • a machine doing hundreds of DNS lookups that all come back NXDOMAIN. normal computers barely ever see NXDOMAIN. a DGA bot generates a wall of them until one resolves
  • the names are high entropy: x8fj20dla.com looks like random noise. real domains are pronounceable and short
  • they arrive in batches on a schedule. every infected machine wakes up at the same time and asks for the same list, all before a single packet of real data moves

that last point is where an IDS or a DNS log actually wins: you don't need to know the domain, you need to notice a machine asking 500 questions and getting 499 "no such host" answers.

defending for real

three approaches, increasing in cleverness:

  1. NXDOMAIN monitoring: count failed lookups per client. a spike is the loudest, cheapest signal you'll ever get
  2. run the DGA yourself: if you reverse the sample and recover the algorithm and seed, you can compute future domains and pre-block them. this is what took down Conficker, and it's why some malware uses a secret seed and a date nobody can guess
  3. dictionary DGAs exist as a counter: instead of random strings, they build domains from word lists, so they look like best-mail-service.com. lower entropy, harder to spot. the entropy heuristic weakens, so you're back to volume and NXDOMAIN patterns

the recap for that post :

  • a DGA computes candidate C2 domains from a seed (usually the date), so malware never hardcodes an address
  • attacker registers one out of thousands, bots try them all until one answers
  • no fixed IP means no easy block, and takedowns only work until tomorrow's list generates
  • detect by shape: NXDOMAIN floods, random-looking names, batch lookups on a schedule
  • defend with failed-lookup monitoring, or reverse the algorithm and pre-register the future domains