ns1.greatdomains.com - DNS on the Wild ( and Wacky ) Frontier

Ted_Rule at flextech.co.uk Ted_Rule at flextech.co.uk
Fri Oct 13 14:28:41 UTC 2000




Some further details of a DNS oddity found lurking on ns1.greatdomains.com.

Since last posting a broken dig to the mailing list, I've been able to make some
more complete decodes of their broken DNS "server" implementation, and potential
issues which may arise with bind9 interoperability.

A potential contact point for anyone wishing to make further representations to
GreatDomains
to correct their server/spoofer is:


( Loring Rose <lrose at greatdomains.com> )
Loring Rose, Network Administrator
GreatDomains.com

The first problem encountered was that dig was apparently unable to decode their
server's
responses. As shown below, it's actually only dig from the bind-8.2.2-P5 kit
which has a problem;
perldig ( from the Net::DNS contrib demo kit ) and nslookup and bind8 itself
appear to "correctly"
decode the packet.

Herein follows a dig / perldig / nslookup
============================================

$ dig @ns1.greatdomains.com eve1.net a

; <<>> DiG 8.2 <<>> @ns1.greatdomains.com eve1.net a
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ns_initparse: Message too long
;; Total query time: 534 msec
;; FROM: homer.flextech.co.uk to SERVER: ns1.greatdomains.com  207.171.44.100
;; WHEN: Fri Oct 13 14:27:18 2000
;; MSG SIZE  sent: 26  rcvd: 51

$ perldig @ns1.greatdomains.com eve1.net a
;; Answer received from 207.171.44.100 (51 bytes)
;;
;; HEADER SECTION
;; id = 46713
;; qr = 1    opcode = QUERY    aa = 1    tc = 0    rd = 0
;; ra = 0    rcode  = NOERROR
;; qdcount = 1  ancount = 1  nscount = 0  arcount = 0

;; QUESTION SECTION (1 record)
;; eve1.net.    IN      A

;; ANSWER SECTION (1 record)
eve1.net.       3600    IN      A       207.171.44.105

;; AUTHORITY SECTION (0 records)

;; ADDITIONAL SECTION (0 records)
$ nslookup
> server ns1.greatdomains.com
Default Server:  ns1.greatdomains.com
Address:  207.171.44.100

> set d2
> eve1.net
Server:  ns1.greatdomains.com
Address:  207.171.44.100

;; res_nmkquery(QUERY, eve1.net, IN, A)
------------
SendRequest(), len 26
    HEADER:
        opcode = QUERY, id = 56858, rcode = NOERROR
        header flags:  query, want recursion
        questions = 1,  answers = 0,  authority records = 0,  additional = 0

    QUESTIONS:
        eve1.net, type = A, class = IN

------------
------------
Got answer (51 bytes):
    HEADER:
        opcode = QUERY, id = 56858, rcode = NOERROR
        header flags:  response, auth. answer
        questions = 1,  answers = 1,  authority records = 0,  additional = 0

    QUESTIONS:
        eve1.net, type = A, class = IN
    ANSWERS:
    ->  eve1.net
        type = A, class = IN, dlen = 4
        internet address = 207.171.44.105
        ttl = 3600 (1H)

------------
Name:    eve1.net
Address:  207.171.44.105

===============================================================================

At the stage of my previous posting , I was unable to proceed beyond the hex
dump of the packet,
as I hadn't realised that both perldig and nslookup could decode the packet.

To further understand why dig couldn't parse the packet, a critical test was
digging for an MX record.
Because the server has no MX records "listed" and doesn't really support
RFC2308/NCACHE, it transpires
it returns a packet with zero answers in the ANSWER/AUTH/ADDITIONAL Sections.

$ dig @ns1.greatdomains.com eve1.net mx

; <<>> DiG 8.2 <<>> @ns1.greatdomains.com eve1.net mx
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ns_initparse: Message too long
;; Total query time: 547 msec
;; FROM: homer.flextech.co.uk to SERVER: ns1.greatdomains.com  207.171.44.100
;; WHEN: Fri Oct 13 14:33:51 2000
;; MSG SIZE  sent: 26  rcvd: 27

$ perldig @ns1.greatdomains.com eve1.net mx
;; Answer received from 207.171.44.100 (27 bytes)
;;
;; HEADER SECTION
;; id = 5359
;; qr = 1    opcode = QUERY    aa = 1    tc = 0    rd = 0
;; ra = 0    rcode  = NOERROR
;; qdcount = 1  ancount = 0  nscount = 0  arcount = 0

