#!/usr/bin/perl# ################ ### DNScan ###################### ################ Inspired by ### ### strayfe's dmap #################### ###################### Coded by dbr ### ### 01/09/2006 ### #################### use Socket; use Getopt::Std; use strict; use Thread; $SIG{INT} = \&clearup; #Varible used to check a second sigint, if it's setup in the sub, it's killed when the thread ends #it'd declared out here so I can set/check it without it being killed my$clearingup; ################# ###! Default !################# #################! Options !################### #################! Change me !### ################### ##Lookup delay, # Sets the delay between lookups, to stop a craptonne of looksups at once ## Over-ride with -d my $delay=1; ##Default prefix file # Sets the default prefix file if none is set ## Over-ride with -p my $prefile="prefixs.txt"; ##Try numeric increments # If a subdomain is valid, try subdomain + number, # Example : db.example.com is not valid, db1.example.com is valid # try db2.example.com, if it's valid, try db3.example.com etc etc # Will try regardless of subdomain without number (incase db is invalid, but db1 is) ## Default : True ## Over-ride with -i my $increment="false"; ##Verbose # Extra errors ## Default : False ## Over-ride with : -v my $verbose="false"; ##Max threads # Number of threads to run at once ## Default : 10 ## Over-ride with -t my $maxthread=10; ##################### ####################### # \/ Don't touch \/ ############################## end user varibles # ##################### Unless you know your doing ##################### ############################## #commandline switches-y bit #not defining v and i makes them work with no data # after, for some screwed up reason, thus they aren't there.. getopt("p:d:h:"); our($opt_i,$opt_h,$opt_v,$opt_p,$opt_d); if($opt_v){ $verbose="true"; }else{ if($verbose eq "true"){ warn("[?] Using default verbose\n"); $verbose="true"; }else{ if($verbose eq "false"){ undef $verbose; }else{ warn("[?]Default verbose is not true/false, defaulting to not-verbose"); undef($verbose); } } };if($verbose){warn("[?] Verbose\n");} $prefile=$opt_p || warn("[?] using default prefix file : " . $prefile ."\n") if $verbose; $delay=$opt_d || warn "[?] using default delay : " .$delay."\n" if $verbose; if($opt_i){ $increment=$opt_i; warn("[?] Using increment\n"); } else { if($increment eq "true"){ warn("[?] using incremented subdomains (default)\n") if $verbose; } else { if($increment eq "false"){ undef($increment); } else { warn("[?] default increment not true/false, defaulting to false\n"); undef($increment); } } } my $host=$opt_h || usage("host must be set"); #Open prefix file open(PRE,"<".$prefile); chomp(my @prefixs=
);
close(PRE);
#file checks
if(!-e $prefile){
usage("prefix file does not exist");
}
print("[*] Number of prefixs : " . $#prefixs . "\n");
#end startup crap, bulk of code from here on
my @threads;
my $thrnum=0;
if($increment){
my @increment_curnum;
my @increment_origname;
}
my @results;
for my $prefix (@prefixs)
{
my @templist;
while(1){
@templist=Thread->list;
if($#templist<10){
@threads[$thrnum]=new Thread (\&scanthread,$prefix,$host,$increment);
my $nullinglypointless=@threads[$thrnum]->join();
$thrnum++;
sleep(0.5);
last;
} else {
sleep(1);
}
}
}
sleep(1);
print("[*] Done all lookups\n[*] Displaying results\n");
print($#results);
exit;
# # # # # # # # # #
# # thread code # #
# # # # # # # # # #
sub scanthread(){
my ($name,$host,$increment)=@_;
if($increment){
if(!(@main::increment_curnum[$name])){
my @data;
push(@data,"2");
push(@data,$name);
@main::increment_curnum[$name]=@data;
}
}
print("\n".$name.".".$host.":\n");
my $tolookup=$name .".". $host;
my @addrs=namelookup($tolookup);
if($#addrs>=0){
#subdomain exists
if($increment){
my $incrementname=$name . ((@main::increment_curnum[$name]))[0];
print("Trying increment of " . ((@main::increment_curnum[$name])[0])."\n");
@main::threads[$#main::threads++]=new Thread(\&scanthread,$incrementname,$host,$increment);
((@main::increment_curnum[$name]))++;
}
my @topush;
(@topush[$name])=@addrs;
push((@main::results),@topush);
return "true";
} else {
#Subdomain doesn't exist
return "false";
}
}
# # # # # # #
# # subs # #
# # # # # # #
#simple dns lookup
sub namelookup(){
my ($lookupname)=@_;
my @addrs;
my @gethost=(gethostbyname($lookupname))[4];
if($#gethost>=0){
for(@gethost){
my $curip=inet_ntoa($_);
push(@addrs,$curip);
}
}
return @addrs;
}
#usage error sub
sub usage(){
my ($message)=@_;
warn("[!] ". $message . "\n\n");
print("Usage : ".$0." [OPTIONS]\n");
print("-p \t Prefix file. \t\t\t\tDefault: prefix
-d \t Delay between lookups in seconds. \tDefault : 1
-i \t Try incrementing subdomain. \tDefault : True\n\t\t This will try subdomain + 1, if it's valid, then 2, etc, till they are no longer valid\n
-h \t The target hostname \t Default : None
\t This is the host to try subdomains on, should be in the format name.tld, no www.");
exit;
}
sub clearup(){
if($main::clearingup eq "true"){die("[!] Caught second SIGINT\n");}
$main::clearingup="true";
warn("[!] Caught SIGINT, cleaning up\n");
if(@threads){
for(Thread->list){
$_->kill("SIGINT");
}
}
if(@prefixs){
close(@prefixs);
}
}