Dynamic Resolution: How Hackers Implement Elusive Command and Control Infrastructure

Malware implants can call back to command and control (C2) servers in a variety of ways. Adversaries often use several layers of proxies to hide their primary infrastructure and prevent attribution. Sometimes, malware communicates with many servers instead of one outer proxy — a technique dubbed Dynamic Resolution — which makes it harder to spot C2 traffic in a network since it becomes more spread out. This also adds resilience in case the main callback channel is lost, since backup servers are available for communication. In this post, we will explore some methods attackers use to implement this technique.
The IPs and domains referenced in this post are used as random examples only.
Fast Flux DNS
When defenders analyze traffic logs for malicious activity, a key metric is the number and type of connections between a source and a destination IP. Fast Flux DNS dynamically rotates the destination IP of the C2 domain used by implants, making it harder for defenders to spot malicious network traffic and providing a fallback if the current IP is detected.
In Single-Flux DNS, a pool of IP addresses are consistently rotated as the A (IPv4) record for a single domain name (AAAA for IPv6 addresses). The record is given a short time-to-live (TTL) value, preventing downstream DNS servers from caching an address for too long.
Say the implant is programmed to use nothingsketchyatall.com for C2. Before initiating a connection, the host operating system will send a DNS query to its configured resolver, 8.8.8.8 (Google DNS). The Google DNS server has no records for nothingsketchyatall.com and requests the NS record from a .com TLD name server (j.gtld-server.net). The.com name server returns the domain’s authoritative name server and its address:
$ dig nothingsketchyatall.com NS @j.gtld-servers.net
;; QUESTION SECTION:
;nothingsketchyatall.com. IN NS
;; AUTHORITY SECTION:
nothingsketchyatall.com. 21600 IN NS ns.nothingsketchyatall.com.
;; ADDITIONAL SECTION:
ns.nothingsketchyatall.com. 15015 IN A 100.100.100.100
Since the name server is in the same zone, the TLD also returns a “glue” IP address for the name server. A glue record is needed to prevent a circular dependency, where the resolver asks the TLD name server for the NS of the domain because it needs an IP address, only to receive the name server domain, which results in the resolver asking the TLD again, since it will then need the name server’s address. The NS record does not need to be in the same zone as the domain, but can be since the NS record generally remains static in Single-Flux DNS (more on this in a bit). Now that Google DNS has the name server of nothingsketchyatall.com and the name server’s IP address, it can retrieve the nothingsketchyatall.com A record:
$ dig nothingsketchyatall.com A @ns.nothingsketchyatall.com
;; QUESTION SECTION:
;nothingsketchyatall.com. IN A
;; ANSWER SECTION:
nothingsketchyatall.com. 300 IN A 200.200.200.200
Notice how the TTL value is only 300 seconds. In five minutes, the local system’s DNS cache and Google’s cache will clear the record, and the attackers will programmatically update the A record on the name server to another proxy’s IP address.
To add another layer of complexity for defenders, attackers can also flux the IP address of the authoritative name server for the domain — otherwise known as Double-Flux DNS. Let’s take a look at an example. When Google DNS requests the NS record for nothingsketchyatall.com, the .com TLD might reply with something like this:
$ dig nothingsketchyatall.com NS @j.gtld-servers.net
;; QUESTION SECTION:
;nothingsketchyatall.com. IN NS
;; AUTHORITY SECTION:
nothingsketchyatall.com. 21600 IN NS alsonothingsketchy.com.
In this case, the name server is a different parent domain than the DNS zone (called out-of-bailiwick). Since this name server is a different parent domain, a glue record is not required, and Google DNS will need to resolve its A record like any other domain if it wants to retrieve the A record for nothingsketchyatall.com.
$ dig alsonothingsketchy.com A
;; QUESTION SECTION:
;alsonothingsketchy.com. IN A
;; ANSWER SECTION:
alsonothingsketchy.com. 300 IN A 50.50.50.50.
The A record for the name server also has a five-minute TTL value. Now, not only will the attackers be rotating the address of the C2 proxy at nothingsketchyatall.com, they will also be rotating the address of the name server that provides the address of the C2 proxy. A different DNS zone for the NS record is needed since fluxing the name server’s A record in the TLD is not possible. Domain registrars assign the NS record for a domain with the TLD, and an attacker cannot quickly automate this.
In Single-Flux DNS, attackers often use bulletproof hosting (BPH) providers as the DNS providers for their C2 proxies. While many DNS providers allow frequent changes to records via an API or other interface, BPH providers ignore abuse requests from law enforcement and other organizations, unlike mainstream providers like Cloudflare. This forces defenders to target the actual proxy server addresses to take down the C2 infrastructure.
In Double-Flux DNS, BPH providers can be used to flux the name server’s A record. The name servers themselves are most likely compromised botnet hosts running DNS software like BIND or PowerDNS. Since the actual proxy infrastructure is also needed for this operation, it’s simpler to use compromised hosts for the name servers instead of dedicated infrastructure and reduce the overhead required to perform Double-Flux DNS.
Domain Generation Algorithms
Rotating IPs are cool and all, but what happens when lookups on the domains themselves are blocked? If the attackers use limited domains, they will lose contact with their implants. To add an extra layer of resiliency, attackers may build a Domain Generation Algorithm (DGA) into malware instead of using hardcoded domains. DGAs rotate the C2 lookup domain after a period, for example, every week, adding fallback options. The algorithms have a deterministic output that can be replicated on the server-side, but is complex enough to continue indefinitely.
Below is a basic DGA written in Go that generates a new semi-random domain daily. The same domains will be calculated on the C2 infrastructure so they can be registered and assigned DNS records as needed.
// Get today's date
now := time.Now()
year, month, day := now.Date()
// Create a simple hash using XOR/bit-shifting based on today's
// date with some large multipliers to increase the bit-length
hash := uint32(year*374761393 + int(month)*668265263 + day*69069)
hash = (hash ^ (hash >> 13)) * 1274126177
hash = hash ^ (hash >> 16)
// Create a 20 character string sufficiently distributed across
// a-z using a Linear Congruential Generator seeded with the hash
var domain strings.Builder
for i := 0; i < 20; i++ {
hash = hash*1103515245 + 12345
letter := 'a' + rune(hash%26)
domain.WriteRune(letter)
}
// Even days use .us odd days use .com top-level domain
if day%2 == 0 {
fmt.Println(domain.String() + ".us")
} else {
fmt.Println(domain.String() + ".com")
}
The dates below will yield specific domains:
- July 26th 2025: orgxspahcdknaxszkrcp.us
- July 27th 2025: mvaxafcbuxyzkvohcfqx.com
- July 28th 2025: fqnuxsnipstsdyrmpgnu.us
- July 29th 2025: jutehydohozsnihqbuhu.com
A real-world DGA would more likely generate combinations of words and numbers such as 4tacosrealestate2021.com to look less suspicious.
DNS Calculation
At this point, the implant and infrastructure constantly shift domains and IP address channels, adding significant resiliency and elusiveness to the command and control traffic. The final cherry on top is to use unpredictable port numbers for new TCP and UDP connections. MITRE has documented several threat actors such as APT41, TA551, Gamaredon Group, menuPass, and others using DGAs and Fast Flux DNS, but only lists one group, APT12, as an example that has used DNS calculation.
DNS calculation uses calculations based on the IP address of the channel to determine the port number. For example, if the implant starts beaconing and DNS resolves the IP address for the C2 domain as21.64.230.78, the implant may determine the port to connect to with this formula:
port = concat(first_octet, second_octet) + third_octet - fourth_octet
port = 2164 + 230 - 78 = 2316
Using different ports for different proxies may reduce the chance of detection. However, threat actors generally tend to use standard ports for the protocol of their C2 traffic (e.g. 443 for HTTPS, 53 for DNS). Connecting to many random ports within a period might end up drawing more attention to an infected host, which is why there is probably only one group documented using this technique.
Defensive Considerations
Detecting this activity is challenging as it closely mimics how common websites utilize load balancing with CDNs. Assuming the implant has not been burned, security teams should focus on detecting anomalous connections and establishing robust baselines for endpoint traffic behavior. Threat intelligence services that perform real-time monitoring of internet connections in their clients’ networks may be able to detect Fast-Flux or algorithm-generated domains using various advanced methods. However, most of these require prolonged observation of the infrastructure. Even if a domain is suspected of being malicious, that conclusion is not made with 100% confidence. By the time a thorough investigation is completed, the channel has long since retired.