The Domain Name System (DNS) is an essential part of the Internet, which has also been overloaded with many other security-critical applications such as anti-spam defenses, routing security (RPKI), and even TLS trust bootstrap. Therefore, risking the integrity of DNS records can lead to catastrophic security failures, including fraudulent certificates being issued that can compromise the underpinning of public-key cryptography.
At the University of California, Riverside, we found the current design and implementation of modern OSes can lead to side-channel-based DNS cache poisoning attacks, namely SAD DNS (Side-channel AttackeD DNS).
What are DNS cache poisoning attacks?
The idea behind DNS cache poisoning attacks is to inject a fake response to the recursive resolver by spoofing the authoritative name server’s IP address after a non-recursive query is sent to the authoritative name server (NS). If the attack succeeds, the resolver will accept and cache the rogue record. Note that we assume the attacker is off-path, meaning they cannot sniff or rewrite the legitimate DNS traffic between the resolver and NS (otherwise it is relatively trivial to do so).
DNS messages are usually protected by two 16-bit secrets: ephemeral port number in the UDP layer, and transaction ID (TxID) in the DNS layer, which are unknown to any off-path party. To launch off-path cache poisoning attacks, the 16+16=32-bit secret must be figured out promptly. Given the small attack window (the time between when a query is sent and a response is received, usually <1s), brute-forcing 2^32 possibilities is nearly impossible (and requires at least 4 Gbps packet forwarding rate). In most cases, DNS looks safe thanks to the 32-bit secrets. However, SAD DNS can degrade it to 16-bit by inferring the ephemeral port number before brute-forcing the TxID, making cache poisoning attacks largely possible again.
How does SAD DNS work?
Listening UDP ports can usually be discovered by sending UDP probes from an arbitrary host and checking whether an ICMP port unreachable is returned (closed port) or not (open port).
Ephemeral ports can be checked similarly, but usually requires the packet coming from the remote peer of the established socket (yes, UDP can be ‘connected’ per RFC 8085). For inferring the ephemeral port opened by DNS resolvers, the UDP probes must appear to be sent from the NS. Even though this is an easy task for an IP spoofing host, learning the existence of the triggered ICMP reply is difficult since it would be sent to the ’real’ NS, instead of the attacker’s spoofed one.
SAD DNS solves this problem by inferring the open ephemeral port (by checking the ICMP reply) using a side-channel raised from ICMP global rate limiting, which is implemented in all model OS kernels, as specified in RFC 1812.
For example, Linux limits the rate of outgoing ICMP packets to 1000pps using a token bucket, which refills 50 tokens per 50ms and maxes out at 50 tokens. Each solicited ICMP message will remove one token from the bucket to be sent on the link, and an empty bucket prevents any ICMP reply. Since the bucket is shared among all IPs, including both the attacker’s spoofed IP and their real IP, they can then infer if their spoofed UDP probe solicited an ICMP by checking whether their verification probes (UDP probes sent from the real host) can get an ICMP reply or not.
Figure 2 shows the attack process. Initially, the attacker sends 50 spoofed UDP probe packets (with 50 different port numbers to scan). If any probe is sent to the correct ephemeral port (usually there is only one), the other 49 probes would solicit 49 ICMPs, resulting in the bucket containing only one token. Otherwise, the bucket would be empty after 50 ICMPs are emitted.
To observe the difference in the token bucket between these two states, the attacker sends a verification UDP probe using a real IP. If they get an ICMP back, meaning the bucket is not empty, then they can confirm there is an open port among 50 probed ports. By repeating this in binary search fashion, the attacker would eventually discover the open ephemeral port and perform the subsequent TxID brute-forcing.
What’s the mitigation?
This vulnerability is marked as CVE-2020-25705. Most popular DNS services like Google, Cloudflare, and Quad9 were vulnerable at the time we discovered SAD DNS and now most of them are patched.
Thanks to the Linux kernel team that patched this vulnerability in the icmp: randomize the global rate limiter commit by randomizing the ICMP global rate limiting counter. The patch has been applied to 5.10 and the newer kernel and propagated to all maintained LTS branches.
Other OSes such as macOS or Windows could have also patched SAD DNS without publishing the details.
Since this has little to do with DNS software, updating the kernel is likely the only way to patch SAD DNS. However, if a kernel update is not feasible, blocking outgoing ICMP port unreachable messages using iptables may also help. Enabling advanced security features like DNSSEC or DNS cookies may also help mitigate SAD DNS, and future off-path DNS attacks as well.
You can view all our related resources on SAD DNS (including the full research paper, presentation slides, and video played at ACM CCS 2020) on our website. Follow our GitHub for up-to-date research papers on this topic and many other interesting security projects from our security lab at UC Riverside.
Keyu Man is a PhD candidate at UC Riverside and advised by Zhiyun Qian.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.