I am currently working in the RCNTEC company where I have a deal with distributed environments everyday. Once I had to work with the ISC BIND to implement DNS service and asked myself - are there only those DNS servers for domain are used, that are listed as NS servers for this domain? Are there really only two nameservers for ‘yandex.ru’ zone and four for ‘google.com’ zone?

Obviously, no. I think that a lot of companies, that have their work with Internet services, have distibuted DNS infrastructure standing behind load balancer, firewall or some kind of reverse proxy.

But how can we solve the mystery and get some info about backend DNS servers?

It was a time to dive into DNS.

Chaosnet

You can read more about Chaosnet here. In two words, it is another network protocol working on Layer 3 of the ISO OSI.

Regarding DNS, Chaosnet was recognized as one of the network classes (with code CH) like IN (for Internet) and HS (for Hesiod).

Chaosnet is very interesting, because CH class is used frequently to serve zone ‘bind.’ containing several useful info about DNS server. I think that you know about ‘version.bind.’ record that allows you to determine DNS server version.

There is commonly used DNS fingerprint technique based on this record.

Just see an example:

bash-3.2$ dig CH @ns.illegalbytes.com version.bind. -t txt

; <<>> DiG 9.8.3-P1 <<>> CH @ns.illegalbytes.com version.bind. -t txt
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25357
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;version.bind.			CH	TXT

;; ANSWER SECTION:
version.bind.		0	CH	TXT	'9.9.4-RedHat-9.9.4-50.el7_3.1'

;; AUTHORITY SECTION:
version.bind.		0	CH	NS	version.bind.

;; Query time: 179 msec
;; SERVER: 185.22.62.102#53(185.22.62.102)
;; WHEN: Sun Aug 27 20:27:06 2017
;; MSG SIZE  rcvd: 86

As you can see above, I requested Chaosnet TXT-record ‘version.bind.’ from my own DNS-server and got the response containing my DNS server’s version.

We can get DNS server version, but we still couldn’t enumerate DNS servers behind a relay. Also, a lot of system administrators know about this ‘feature’ and know how to fix this and hide version.

Even if our target’s system administrator has not patched zone ‘bind.’, we can’t enumerate DNS anyway - this is only version, not IP or anything similar.

Another CH TXT-record

TXT-record ‘hostname.bind’ is another record available in CH zone ‘bind.’. Let’s see, what happens if we will request this record from our DNS-server:

bash-3.2$ dig CH @ns.illegalbytes.com hostname.bind. -t txt

; <<>> DiG 9.8.3-P1 <<>> CH @ns.illegalbytes.com hostname.bind. -t txt
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51139
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;hostname.bind.			CH	TXT

;; ANSWER SECTION:
hostname.bind.		0	CH	TXT	'vm117494.local'

;; AUTHORITY SECTION:
hostname.bind.		0	CH	NS	hostname.bind.

;; Query time: 814 msec
;; SERVER: 185.22.62.102#53(185.22.62.102)
;; WHEN: Sun Aug 27 20:54:37 2017
;; MSG SIZE  rcvd: 72

Great! We got server hostname. In my case, hostname is only internal server name. But what about distributed environments?

My experience said that this is very convenient and common to have servers hostnames equals with their external DNS names. In this case, with internal hostname we will get external DNS name too. And we can simply resolve external DNS name to obtain server IP.

Unhidens

I had written a small utility to run ‘dig’ against relay to determine versions, hostnames and resolve received hostnames.

Let’s see output of unhidens launched against russian domain registar’s nameserver:

>
1
2
3
4
5
6
7
8
9
10
11
12
13
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
zone 'bind' {
	type master;
	file 'bind.dns';

        allow-query { any; };
};

And create ‘bind.dns’ zone-file:

$TTL    1D
$ORIGIN bind.
@       1D      CHAOS   SOA     localhost. root.localhost. (
                2017082702      ; serial 
                3H              ; refresh 
                1H              ; retry 
                1W              ; expiry 
                1D )            ; minimum 
        CHAOS NS        localhost.

version.bind.   CHAOS  TXT "is newest available version!"
authors.bind.   CHAOS  TXT "are better coders than I. :)"
hostname.bind.  CHAOS  TXT "unknown for me."

This is not the easiest way to hide your version and hostname, but with this configuration you are able to log requests to the ‘bind.’ zone - and track all clients trying to request sensitive info about your machines.

Good luck!

The end