We have been getting questions about “DNS Server Cache Snooping Remote Information Disclosure” attacks lately, mostly coming from reports generated by one very popular security scanner:
DNS Server Cache Snooping Remote Information DisclosureSynopsis:
The remote DNS server is vulnerable to cache snooping attacks.Description:
The remote DNS server responds to queries for third-party domains that do not have the recursion bit set.
This may allow a remote attacker to determine which domains have recently been resolved via this name server, and therefore which hosts have been recently visited.
For instance, if an attacker was interested in whether your company utilizes the online services of a particular financial institution, they would be able to use this attack to build a statistical model regarding company usage of that financial institution.
Of course, the attack can also be used to find B2B partners, web-surfing patterns, external mail servers, and more.Note: If this is an internal DNS server not accessible to outside networks, attacks would be limited to the internal network.This may include employees, consultants and potentially users on a guest network or WiFi connection if supported.Risk factor:
MediumCVSS Base Score:
5.0CVSS2#AV:
N/AC:L/Au:N/C:P/I:N/A:NSee also:
http://www.rootsecure.net/content/downloads/pdf/dns_cache_snooping.pdfSolution:
Contact the vendor of the DNS software for a fix.
So what is this about?
The idea behind this “attack” is to find out whether a given recursive DNS server has been asked to resolve a given domain name recently. This might in theory be used by an authorized user to know which domains would be worth targeting for mis-typing attacks.
It cannot, however, be used to get the whole content of the cache since one needs to know which domains to query, and of course can’t be used either to know who requested that domain.
How does this work?
It works by exploiting the fact that DNS resolvers do not perform actual resolution for every query they get, instead they all rely on one or several caches, allowing them to remember the responses they have recently received for a certain time, up to the “TTL” value of the response. So if we can determine that a given domain is in the cache, we know that it was queried at most “TTL” seconds ago.
The easiest way to determine if a recursive server has a given domain in cache is to ask: sending a DNS query with the recursion desired bit cleared (RD=0) will only return results from the resolver cache, as per RFC 1034. If information is available about the requested name and type, it is returned, otherwise an empty ‘No Error’ answer is sent.
Should the server refuse to answer these queries, it is also possible to know whether an answer comes from the cache by looking at the TTL returned by the recursive server for a RD=1 request, and comparing it to the original TTL returned by a name server authoritative for that domain. If the TTL returned by the recursor is equal to the one returned by the authoritative server, it was likely not in cache, or was cached less than a second ago. Otherwise it comes from the recursor cache.
We could also precisely measure the time taken by the server to respond, since in the absence of a cached answer the recursive server would have to contact an authoritative server over the network, likely increasing the response time by several milliseconds.
Why does the Recursion Desired
feature exist in the first place?
That feature is an integral part of the DNS protocol, as described in RFC 1034, in particular for communication between a recursive server and an authoritative server, where recursion is indeed not desired. As some servers historically provided both authoritative and recursive services, it still makes sense today to be able to distinguish the client’s expectations and to advertise the server capabilities.
It should also be noted that it is extremely useful to be able to use RD=0 queries to remotely inspect the content of the cache for a given name when troubleshooting operational issues in production. The alternative would require connecting to the running recursor process using rec_control
and dumping the whole cache.
Mitigations
The first method might be mitigated by refusing RD=0 queries, for example using dnsdist:
addAction(NotRule(RDRule()), RCodeAction(DNSRCode.REFUSED))
It might however break existing clients and setups, since the RD=0 behaviour has been relied on for decades. Moreover, there is no way to mitigate the second and third ones without violating fundamental DNS specifications and impacting performance.
Therefore our recommendation is to simply ignore this “issue”, since there is no clear threat-model where it is actually relevant. This is also the conclusion that the fine folks of ISC reached regarding their BIND DNS server.
Update (July 2024)
Because this issue kept coming up, we decided to add a new Recursor setting called allow-no-rd, which allows such RD=0 queries. This setting is available since version 5.0.0 and turned off by default, disallowing RD=0 queries.