;; QUESTION SECTION (1 record)
;; eve1.net.    IN      MX

;; ANSWER SECTION (0 records)

;; AUTHORITY SECTION (0 records)

;; ADDITIONAL SECTION (0 records)

The fault here is that the response packet is one byte larger than the query -
because
no ANSWER/AUTH/ADDITIONAL is returned, it ought to be the SAME length as the
query.

Further simple tests seem to confirm that the generalised problem is that it
always returns
a DNS response where the UDP data ( and hence UDP header's size field ) is one
byte
greater than the actual encoded DNS data.


The next problem is that broken format of the response to an ANY query.

$ perldig @ns1.greatdomains.com eve1.net any
;; Answer received from 207.171.44.100 (301 bytes)
;;
;; HEADER SECTION
;; id = 39250
;; qr = 1    opcode = QUERY    aa = 1    tc = 0    rd = 0
;; ra = 0    rcode  = NOERROR
;; qdcount = 1  ancount = 5  nscount = 1  arcount = 0

;; QUESTION SECTION (1 record)
;; eve1.net.    IN      ANY

;; ANSWER SECTION (5 records)
eve1.net.       3600    IN      A       207.171.44.105
eve1.net.       3600    IN      SOA     ns1.greatdomains.com.
administrator.greatdomains.com. (
                                        20001013        ; Serial
                                        3600    ; Refresh
                                        600     ; Retry
                                        86400   ; Expire
                                        3600 )  ; Minimum TTL
eve1.net.       3600    IN      NS      ns1.greatdomains.com.
eve1.net.       3600    IN      NS      ns2.greatdomains.com.
ns1.greatdomains.com.   3600    IN      A       207.171.44.100

;; AUTHORITY SECTION (1 record)
ns2.greatdomains.com.   3600    IN      A       207.171.44.101

;; ADDITIONAL SECTION (0 records)

As shown above, the ancount/nscount/arcount entries do not correspond to the
data
It SHOULD be 4/0/2 according to the data but is actually 5/1/0. If the
implementation
was "more correct" it would also include NS records in the AUTH section as well,

and hence have ancount/nscount/arcount of 4/2/2


The next minor problem is lack of proper support for NCACHE.  As shown above it
fails to return
any records for a negative reply - which corresponds to NODATA response type 3
from RFC2308.


The next major problem is lack of checks on the query domain. The server
actually responds
to queries for any and all - even non-existent - zones. The quirkiest example of
 this is it's response
to dig  . any , as shown below. Not only does it have a packet size bug, it
places the glue in the
wrong section , AND it includes records from a seemingly random domain in the
answer section
along with the invalid root A record.

Better still, if you ask the question more than once, you get a different answer
 every time!

See below for details.

$ perldig @ns1.greatdomains.com . any
;; Answer received from 207.171.44.100 (307 bytes)
;;
;; HEADER SECTION
;; id = 2685
;; qr = 1    opcode = QUERY    aa = 1    tc = 0    rd = 0
;; ra = 0    rcode  = NOERROR
;; qdcount = 1  ancount = 5  nscount = 1  arcount = 0

;; QUESTION SECTION (1 record)
;; .    IN      ANY

;; ANSWER SECTION (5 records)
.       3600    IN      A       207.171.44.105
www.kidnames.com.       3600    IN      SOA     ns1.greatdomains.com.
administrator.greatdomains.com. (
                                        20001013        ; Serial
                                        3600    ; Refresh
                                        600     ; Retry
                                        86400   ; Expire
                                        3600 )  ; Minimum TTL
www.kidnames.com.       3600    IN      NS      ns1.greatdomains.com.
www.kidnames.com.       3600    IN      NS      ns2.greatdomains.com.
ns1.greatdomains.com.   3600    IN      A       207.171.44.100

;; AUTHORITY SECTION (1 record)
ns2.greatdomains.com.   3600    IN      A       207.171.44.101

;; ADDITIONAL SECTION (0 records)
$

$ perldig @ns1.greatdomains.com . any
;; Answer received from 207.171.44.100 (283 bytes)
;;
;; HEADER SECTION
;; id = 35881
;; qr = 1    opcode = QUERY    aa = 1    tc = 0    rd = 0
;; ra = 0    rcode  = NOERROR
;; qdcount = 1  ancount = 5  nscount = 1  arcount = 0

;; QUESTION SECTION (1 record)
;; .    IN      ANY

;; ANSWER SECTION (5 records)
.       3600    IN      A       207.171.44.105
ptsa.com.       3600    IN      SOA     ns1.greatdomains.com.
administrator.greatdomains.com. (
                                        20001013        ; Serial
                                        3600    ; Refresh
                                        600     ; Retry
                                        86400   ; Expire
                                        3600 )  ; Minimum TTL
ptsa.com.       3600    IN      NS      ns1.greatdomains.com.
ptsa.com.       3600    IN      NS      ns2.greatdomains.com.
ns1.greatdomains.com.   3600    IN      A       207.171.44.100

;; AUTHORITY SECTION (1 record)
ns2.greatdomains.com.   3600    IN      A       207.171.44.101


Having had a partial explanation from greatdomains of this server, it is
apparent that they're not
intending to run a complete server - they themselves intended to run a "spoofer"
 which "invents"
response records on the fly based on the domain name and the querytype. Hence
there is only
a minimal record set supported, and probably no support at all for zone transfer
 or query over TCP.

I wouldn't have a problem with this, if they actually formatted the packet
correctly, and perhaps
responded DNS REFUSED to domains not "valid" on the "spoofer".

And now for the clincher.

The bind8 server appears to decode these malformatted packets; it has some
packet length
checking in src/bin/named/ns_resp.c such as this:

.....

        if (cp > eom) {
                formerrmsg = outofDataAFinal;
                goto formerr;
        }

......

which copes with the situations of truncated data where the UDP packet length is
 too short, but
apparently no corresponding test of packet too long.


Meanwhile, and after only a very cursory trawl through the bind9 source, of
which I admit I am
entirely unfamiliar, it seems that this section of code in dns_message_parse()
in lib/dns/message.c

.......

        ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER,
                         preserve_order);
        if (ret != ISC_R_SUCCESS)
                return (ret);

        ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY,
                         preserve_order);
        if (ret != ISC_R_SUCCESS)
                return (ret);

        ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL,
                         preserve_order);
        if (ret != ISC_R_SUCCESS)
                return (ret);

        isc_buffer_remainingregion(source, &r);
        if (r.length != 0) {
                if (r.length == 2 && r.base[0] == 'M' && r.base[1] == 'S') {
                        isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
                                      DNS_LOGMODULE_MESSAGE, ISC_LOG_INFO,
                                      "message has nonstandard Microsoft tag");
                } else {
                        return (DNS_R_FORMERR);
                }
        }

