DNS as a Bidirectional Communication Protocol, What? - Part 1 - The Theory

This is the most click-baiting sounding title I know.. but strap yourself in for a very intense look into some of the idea's my brain comes up with.

Where did this idea come from?

Recently I've been doing some network segmenting for my devices at home and as part of this there are a number of devices which often require DNS access otherwise they just stop responding, however you can sever their internet access just fine. This could be by-design that the device assumes inability to successfully resolve DNS=no internet, I think this logic isn't flawed in itself however in my experience the devices don't recover when DNS comes back, but I digress.

This got my hackerman brain thinking, can you use DNS queries as a means for bidirectional communication?

Why are you even entertaining the idea Corey?

I have a bit of an interest in Cyber Security in general, I've watched Mr Robot and I'm a bit of an expert! No, not really but a boy can dream. At this point in time I'm just a tinkerer.

To understand why this could be such an interesting attack method is understanding how organisations setup their infrastructure. Hint: It's similar to my network segmentation I did for IoT devices. In an ideal world your server (and other core components) infrastructure does not have internet access, this greatly reduces your attack surface area, you'd then have a case-by-case basis to allow what traffic is required and you've greatly improved your security. But what do almost all core infrastructure still need access to? DNS. And more importantly, most DNS servers will resolve external domains, even internal DNS servers will still forward queries upstream if they don't have the record cache'd (you'll see why this is key later).

Understanding how DNS works

I'm not going to be able to do a better job of explaining DNS than what Cloudflare has done in their page DNS server types. I would recommend reading this page if you're not too sure to help understand how using DNS might be plausible as a directional communication protocol.

The Theory

Requirements

  • A client to perform a DNS request that none of its nameservers upstream have cache'd so it asks the authoritative nameserver to answer the query.
  • Access to authoritative nameservers
  • A domain that I control

Uploading Data Example

1.Choose a sub-domain that looks somewhat legitimate
cdn.domain.com
2. Encode some data, maybe base64?
"Hello World, this is a test!" encodes to SGVsbG8gV29ybGQsIHRoaXMgaXMgYSB0ZXN0IQ
4. Use a unique identifier for the payload
img5
6. Split DNS queries into appropiate sized sub-domains to not raise many alarms when a human is viewing logs.. Maybe including sequence and total so we don't have to rely on timers
Eg: Splitting the above base64 into four segments gives us
SGVsbG8gV
29ybGQsIHR
oaXMgaXMg
YSB0ZXN0IQ
The above with the identifier, sequence and count would look like
img5-1-4-SGVsbG8gV.cdn.domain.com
img5-2-4-29ybGQsIHR.cdn.domain.com
img5-3-4-oaXMgaXMg.cdn.domain.com
img5-4-4-YSB0ZXN0IQ.cdn.domain.com

5. Capture authoriative nameserver logs for queries
This should be easy enough with Bind9
7. Re-assemble data from DNS queries on our authoriative nameserver
Since we've been given all the right data even if we received them out of order the sequence and total will let us easily reassemble
9. Decode base64 data
Decoding will show us the message "Hello World, this is a test!"
11. Done??

Now I know what you're thinking, upload of data looks easy enough, how are you going to download data? Well..

Downloading Data Example

I think the thing to remember here is every query HAS to be unique otherwise servers will cache and we won't receieve "timely" results, and I say "timely" because this isn't fast by any means. The best method I can think of is that the client sends an ID that the nameserver can use to send data back.

  1. Client performs a query stating what their next query will be
    upload-5b3c.cdn.domain.com
    Where 5b3c is the unique ID
  2. Wait X amount of time
    2 mins, might not even need that long
  3. Then the nameserver has to create a DNS entry using the ID, the result for the dns entry should specify the total queries to perform
    DNS entry created on nameserver for 5b3c.cdn.domain.com - This query will return the result: 5b3c-4.cdn.domain.com - This means we should perform 4 queries to get our payload
  4. Nameserver should also create 4 DNS entries with a CNAME record of the payload
    Using the 4 segments of the base64 from previously we'd have the entries:
    5b3c-1-4.cdn.domain.com CNAME 5b3c-1-SGVsbG8gV.cdn.domain.com
    5b3c-2-4.cdn.domain.com CNAME 5b3c-2-29ybGQsIHR.cdn.domain.com
    5b3c-3-4.cdn.domain.com CNAME 5b3c-3-oaXMgaXMg.cdn.domain.com
    5b3c-4-4.cdn.domain.com CNAME 5b3c-4-YSB0ZXN0IQ.cdn.domain.com
  5. The client device will then perform multiple DNS queries starting with checking our ID for how much total queries to run, querying 5b3c.cdn.domain.com will give us a CNAME record of 5b3c-4.cdn.domain.com which we know means it has 4 segments
  6. We then perform the 4 queries 5b3c-1-4.cdn.domain.com, 5b3c-2-4.cdn.domain.com, 5b3c-3-4.cdn.domain.com and 5b3c-4-4.cdn.domain.com and each one will give us their respective CNAME record which contains a part of the base64 encoded message
  7. We then client-side reassemble the 4 segments
  8. Decode the base64 and we get the message "Hello World, this is a test!"
  9. We have now received a payload only using DNS queries

How is this bidirectional?

Well... If you had the client device send a new unique ID every 5 minutes the nameserver would have the ability to grab the latest ID, create a new record telling it prepare to get X amount of queries and then that's bidirectional in combination with the uploading data method. You could probably extend this a bit further and have an acknowledgement step from both sides otherwise retransmit with a new ID.

Why use authoritative nameservers?

That is a very valid question, we could in fact have the client device query a nameserver we control, however it's common and good practice to only allow your DNS servers to perform DNS queries and then having a NAT loopback rule to enforce this, using uncache'd DNS queries that have to talk to the authoritative DNS server means we can use any DNS server in the world (permitting it forwards un-resolved queries upstream). But even more importantly is we can use the already configured DNS server on the target device.

Potential roadblocks

Any DNS filtering for newly observed domains, need to investigate this a bit more.

So, what do you think, is this actually plausible? What have I missed? What can I do better? Has it already been done?? Stay tuned for Part 2 where I attempt to actually do it

Subscribe to Corey Easton's Blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe
DISCLAIMER
Opinions expressed here are my own view.