How to spot DNS tunnelling in a PCAP
DNS is allowed out of almost every network, so it is a tempting channel for smuggling data. The trick is to encode the data into the names being looked up and have a server you control answer. It works, but it leaves marks no ordinary lookup makes.
PCAPNG Analyzer Pro checks every capture for this. Very long names, unusually many unique names and random-looking labels are flagged with example names, and so is a high rate of failed lookups. On our test capture with a tunnel, the long-name and random-label findings both fired.
See a sample incident report →1. How DNS tunnelling works
The attacker registers a domain and runs its authoritative name server. Software on the compromised host encodes data, typically as base32 or hex, into labels: mzxw6ytboi4dq.1.t.example. Your resolver dutifully forwards each lookup to the attacker's server, which decodes the name and answers. A TXT, NULL or CNAME answer can carry commands or data back.
Every lookup must be a new name, or your resolver would answer from its cache and the data would never arrive. That requirement, plus the limited room in each name, shapes everything below.
2. Look for long names
A DNS name can be up to 253 characters, in labels of up to 63, and tunnels use as much of that as they can. Ordinary names are mostly short. List the longest names queried:
tshark -r capture.pcapng -Y "dns.flags.response == 0" -T fields -e dns.qry.name \
| awk '{ print length($0), $0 }' | sort -rn | uniq | head -20
Long names on their own are a weak signal: some CDNs and security products use long encoded names too. What matters is long, random-looking labels that keep changing under the same parent domain:
73 zt7tnlkknm5xj3jlddmutadxec23rkpsd7ggh75ybqsgqh3v.126.t.exfil-test.example
3. Count unique names per domain
Because every lookup has to be new, a tunnel produces hundreds or thousands of different names under one domain. Count unique names by their last two labels:
tshark -r capture.pcapng -Y "dns.flags.response == 0" -T fields -e dns.qry.name \
| sort -u | awk -F. '{ print $(NF-1) "." $NF }' | sort | uniq -c | sort -rn | head
In a test capture with a tunnel sending 6 KB, its domain had 200 unique names, while every ordinary domain had one or two. Two labels is a rough cut: for names under country suffixes such as .co.uk, take three. Then see which host made the lookups:
tshark -r capture.pcapng -Y 'dns.flags.response == 0 && dns.qry.name contains "exfil-test.example"' \
-T fields -e ip.src | sort | uniq -c
4. Check record types and volume
Most lookups ask for A, AAAA or HTTPS records. Tunnels favour TXT (16), NULL (10) and sometimes CNAME or MX, because those can carry more data back. Get a breakdown by type with:
tshark -r capture.pcapng -q -z dns,tree
Then look at the TXT and NULL queries directly: dns.qry.type in {16, 10}. Also compare volume per client: one host sending thousands of lookups to one domain, steadily or in bursts, is unusual for anything but a tunnel or a misbehaving application.
5. Confirm a suspect domain
- Look at the labels. Base32 uses only letters and the digits 2 to 7; hex uses 0 to 9 and a to f. A sequence number in the name, like the
.126.above, shows data being sent in order. - Look at the answers. Filter the responses for the domain and read the TXT data or CNAME targets. Encoded text coming back is a command channel.
- Check the timeline. Did the lookups start with a particular event, such as a download or a logon? Do they run at night?
- Check the domain. Its age and owner, looked up by hand, and whether your network has used it before.
6. Rule out legitimate uses
Some legitimate software also encodes data into DNS names:
- Anti-virus and reputation services look up file hashes or URLs as DNS names.
- Email blocklists and anti-spam checks query an IP address or domain under the list's domain.
- CDNs, telemetry and tracking services generate unique subdomains per session.
- Some VPN and captive-portal products tunnel over DNS deliberately.
Identify the parent domain's owner before drawing conclusions. A known vendor's domain with long names is normal; an unfamiliar domain with high volume from a single host is not.
DNS-over-HTTPS and DNS-over-TLS hide lookups inside encrypted connections, and a tunnel using them looks like ordinary HTTPS. If browsers or malware can reach public DoH resolvers directly, block that and force DNS through resolvers you can monitor.
Manual method vs PCAPNG Analyzer
Manual method
- List the longest query names.
- Count unique names per parent domain.
- Break down query types and volume per client.
- Read the labels and answers for a suspect domain.
- Identify the domain's owner and rule out vendors.
With PCAPNG Analyzer
- Upload the capture.
- Review the DNS tunnelling findings, each with example names, and the failed-lookup finding.
- Use See queries and See answers to read the names and responses, then add confirmed domains to a threat-intel list.
The long-name finding flags three or more names over 70 characters, and the unique-name finding flags a capture with more than 500 distinct names; both thresholds are adjustable in Settings → Detection Rules. The randomness finding scores the labels of each name (those of four characters or more) by entropy, which measures how evenly they use their characters, and flags names whose most random label exceeds 4 bits per character: long encoded labels reach that, and ordinary words can’t. On a test capture with a tunnel, the long-name and random-label findings both fired. Like every finding, they are leads: the domain's owner decides whether it's a tunnel or a vendor.
Watch what leaves through DNS
Flag long, random and high-volume lookups in every capture, while the capture stays on your own computer or server.
Compare Free and ProSelf-host it