DNS Zone Scanning

by DEFT  (deft@phayze.com)

Recently I've been trying to add more focus to my port scanning.

By this I mean I try to resist the urge to scan large Class B networks that take days or weeks to complete, and which also result in my ISP berating me because they got 10 calls from companies who were annoyed by my massive scans.  And all this for what?  To know port 139 is open on 800 windows boxes!?  Is there a way we can make our scans more efficient and even less noticeable?

What if there was a way to scan only all the "important" machines in a domain (example.com)?

We would waste less time probing useless machines and probably call less attention to ourselves.  By "important," I mean the HTTP, FTP, NT, UNIX servers, switches, routers, etc., of the company.  We would need a way to scan only these addresses and not the other smaller-scale (i.e., users' Windows 95 boxes) machines in between.

Keep in mind, all these important machines are spread out over separate subnets.  Maybe many of the corporate web servers sit on the 100.20.4.x subnet, and a lot of the more interesting UNIX boxes sit on 100.20.9.x and up.  That's over 1000 addresses in between that we don't really care about since we just want the big players on a company's network.

Can this quickly and efficiently be accomplished?  Yes!  And our answer lies in the DNS system.

DNS is the who's who of the Internet.  Arguably any machine that is of significant importance to an organization is registered in DNS somewhere.  And this is the information we need.  "So how do we get this info Mr.  DNS man?" you ask.

Well, first of all, I am no DNS specialist.  To get more background on this DNS stuff go to www.dns.net/dnsrd (lots of great tools too!).  Now to answer your question, we will be using something called a DNS zone transfer.

A zone transfer is when one machine requests a list of all registered machines of another zone.  I emphasized "registered" because a zone transfer only obtains the machine names known to the the DNS server you are querying.  So if you are looking to probe those other unknown machines (which may be just as important to you as many surprises can be found this way) in between all these major ones, this type of scan is not for you.  Note that a zone transfer is a legitimate way for one DNS server to keep its records up to date - there's nothing illegal about it.  So it's a great way to get an enormous amount of information from a domain.  However, it may look a little odd (read suspicious), and not all domains will allow you to do this.

The programs we will use to do this are host, which runs on Linux (available at www.dns.net/dnsrd/tools.html), and to do the scans, Nmap (www.insecure.org), of course.  The program host appeared in 2600 a while back.  Check out 11:4, "Net Surfing Techniques," for a quick overview of host.  Windows users can participate in zone transfer fun as well.  See www.dns.net/dnsrd/mark/wintools.html for some great tools.

The Program

Using a little Perl we can make host and Nmap achieve our objective of scanning the important machines.

Host by itself returns a lot of junk along with the IP addresses.  Try running host -alv example.com, and you'll see what I mean.

Nmap can't read in these IPs due to this extra junk, so we need to do some cleanup.

First, we strip off the DNS junk to get only a list of IPs.  We use IPs instead of hostnames because more than one hostname can be mapped to a single IP (This is virtual addressing.  Try host -alv mtv.com for an example.)

Now although Nmap could read this file just fine, there can be many repeating entries of the same IP.  So the program then filters out all of these repeating IPs and puts it in a file to be scanned by Nmap.

So there we are!  Now we can scan the machines that matter far faster than a simple bulk scan.  This program is made to run on UNIX but can be easily adapted to Perl for NT or even Windows 98.  Try substituting Netcat for Nmap.

There are two downsides to this method.

Firstly, it is loud.  Any company with decent security will log a zone transfer.  However, this is not to say it would be noticed, as zone transfers are a routine thing.  A zone transfer is far less suspicious than your typical TCP connect scan, and might even call less attention to itself than a SYN scan, since a lot of IDS's log SYN scans now.

In this way, a zone transfer may even be preferred over a scan.  When scanning, an IDS would notice thousands of probes, but it would only log one zone transfer.  However, the zone transfer is not as thorough.

Which brings me to the second downside.  Remember, we are only receiving and scanning the hosts registered in DNS.  Though we can learn about thousands of machines this way, we could be missing many other important details of the network.

All in all, this method is pretty handy.  It is conservative, yet effective.

You could also adapt this program to scan only certain types of machines by looking for patterns in the hostnames.  For example, many organizations use a naming scheme that gives a hint (if not outright tells you) what the machine is: SUN3.example.com, ftp.example.com, cisco-5.example.com are some examples.  Maybe you only want to grab banners from all the FTP servers.  You don't even have to use Nmap.  Be creative!

zonescan.pl:

#!/usr/bin/perl 

# zonescan.pl - by DEFT
# Usage: zonescan.pl whatever.com

if ( $ARGV[0] eq "" ) {
    die "usage: zonescan.pl whatever.com\n";
}

# do zone xfer

print "Starting zone transfer...\n";
system("/usr/bin/host -I $ARGV[0] $ARGV[1] > zone");

open( ZONE, './zone' );

while (<ZONE>) {
    split;
    if ( $_[0] eq "Server" && $_[1] eq "failed:" ) {
        die "Zone transfer refused.\n";
    }
    else { last; }
}

print "Zone transfer complete.\n ";
print "Creating target file. This may take a while ... \n";

# clear old log files for appending to later

system("echo '' > hosts");
system("echo '' > hostsToScan");
system("echo '' > log");

# strip off DNS junk to get the hostnames

while (<ZONE>) {
    split;
    if ( $_[1] eq "has" ) {
        system("echo $_[3] >> hosts");
    }
}

# need to strip off the repeating entries

open( HOSTS, './hosts' );
my (@wholefile) = <HOSTS>;
%seen = ();
foreach $item (@wholefile) {
    push( @uniq, $item ) unless $seen{$item}++;
}

for ( $i = 1 ; $i <= @uniq ; $i++ ) {
    system("echo '$uniq[$i]' >> hostsToScan");
}

print "Target file created. Starting nmap now.\n";
print "Check log for results.\n";

# clean up and do the scan. Add your own nmap options here.

system("rm -rf hosts zone");
system("/usr/bin/nmap -sS -iL hostsToScan >> log&");

Code: zonescan.pl

Return to $2600 Index