#!/usr/bin/perl -w # # Script to enumerate DNS information on a domain # # 4 parts # # 1: Try zonetransfer (takes long for big domains, leave it running) # 2: Lookups from a worldlist # 3: Results are converted to class C ranges # 4: Reverse lookups on Class C ranges # # Timeouts are put at 7 secs # # By Filip Waeytens - august 2003 - Filip_Waeytens-at-yahoo.com use strict; use Net::DNS; use IO::File; #usage if (@ARGV!=2){ print "Usage: perl dnsenum.pl \n\n"; exit 1; } #declarations my $domain=$ARGV[0]; my (@nameservers, @networks, @octets, @roctets, @words, @results, @uniq, @ips); my ($rr, $i, $f, $config, $ipssize, $raddress, $uniq, $results, $network, $networks); my %seen; print "\n\nChecking $domain\n\n"; #getting the namservers for the domain my $res = Net::DNS::Resolver->new; $res->tcp_timeout(10); my $query = $res->query($domain, "NS"); if ($query) { foreach $rr (grep { $_->type eq 'NS' } $query->answer) { push @nameservers, $rr->nsdname;#push nameservers in the @nameservers array } } #print error and exit if it doesn't work out else { warn "query failed: ", $res->errorstring, "\n"; exit (1); } print "\n------------------------------------------\n\n"; print "Nameservers for this domain:"; print "\n\n----------------------------------------\n\n"; &nslookup (@nameservers);#do a lookup of the nameservers and print them out #check for dot in domainname and add one if necessary unless ($domain =~/^\./){ $domain=".$domain"; } print "\n------------------------------------------\n\n"; print "Trying Zonetransfers\n"; print "\n------------------------------------------\n\n"; &zonetransfer(@nameservers);#trying zonetransfers on nameservers #opening the textfile with names $config=$ARGV[1]; $f = new IO::File($config) || die "Couldn't open file for reading: $!\n"; #put them in a nice array and instantiate multiple subarrays my $thread = 0; my $nthreads = 5;#tweak this for speed - experiment while (<$f>){ chomp $_; $_="$_$domain"; $words[$thread] = [] unless defined $words[$thread]; push @{$words[$thread]}, $_; $thread = 0 if ++$thread >= $nthreads; } print "\n------------------------------------------\n\n"; print "Looking up names from $config\n"; print "\n------------------------------------------\n\n"; foreach (@words) { &nslookup(@$_);#do a lookup for each array in the array and print out results } #C-class range determination @results =sort @results; foreach $results(@results){ @octets=split /\./,$results; #$octets[3]="1-254"; $network="$octets[0].$octets[1].$octets[2]"; push @networks,$network; } #extract unique values from array %seen = (); @uniq = (); foreach $networks(@networks) { unless ($seen{$networks}) { # if we get here, we have not seen it before $seen{$networks} = 1; push(@uniq, $networks); } } #printing the results of our ranges print "\n------------------------------------------\n\n"; print "Breakdown in C classes\n"; print "\n------------------------------------------\n\n"; foreach $uniq(@uniq){ print "$uniq/24\n"; for ($i=1;$i<255;$i++){ push @ips,"$uniq.$i";#push all unique ip's in the array ips } } #starting reverse lookups on the ip's $ipssize=scalar(@ips); print "\n------------------------------------------\n\n"; print "doing reverse lookup of $ipssize addresses\n"; print "\n------------------------------------------\n\n"; &reverselookup(@ips);#calling reverselookup routine with ip's print "\n\n----------------------------------------\n\n"; #subroutine for reverse lookups sub reverselookup { foreach $_(@_){ @roctets=split/\./,$_; $raddress="$roctets[3].$roctets[2].$roctets[1].$roctets[0].in-addr.arpa"; my $res = Net::DNS::Resolver->new; $res->nameservers(@nameservers); $res->tcp_timeout(7); my $query = $res->query($raddress, "PTR"); if ($query) { foreach my $rr ($query->answer) { print $rr->string, "\n"; } } # else { # print ".";#this part prints a dot when no result is found-just to check progress # } } } #subroutine for lookups sub nslookup{ foreach $_(@_){ my $res = Net::DNS::Resolver->new; $res->tcp_timeout(7); my $query = $res->search($_); if ($query) { foreach my $rr ($query->answer) { if ($rr->type eq "A"){ print $rr->string, "\n"; if ($_=~/$domain/){ push @results,$rr->address;#push the ip addresses in an array if it belongs to the domain } } } } # else { # print "."; # } } } #subroutine for zonetransfers sub zonetransfer{ foreach $_(@_){ my $res = Net::DNS::Resolver->new; $res->tcp_timeout(7); $res->nameservers($_); my @zone = $res->axfr($domain); print "trying zonetransfer for $domain on $_\n"; foreach $rr (@zone) { $rr->print; } }