Blog: How-Tos

It’s always DNS, here’s why…

David Lodge 16 May 2023

Introduction

There’s an old adage in network and Internet support: When something breaks in any network “it was DNS”.

Sadly it’s usually true.

…or at least it is when you have certain timeouts, or when a company you used to work for moves from the stable Unix based DNS to a Windows based one and the Windows administrator doesn’t understand about double reverse DNS lookups (not that it’s been annoying me for 20 years, oh no).

There’s a haiku by @broskiFGC that captures it beautifully:

It’s not DNS
There’s no way it’s DNS
It was DNS

DNS, or Domain Name System is one of the ancient protocols that modern networking relies on. It was first outlined in RFC 882 and RFC 883, written back in November 1983. It took four years before the technical details were written into RFC 1035 in November 1987.

In 1987 networks were totally different, where generally only servers would be connected to the networks with trusted administrators, so the design was about routing to the right place to get a trusted response. Security concepts such as encryption or verifiability of data were not considered.

The protocol underlies nearly every transaction across modern networks, whether emailing or web browsing, or using other protocols that use a name for a destination.

DNS (mostly) uses UDP as its transport protocol, this allows requests to be quick and use fewer network resources. It can perform some queries over TCP (such as zone transfers) where needed.

Risks

This led to a plethora of DNS attacks, mostly about providing a custom answer to a DNS request or DNS cache poisoning which could be manipulated by a malicious user to provide the wrong answer and manipulate traffic. The lack of encryption meant that it could be possible to track the requests and identify destination.

The ongoing move towards encrypted and verified services and using switches instead of hubs has reduced this risk somewhat. But the lack of encryption and making requests to standard servers have introduced privacy risks, after all if you’re broadcasting a request on a wireless network to a dodgy website, then anything can listen in to that request and draw conclusions.

As a lot of places allow DNS traffic, it is a common option to use as a tunnel for C2 networks, or for transferring date into or out of a network; usually using text (TXT) records such as:  https://www.pentestpartners.com/security-blog/cant-get-data-onto-that-machine-download-a-tunnel-client-over-dns/

Securing DNS

And here we get to the more modern section, how do we make DNS more secure? There are three main problems with the original DNS protocol:

  • Problem 1: It is unencrypted and easy to sniff by intercepting content
  • Problem 2: There is no cryptographic signature, so it is easy to spoof
  • Problem 3: There is a privacy risk that the owner of the server can track your requests

Problem 3 is hard to fix in the current environment, meaning that if your ISP logs your requests, they can know which names an IP address has requested. These have been requested in criminal investigations in the past; but there is a caveat – a request for the name of a server does not mean that the requester has visited the server. You could stop your ISP knowing this information by using a third-party DNS service, but that just means someone else gets the DNS requests.

There are services which promise not to log DNS requests, such as FreeDNS; this can mitigate that risk a lot.

Fixing problems 1 and 2 though is complex, and there are a few protocols out there that are in use and can implement controls. There is a lot of FUD about securing DNS in the industry, just because your domain does not support DNS does not mean it is instantly hackable. Enhancing DNS to include encryption and verification to data is important, but in terms of real risk it sits a long way below patching your servers and securing TLS.

2019 saw the creation of a proposed protocol, known as Anonymized DNS. This was conceived by the DNSCrypt project and intended as an extension to DNSCrypt (see later) but can work over other naming protocols. This uses a relay to broker the encrypted request so that a compromise of both the broker and server is needed to identify who made a specific request.

Validating your records, with DNSSEC

DNS Security extensions (DNSSEC) was first defined in RFC 2065 back in January 1997 and has had many updates since then. It allows a domain to provide a public key that can be used as a trust anchor to validate a resolving server as being valid for that domain.

DNSSEC works by adding a record of type RRSIG to all responses. This record is the signature for that response; the signature can be checked against the domain’s public key which is returned by requesting a DNSKEY record from the domain.

We can see this by preforming queries using and not using DNSSEC, from the Linux command like:

The resolver can then traverse the domain tree to the root entry (e.g. pentestpartners.com would need to be validated in three zones: pentestpartners.com, .com and .) to ensure that there’s a chain of trust all the way back to the root. The root and major TLDs have valid DNSKEYs.

It should be noted that at the time of writing most client operating systems do not use the DNSSEC extensions (systemd-resolved on Linux can do it, but it is disabled by default on most distributions) so this is of little use.

DNSSEC also has an interesting method to prove that the resolver is valid for a non-existent domain. It uses a record type, NSEC to show the previous and next domains. Of course, it was quickly realised that you could perform domain discovery using these records. So, a further version was created using hashed domain names a new NSEC3 record type. Of course, with modern GPUs the hashes can be cracked, so this could also be used to enumerate valid domains.

