Blog |Follow Nick on Mastodon| About
 

Back in the day - Windows 2000 era - we would block TCP/53 on the firewall, at the time this was because DNS queries were on UDP/53 and TCP at the time was used for Zone Transfer.

A zone transfer, is where you ask a DNS server to give you all it's records, the legitimate reason for this is creating resilient scalable DNS infrastructure where you need & want the DNS records stored in multiple places.. or maybe closer to the user for speed/performance.

The dark side of zone transfers is that an attacker can use these to map a network, externally a zone transfer is a document describing all your internet assets and internal zone is practically a full network map.

On the modern day network, we can no longer block TCP/53, the original spec stated that if a DNS response exceeds 512 byte then the client should query again via TCP. Twenty years ago a TCP response was barely need but now, DNS records such as DNSSEC, SRV, TXT mean that TCP is actively in use, in fact internally on a Microsoft Active Directory network you will find many things start to fail if TCP/53 is blocked.

This shift from DNS being equally UDP or TCP has opened the door for an old vulnerability. DNS servers now-a-days come by default with zone transfers disabled however the opportunity for miss-configuration is back, with no firewall protection human error is possible (probable?!).

There's about 60 servers in my scope for testing at work, so I figured a quick script was worth a punt!

I've uploaded it to github gist, or a zipfile here -> test_xfer_py.zip

Setup

Not a lot to do, 2x text files...

  1. Update domains.txt with the domain names (zones) you want to try and transfer
  2. Update servers.txt with the DNS Servers you want to run the script against
  3. Either install Docker/Docker-Compose or Python with dnspython

Run

Simples...
If Docker, then docker-compose up.
If Native python, just run it python test_xfer.py

Here's an example run against linickx.com's public NS...

$ docker-compose up
Starting dns_xfer_test_py_dnspython_1 ... done
Attaching to dns_xfer_test_py_dnspython_1
py_dnspython_1  | [CRITICAL] 2019-03-10 20:20:20,647 Zone Tranfser Failed: coco.ns.cloudflare.com | linickx.com
py_dnspython_1  | [DEBUG] 2019-03-10 20:20:20,647 Exception: <class 'dns.query.TransferError'> Zone transfer error: FORMERR
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,647 XFR Failed: coco.ns.cloudflare.com - linickx.com
py_dnspython_1  | [CRITICAL] 2019-03-10 20:20:20,690 Zone Tranfser Failed: coco.ns.cloudflare.com | linickx.co.uk 
py_dnspython_1  | [DEBUG] 2019-03-10 20:20:20,690 Exception: <class 'dns.query.TransferError'> Zone transfer error: FORMERR
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,691 XFR Failed: coco.ns.cloudflare.com - linickx.co.uk
py_dnspython_1  | [CRITICAL] 2019-03-10 20:20:20,741 Zone Tranfser Failed: nash.ns.cloudflare.com | linickx.com
py_dnspython_1  | [DEBUG] 2019-03-10 20:20:20,742 Exception: <class 'dns.query.TransferError'> Zone transfer error: FORMERR
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,742 XFR Failed: nash.ns.cloudflare.com - linickx.com
py_dnspython_1  | [CRITICAL] 2019-03-10 20:20:20,785 Zone Tranfser Failed: nash.ns.cloudflare.com | linickx.co.uk
py_dnspython_1  | [DEBUG] 2019-03-10 20:20:20,786 Exception: <class 'dns.query.TransferError'> Zone transfer error: FORMERR
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,786 XFR Failed: nash.ns.cloudflare.com - linickx.co.uk
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,787
py_dnspython_1  |
py_dnspython_1  |  !! Finished !!
py_dnspython_1  |
py_dnspython_1  | [INFO] 2019-03-10 20:20:20,787 xfer_summary_190310-202020.csv
dns_xfer_test_py_dnspython_1 exited with code 0
$ 

... obviously, nothing open there ;-)

Results

The script results will be in a date/timestamp CSV file -> xfer_summary_xx-yy.csv

If you got lucky and found a vulnerable DNS server, the zone will be dumped to date/timestamp text file -> server_domain_xx-yy.txt

I however didn't get lucky, all servers clean, maybe you will!

 

 
Nick Bettison ©