.......


will almost certainly mean that this test:

 if (r.length != 0) {

will trip up on greatdomains' one-byte-too-long responses. ( It's also
fascinating
to see that a Microsoft special getout clause has already had to be coded into
bind9 ! )

As a result , all their many thousands of hosted domains may start to disappear
as bind9 comes online.

Needless to say, it's pure speculation what their server may do in the face of
EDNS/DNSUPDATE/DNSSEC queries - I have no machines with which to perform that
level of testing.

It's also difficult to absolutely determine whether the packet length
malformation - as apparently
detected by bind9 - is ever logged as such in any way - or even whether the
rogue packet is logged
at all other than a general FORMERR response statistic to the original querier?

The broken DNS server emulation also raises another few ideas about more
insanity checking
in bind8/9 anyway.

What does bind8/9 do at present with A records found in the AUTH section? It
might just ignore
them, or it might include them in the cache with ADDITIONAL level credibility,
but it certainly oughtn't
to add them with AUTHORATITIVE credibility. In a similar vein the server ought
to be checking
for inappropriate records types turning up in the ADDITIONAL section as well?
And both forms of
oddities ought to be logged somewhere.

I have tried to raise the various malformations of their servers' responses with
 greatdomains with
some very detailed Emails similar to the explanations shown above, but they
don't seem particularly
concerned about correcting the various issues. If anyone more authoratitive from
 ISC would like to
take up the challenge, I'd be only too delighted.

If anyone can clarify whether my decode of the bind9 packet length trap is
correct, and how bind9
logs any of the conditions in malformatted packets shown above , please let me
know.


Thanks.


Ted Rule,
Flextech Television



***************************************************************************************************

This E-mail message, including any attachments, is intended only for the person
or entity to which it is addressed, and may contain confidential information.

If you are not the intended recipient, any review, retransmission, disclosure,
copying, modification or other use of this E-mail message or attachments is
strictly forbidden.

If you have received this E-mail message in error, please contact the author and
 delete the message and any attachments from your computer.

You are also advised that the views and opinions expressed in this E-mail
message and any attachments are the author's own, and may not reflect the views
and opinions of FLEXTECH Television Limited.
***************************************************************************************************





More information about the bind-workers mailing list