This is not to say that implementing it is a waste of time: DNS requires replication and it is useful for DNS servers to be able to validate any content that it passes on.

Encryption

So, we have a solution to problem 2; even though it’s not used as much as it can be. Problem 1 is where it gets complex, we have multiple different schemes to encrypt DNS traffic depending on the transport in use, it all sort of follows this xkcd cartoon:

DNSCrypt

DNSCrypt came out of the OpenBSD developers back in 2008, with version 2 following in 2013. This provides an encrypted protocol which uses public-private key encryption to authenticate the server and pass a shared key which can be used to encrypt the query and response.

This sounds similar to TLS but isn’t quite the same as the overheard of the protocol is less to aid transport over UDP. The protocol is transported over 443/udp and optionally over 443/tcp

There has been little uptake of DNSCrypt from commercial operating systems. It is possible to set up a proxy, but this requires effort and is not simple for the average user.

DNSCurve

Another early method for encrypting DNS data, designed in 2009. It uses Curve25519 elliptic curve cryptography and MAC to encrypt DNS question and response block.

DNSCurve has been implemented in many tools, but the main use was OpenDNS, who have since moved over to DNSCrypt.

DoT / DoH / DoQ

The final way of adding encryption is to use an encrypted channel to pass the normal protocol over it, similar to how HTTP used SSL and then TLS to provide an encrypted layer. The most common are listed here.

DNS over TLS (DoT)

The simplest way of doing this was to munge a DNS together with the well use TLS protocol and this was specified in RFC 7858 back in May 2016.

DoT uses a different port (853/tcp) as a transport but once the TLS handshake has been performed it is basically the same protocol.

DNS over HTTPS (DoH)

DNS over HTTPS got know as both Chrome and Firefox decided to support it, allowing it to be configured instead of traditional DNS. Like DNS over TLS, this uses the standard DNS protocol but transports it over an HTTPS connection.

Annoyingly the protocol just sends the base64 encoded DNS question as a parameter to the API and returns the binary response, which seems sort of wasteful.

This protocol has the nice side effect that most of the DoH providers also have endpoints which can export the results as JSON, making it easier to integrate with a web frontend. For example:

DNS over QUIC (DoQ)

Okay hands up who’s heard of QUIC? I’m not surprised, it’s sort of the new kid on the block, QUIC, or Quick UDP Internet Connections, is a layer 4 protocol (i.e. on the same level as TCP or UDP) which is similar to UDP but with added multiplexing and baked in encryption. It is mostly used by Google services and can be seen if you sniff the network whilst running Chrome.

DoQ takes advantage of the multiplexing and encryption within QUIC, resulting in requests with fewer overheads. This is likely the version of DNS that will get more common in the near future.

Other Name Services

Multicast DNS (mDNS)

Originally proposed back in 2000 and published in RFC 6762 in February 2013. Multicast DNS is designed to aid zero configuration systems and underpins DNS Service Discovery (DNS-SD).

It differs from normal DNS as it multicasts its packets, so doesn’t need to have a DNS server configured. This obviously restricts its useful to the local network. It works on the address and port 224.0.0.251:5353/udp or ff02::fb:5353/udp. It can also work through Ethernet frames.

It mostly uses the data format of DNS, but with some slightly modified records.

On modern networks mDNS can be seen everywhere, being used to configure printers, ChromeCast devices, smart speakers and similar IoT devices. It’s often interesting to sniff the network looking for mDNS requests.

Link-Local Multicast Name Resolution (LLMNR)

LLMNR is very similar to mDNS, using multicast and the DNS protocol; but talking to 224.0.0.252:5355/udp or ff02:0:0:0:0:0:0:1:3:5355/udp.

It was defined in RFC 4795 and was mostly used by Windows as a replacement for the NetBIOS name resolution.

Its use is being phased out in favour of mDNS.

Conclusions

Mapping a name to an address is a complex business which can cause serious impacts if something goes wrong. Although the initial protocol wasn’t designed with security in mind, extensions are in place to apply some form of protections.

Be aware of bad advice. If you don’t implement DNS security you are not opening a massive hole in your network.

Implementing DNSSEC is not difficult and it can be beneficial overall. There are gotchas that can introduce some risk to the DNS configuration if best practices are not followed.

There is no expectation of privacy with DNS. If the content of the requests is encrypted then your resolver still knows what has been requested. There are ways of securing this by both encrypting the data and/or creating some sort of privacy proxy; whether this is worthwhile implementing or whether another mechanism (e.g. a VPN or TOR) is used, depends on the situation and the desired privacy level.