Hide and Seek in TXT Records

18. September 2020

Did you ever wondered how the “bad guys” cover things?

Some time ago John Ferrell wrote about how to hide malicious code in files looking like a good old plain text log file. Last month (August 2020) John Hammond wrote a part two. In this part he’s showing how they download additional payloads from the internet under the radar. It’s quite simple, if you know.

What’s the Problem with Payloads

So if you are writing malware you face the same problem as any software developer: You want to ship updates. But it is not that simple. If you register a domain to provide your payload it is way to easy to block this domain as a counter measure. What if you could use a domain which no one can easily block? Here comes Googles DNS service into the play. Most of you know Google’s DNS from the famous, but they also provide a HTTPS based interface:

curl -sS 'https://dns.google.com/resolve?name=weltraumschaf.de

Which will respond with:

  "Status": 0,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
      "name": "weltraumschaf.de.",
      "type": 1
  "Answer": [
      "name": "weltraumschaf.de.",
      "type": 1,
      "TTL": 592,
      "data": ""

That’s no big deal, eh? Yes it is!

Maybe you are not so familiar with DNS, but the standard provides a so called TXT Resource Record in which you can store arbitrary text. Bingo! The solution is Base64 encode your payload and store it into a TXT record:

@   IN    TXT   VGhpcyBpcyBzZWNyZXQgc2F1Y2UhCg==

I’m not sure how much data you can store in a TXT Resource Record. In the mentioned blog post they described that they only stored some IP addresses. But with Base64 encoding you can store anything in it.

The big advantage is that Google provides the API via HTTPS so inspection is not so easy. So you can use your own random hostname. Without TLS-breaking DPI this is not visible to potential victims.

Here’s an example I deployed to my DNS:

curl -sS 'https://dns.google.com/resolve?name=weltraumschaf.de&type=txt' | \
  jq .Answer[1].data | \
  tr -d '\\"' | \
  base64 -D -

Which decodes to:

This is secret sauce!
Published under the THE BEER-WARE LICENSE.
If you like what I do you can subscribe my RSS feed or follow me on Twitter.

Improve Your Documentation With Russian Roulette