4

Ran across an exploit for glibc today which involves the getaddrinfo() call for DNS resolution. I'm running Ubuntu 12.04 on two Bind9 boxes that face the internet. I'm not sure I totally understand the exploit, but it seems to be caused by a large reply from a malicous DNS server. One of the mitigations is a "firewall that drops UDP DNS packets > 512 bytes" so I've configured netfilter on the DNS servers to drop any UDP > 512 bytes coming from, or going to, port 53: -A INPUT -i lo -j ACCEPT -A INPUT -p udp --sport 53 -m length --length 511:65535 -j DROP -A INPUT -p udp --dport 53 -m length --length 511:65535 -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Is there a better way to do this with a Bind setting or anything? I've tested the rule with scapy and it does indeed block a UDP packet > 512 tossed at port 53.

UPDATED per responses: -A INPUT -i lo -j ACCEPT -A INPUT -p udp --sport 53 -m length --length 949:65535 -j DROP -A INPUT -p udp --dport 53 -m length --length 949:65535 -j DROP -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

and /etc/bind/named.conf.options

options {
   ...
   // 2016-02-17 - tmb - glibc exploit mitigation
   edns-udp-size 900 ;
   max-udp-size 900 ;
};

UPDATE 2: As pointed out by atdre below, Cloudflare tried the above technique and although the entire payload could not be transferred, memory corruption was still a possibility. I think I'll look into Unbound.

Server Fault
  • 3,714
  • 12
  • 54
  • 89

3 Answers3

6

While A firewall that drops UDP DNS packets > 512 bytes. mitigates the exploit (over UDP specifically, TCP can still be an attack vector) it's also not correct behaviour and breaks other functionality instead.

Since the introduction of EDNS0 there is no such limit in the DNS spec and you will cause breakages for valid traffic by just dropping packets.

What birdwes suggests, with configuring a resolver nameserver to limit response sizes back to its clients is a better way as clients will at least be properly notified (truncated response) as per the specs instead of just silence and eventually a timeout, but the proper solution is to install patched glibc (that's where something is wrong, the size is not wrong).

Håkan Lindqvist
  • 35,011
  • 5
  • 69
  • 94
3

If you are running bind locally, this gives you a test:

dig @127.0.0.1 tcf.rs.dns-oarc.net txt

as described here: https://www.dns-oarc.net/oarc/services/replysizetest .

You will get a reply like this:

root@myhost:~# dig @127.0.0.1 tcf.rs.dns-oarc.net txt

; <<>> DiG <<>> @127.0.0.1 tcf.rs.dns-oarc.net txt
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61575
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 26, ADDITIONAL: 27

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1024
;; QUESTION SECTION:
;tcf.rs.dns-oarc.net.           IN      TXT

;; ANSWER SECTION:
tcf.rs.dns-oarc.net.    60      IN      CNAME   tcf.x981.rs.dns-oarc.net.
tcf.x981.rs.dns-oarc.net. 59    IN      CNAME   tcf.x986.x981.rs.dns-oarc.net.
tcf.x986.x981.rs.dns-oarc.net. 58 IN    CNAME   tcf.x991.x986.x981.rs.dns-oarc.net.
tcf.x991.x986.x981.rs.dns-oarc.net. 57 IN TXT   "Tested at 2016-02-17 15:44:36 UTC"
tcf.x991.x986.x981.rs.dns-oarc.net. 57 IN TXT   "xx.xx.xx.xx DNS reply size limit is at least 991"

and you can add the bind option

options {
  ...
  edns-udp-size 1024 ;
  max-udp-size 1024 ;
};

in the file named.conf

as described here: https://labs.ripe.net/Members/anandb/content-testing-your-resolver-dns-reply-size-issues .

I would use this in conjunction with other mitigations too.

birdwes
  • 98
  • 1
  • 2
  • 12
  • I noticed you have `max-udp-size` set to 1024. Does that mean I should adjust my netfilter `--length` rules to 1023:65535 ? I'm curious because I read that the max UDP size for DNS is 512, but when I log on my netfilter rule above, I can see some packets coming in with larger sizes. `[Wed Feb 17 10:55:08 2016] 512_LIMIT: IN=eth0 OUT= ... SRC=192.12.94.30 DST=[redacted] LEN=775 ... PROTO=UDP SPT=53 DPT=1249 LEN=755 ` – Server Fault Feb 17 '16 at 16:54
  • 1
    Packet sizes can exceed 512 bytes when EDNS is enabled, which is to 4096 bytes by default in bind (named). 1024 is just a number that I chose from the link with the patches for glibc at [https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html](https://sourceware.org/ml/libc-alpha/2016-02/msg00416.html), the reason being the alternating of two buffers overflowing 2048 bytes, which can manifest the bug . The trouble with the edns-udp-size/max-udp-size "options" solution is that it only works with UDP, so something still needs to be done about TCP. – birdwes Feb 17 '16 at 17:12
  • 1
    In hindsight, perhaps a better number for both the firewall and bind would be: https://access.redhat.com/articles/2161461 - "Less than 1023" (Null termination character in C language?). I would personally make the firewall number at least two more than the bind number, so that makes the bind size no more than 1021. I have seen a source somewhere today that suggests more than 860, to still support DNSSEC. Will post when I find it, so my suggestion is 900 for bind and 950 for the firewall. – birdwes Feb 18 '16 at 00:24
  • Thanks so much for explaining. Have updated question for suggested fixes. – Server Fault Feb 18 '16 at 14:31
2

After a bit of testing, CloudFlare determined that limiting the response size of DNS packets and turning off EDNS0 support did not remediate CVE-2015-7547. You can test for yourself using the author's PoC code, available as linked gists throughout the post.

You can read about their conclusions and well as see the results of their tests here -- https://blog.cloudflare.com/a-tale-of-a-dns-exploit-cve-2015-7547/

CloudFlare says,

The only good mitigation is to run a DNS resolver on localhost where the attacker can’t introduce resource exhaustion, or at least enforce minimum cache TTL to defuse the waiting game attack.

Giving the following three useful utilities as open-source resolvers that you can install and configure:

  1. Unbound
  2. PowerDNS Recursor
  3. Knot DNS Resolver

They also go on to say,

A generally good mitigation is to shield yourself with a local caching DNS resolver, or at least a DNSCrypt tunnel. Arguably, there might be a vulnerability in the resolver as well, but it is contained to the daemon itself—not to everything using the C library (e.g., sudo).

atdre
  • 131
  • 3