source: npl/internetserver/djbdns/patches/0002-djbdns-misformats-some-long-response-packets-patch-a.diff @ 720681d

Last change on this file since 720681d was 37aaf89, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

djbdns patches, so it works correctly with twitter etc

  • Property mode set to 100644
File size: 5.2 KB
RevLine 
[37aaf89]1Description: djbdns misformats some long response packets
2 The DNS protocol restricts name compression to point into the first
3 16384 bytes of a packet.  Line 18 of response.c from djbdns 1.05
4 directly references this, but response_addname() in the same file does
5 not enforce this at all.  The consequence of this is that names in
6 very large DNS packets may be mangled, and clients may misparse the
7 packet.
8 .
9 Because this email is somewhat long, I'll state up front you can find
10 a patch for this issue at the bottom of this email or at:
11     http://shinobi.dempsky.org/~matthew/djbdns-bug/patch
12 .
13 To help demonstrate this bug, I've constructed an example attack.  In
14 this scenario, there's a .foo TLD operated using tinydns and axfrdns
15 (to support DNS queries over TCP; AXFR support is not required).  The
16 attacker has registered x.foo and is allowed to upload NS records for
17 x.foo and A records for names within the x.foo domain.  However,
18 because of the aforementioned bug, this attacker can construct a
19 record set that causes the .foo servers to respond to queries asking
20 about names within the x.foo domain with poisonous records for names
21 outside of x.foo.
22 .
23 Using tinydns-data and tinydns-get from stock djbdns 1.05, you can
24 reproduce this as follows:
25 .
26     $ curl -O http://shinobi.dempsky.org/~matthew/djbdns-bug/data
27     $ grep -c -v -e '&x\.foo::' -e '^+[^:]*\.x\.foo:' data
28     0
29     $ tinydns-data
30     $ tinydns-get a www.x.foo | grep ': foo '
31     additional: foo 8388608 NS a.ns.bar
32     additional: foo 8388608 NS b.ns.bar
33 .
34 (With the patch I linked above, no records outside of x.foo will be
35 served.  It's also worth noting the printpacket_cat() routine
36 tinydns-get uses for pretty printing the response packet is much
37 stricter about parsing than dnscache's parser is; e.g., it rejects
38 packets with extra trailing bytes and records with bad rdlength fields
39 on known record types.)
40 .
41 If a victim using dnscache now makes an A query for www.x.foo,
42 dnscache will save the poisoned records, and begin contacting the
43 attacker's nameservers for all .foo requests.  (The response will be
44 over 512 bytes long, so dnscache will have to retry the query over
45 TCP, which is why axfrdns is necessary too.)
46 .
47 Now, admittedly if you peek at data, you'll see the supplied records
48 exceed what most TLDs probably allow: there are redundant NS records,
49 there are very long names (but still within the allowed limits of the
50 DNS protocol), names use non-printable characters, there are over 100
51 records totalling about 24K of storage.  However, neither the djbdns
52 documentation nor standard practice warn potential .foo administrators
53 that their domain will be at risk for poisoning if they were to add
54 support for glue record sets.  (Standard practice only warns that such
55 absurd records can negatively impact x.foo, not .foo as well.)
56 .
57 A perhaps more reasonable scenario is that the .foo servers fetch the
58 contents of the x.foo domain over AXFR (removing any records from
59 outside of x.foo) and then serve the records themselves.  axfr-get,
60 the AXFR client from djbdns, would handle the above data set fine.
61 .
62 In looking for a real life example of this latter scenario, I found
63 freedns.afraid.org.  They allowed me to register burlap.afraid.org and
64 set it up as an AXFR slave to my personal server.  I have not explored
65 what limits they place on imported records, and their website states
66 they're using BIND, but assuming they're not too limiting and were to
67 instead use tinydns/axfrdns/axfr-get, it would be possible for me to
68 trick any dnscache that queries for www.burlap.afraid.org into
69 contacting another set of nameservers for all of afraid.org's DNS
70 traffic.
71 .
72 There's a similar service everydns.net.  They do claim to use tinydns
73 (and so I assume axfrdns and axfr-get) and also provide AXFR slave
74 support, but they did not allow me to register burlap.everydns.net.
75 If they did, it would probably be possible to similarly poison
76 everydns.net.
77 .
78 I've tried to search for previous reports of this issue more
79 thoroughly than the last bug I mentioned to the list, and I haven't
80 found any mention of it yet.  I emailed Dan earlier today when I first
81 began to suspect this bug was 'exploitable' to clarify his definition
82 of a 'security hole' in djbdns.  I think the afraid.org example is a
83 reasonable use case where this bug would violate afraid.org's security
84 constraints if they were to instead use djbdns.
85 .
86 Any thoughts from the list on this bug?  (Except from Dean Anderson;
87 I'm sure he'll spend the next 3 weeks now arguing I'm a blackhat
88 hacker while refusing to look at the patch or sample data file because
89 my web server might hack his computer.)
90Author: Matthew Dempsky <matthew@dempsky.org>
91Date: Mon, 2 Mar 2009 04:46:05 +0000
92Last-Update: 2020-07-26
93
94diff --git a/response.c b/response.c
95index ba90c89..33b2fb1 100644
96--- a/response.c
97+++ b/response.c
98@@ -34,7 +34,7 @@ int response_addname(const char *d)
99         uint16_pack_big(buf,49152 + name_ptr[i]);
100         return response_addbytes(buf,2);
101       }
102-    if (dlen <= 128)
103+    if ((dlen <= 128) && (response_len < 16384))
104       if (name_num < NAMES) {
105        byte_copy(name[name_num],dlen,d);
106        name_ptr[name_num] = response_len;
Note: See TracBrowser for help on using the repository browser.