Site hosted by Angelfire.com: Build your free website today!
# NTSCAN.PL
# Written by Stuart McClure
# Sept. 19, 1999
#
# NTSCAN.PL allows for simple NT system enumeration with only null session access.
# Output is in HTML files organized by Class C address. The main results file is
# called scanresults.html and links to all the IP addresses scanned.
#
# Note:
#  1) The script has not been optimized and can take some time to complete
#     depending on the number of systems you are scanning.
#  2) Remember, you must have the requisite programs for the script to work completely.
#
# Programs necessary include (you must have DUMPACL.EXE and DUMPACL.KEY in the
# directory where you run NTSCAN.PL from):
#  netcat, snmputil, epdump, getmac, netviewx, local, global
#  user2sid, sid2user, netdom, dumpacl
#

# --------------------------------------------------------------------------
# Main Program
# --------------------------------------------------------------------------

print "\nNTScan - NT scanning and enumeration script\n";
print "Written by Stuart McClure for Windows NT only.\n";
print "Sept. 19, 1999\n\n";
print "Copyright by Stuart McClure, Sept. 1999\n\n";
print "This program is written AS-IS and will not be supported.\n";
print "In addition, the author is not responsible for the program's misuse.\n\n";
print "Look for updates at http://www.hackingexposed.com and send comments to:\n\n";
print "\tstu\@hackingexposed.com.\n\n";
print "WARNING: the programs used in this script are run without explicit paths.\n";
print "  This means that it will search your path to run a particular\n";
print "  program (i.e. netdom). This also means that if a trojan of the same\n";
print "  name has already been planted on your system that it will run it instead.\n";
print "  Your best solution to this is to modify NTSCAN and hardcode\n";
print "  your program's paths.\n";
print "  WE ARE NOT RESPONSIBLE FOR ANY DAMAGE RESULTING FROM THIS SCRIPT.\n\n";
 
initialize();
parms();
create_menu_head();
run_core();
create_menu_tail();

print "Scan completed.\n";
print "Point your browser to the \"scanresults.html\" file for the results.\n";

# --------------------------------------------------------------------------
# Initialize() resets up the variables for the program.
# --------------------------------------------------------------------------

sub initialize {
 
 $rvar  = 0;
 $tvar  = 0;
 $dvar  = 0;
 $fvar  = 0;
 $pvar  = 0;
 $divar = 0;
 $evar  = 0;
 $cavar  = 0;
 $help  = 0;
 $nvar  = 0;
 $foundit = 0;

}

# --------------------------------------------------------------------------
# Syntax() displays the proper syntax for the program.
# --------------------------------------------------------------------------

sub syntax {
 
 print " ------------------------------------------------------------------------------\n";
 print "  All of the host range options below are mutually exclusive.\n";
 print " ------------------------------------------------------------------------------\n";
 print "     -i 192.168.10.3  Specify a single IP or range of addresses.\n";
 print "      -f <hosts.txt>  Read the hosts from a file.\n";
 print "    -d <domains.txt>  Read the domains from a file.\n";
 print "           -s domain  Enumerates a single domain.\n";
 print "                  -w  Enumerates all domains on the wire.\n\n";
 print " ------------------------------------------------------------------------------\n";
 print "  The remaining options are not.\n";
 print " ------------------------------------------------------------------------------\n";
 print "        -p ports.txt  Read the ports to be scanned from a file (banners too).\n";
 print "               -snmp  Pull SNMP information (or at least try to).\n";
 print "                  -n  Do not determine if system is up (no pinging).\n";
 print "                  -r  Randomize the systems scanned.\n";
 print "                  -v  Verbose messages.\n";
 print "                  -h  Help.\n\n";
 print " In addition to the standard NetBios and TCP\/IP utilities on Windows NT,\n";
 print " you'll also need the following NTRK and external programs to fully utilize \n";
 print " the script:\n\n";
 print "   netcat, snmputil, epdump, getmac, netviewx, local, global\n";
 print "   user2sid, sid2user, netdom, dumpacl. \n\n";
 print " Check out \"Hacking Exposed\" for references to the above utilities.\n\n";
 print " Some examples...\n";
 print "   To scan all the domains on the wire:\n";
 print "      ntscan.pl -w \n";
 print "\n";
 print "   To scan a range of IP's, randomize them, and scan certain ports verbosely:\n";
 print "      ntscan.pl -i 172.29.11.100-200 -r -p ports.txt -v\n";
 print "\n";
 
 exit(1);
}

# --------------------------------------------------------------------------
# Parms() function parses the command line and sets variables
# and runs the necessary commands to setup the program.
# --------------------------------------------------------------------------

sub parms {

 if ($#ARGV < 0) {
   syntax();
 }
 
 @parmar = @ARGV;
 
 # Loop through the flags until exhausted.
 while (@parmar) {
  $arg = shift(@parmar);

  if ($arg eq "-i") {         # IP address range.
   if (($dvar == 1) || ($fvar == 1) || ($svar == 1)) {
    print "Error: -i and -f are mutally exclusive.\n\n";
    syntax();
   }
 
   $rrange = shift(@parmar);
 
   if (!($rrange)) {
 
    syntax();
   }
 
   if ($rrange=~/-/) {
    @tmp = split/-/, $rrange;
    if (!($tmp[1])) {
 
     syntax();
    }
   }
 
  } elsif ($arg eq "-v") {     # Verbose output
     $vvar = 1;
  } elsif ($arg eq "-r") {     # Randomize the IP array
     $rvar = 1;
  } elsif ($arg eq "-h") {     # Help
     syntax();
  } elsif ($arg eq "-n") {     # No pinging
     $nvar = 1;
  } elsif ($arg eq "-w") {     # Enumerate domains on the wire.
     $wvar = 1;
  } elsif ($arg eq "-d") {     # Read domains from a file.
     if (($ivar == 1) || ($fvar == 1) || ($svar == 1)) {
      print "Error: -i, -f, and -d are mutually exclusive.\n";
      syntax();
     }
 
     $dvar = 1;
     $domfile = shift(@parmar);
 
     if (!($domfile)) {
      syntax();
     }
 
     if ($domfile=~/-/) {
 
      syntax();
     }
 
     open (DOMFILE, "<$domfile") or die "Cannot open domain file: $domfile\n";
     close DOMFILE;
 
  } elsif ($arg eq "-f") {     # Read hosts from a file.
     if (($dvar == 1) || ($ivar == 1) || ($svar == 1)) {
      print "Error: -i and -f are mutally exclusive.\n\n";
      syntax();
     }
 
     $fvar = 1;
     $hostfile = shift(@parmar);
 
     if (!($hostfile)) {
 
      syntax();
     }
 
     if ($hostfile=~/-/) {
 
      syntax();
     }
 
     open (HOSTFILE, "<$hostfile") or die "Cannot open host file: $hostfile\n";
     close HOSTFILE;
 
  } elsif ($arg eq "-s") {     # Scan single domain.
     if (($dvar == 1) || ($ivar == 1) || ($fvar == 1)) {
      print "Error: -i, -f, -d, and -s are mutally exclusive.\n\n";
      syntax();
     }
 
     $svar = 1;
     $domain = shift(@parmar);
 
     if (!($domain)) {
 
      syntax();
     }
 
     if ($domain=~/-/) {
 
      syntax();
     }
 
  } elsif ($arg eq "-p") {     # Port scan.
 
     $pvar = 1;
     $portfile = shift(@parmar);
 
     if (!($portfile)) {
 
      syntax();
     }
 
     if ($portfile=~/-/) {
 
      syntax();
     }
 
     open (PORTFILE, "<$portfile") or die "Cannot open ports file: $portfile";
     while($ports=<PORTFILE>) {
      chomp($ports);
      if (!(($ports=~/#/) || ($ports eq ""))) {
       push(@portsa, $ports);
      }
 
     }
     close PORTFILE;
 
  } elsif ($arg eq "-snmp") {
 
     $snmpvar = 1;
 
  } else {
     print "One too many illegal parameters.\n\n";
     syntax();
  }

 }

  if ($dvar == 1) {
 
   open (DOMFILE, "<$domfile");
   while ($file=<DOMFILE>) {
    chomp($file);
    if (!(($file=~/#/) || ($file eq ""))) {
     push (@dom1, $file);
    }
   }
   close DOMFILE;
 
   get_hosts_in_domains();
 
  } elsif ($svar == 1) {
     $domain = uc($domain);
     chomp($domain);
 
     if ($vvar == 1) {  print "Scanning $domain domain.\n"; }
     open (DOM2, "netviewx -D $domain -On 2>&1 |");
     while ($host=<DOM2>) {
      chomp($host);
      print "\tFound $host.\n";
      push (@nbthosts, $host);
     }
 
     res_nbt_name();
     close DOM2;
  } elsif ($wvar == 1) {
     run_wire();
  } else {
     build_hosts($rrange);
  }
 
}

# --------------------------------------------------------------------------
# Run_wire() runs the functions necessary to enumerate domains and then
# build the hosts file.
# --------------------------------------------------------------------------

sub run_wire {
 get_domains();
 get_hosts_in_domains();
 print "\n";
}
 

# --------------------------------------------------------------------------
# Logit() logs everything it does. The output is to a file and is the same
# as when you run NTScan in verbose mode (-v)
# --------------------------------------------------------------------------

sub logit {
 $var = $_[0];
 
 open(LOG, ">>$ARGV[2]\/$ARGV[2].log");
 print LOG $var;
 close LOG;
 
}

# --------------------------------------------------------------------------
# Build_hosts() reads the hosts or host ranges from a file into an array.
# --------------------------------------------------------------------------

sub build_hosts {

 $tmp = $_[0];
 
 if ($vvar == 1) { print "Building hosts...\n"; }

 if ($fvar == 1) {
  open (HOSTFILE, "<$hostfile");
  while ($test=<HOSTFILE>) {
   chomp($test);
   doit($test);
  }
  close HOSTFILE;
 } else {
    doit($tmp);
 }

}

# --------------------------------------------------------------------------
# Check_end() is called by doit() to create the hosts array.
# --------------------------------------------------------------------------

sub check_end {
   if (($a1==$a2) && ($b1==$b2) && ($c1==$c2)) {
     $dend=$d2;
   } else {
       $dend=255;
   }
   if (($a1==$a2) && ($b1==$b2)) {
     $cend=$c2;
   } else {
       $cend=255;
   }
   if ($a1==$a2) {
     $bend=$b2;
   } else {
       $bend=255;
   }
}

# --------------------------------------------------------------------------
# Class_c() returns the class of IP address for the purposes of directory
# structure.
# --------------------------------------------------------------------------

sub class_c {
 my $tmp = $_[0];
 
 @me = split/\./, $tmp;
 my $dir = "$me[0].$me[1].$me[2]";
 
 if (!(-e "$dir")) {
  if ($vvar == 1) { print "Making directory: $dir\n"; }
 
  system("mkdir $dir");
 }
 
 return("$dir");
 
}
 

# --------------------------------------------------------------------------
# Doit() builds the IP addresses from the command line or file and
# updates an array.
# --------------------------------------------------------------------------

sub doit {

 $line = $_[0];
 
 if ($line!=/#/) {
 
   if ($line=~/-/) {
    @tmp = split/-/, $line;
    @bip = split/\./, $tmp[0];
    @eip = split/\./, $tmp[1];
   } else {
    @bip = split/\./, $line;
    @eip = split/\./, $line;
   }

   $a1 = $bip[0];
   $b1 = $bip[1];
   $c1 = $bip[2];
   $d1 = $bip[3];

   $num = @eip;
   if ($num==1) {
     $a2 = $bip[0];
     $b2 = $bip[1];
     $c2 = $bip[2];
     $d2 = $eip[0];
   } elsif ($num==2) {
     $a2 = $bip[0];
     $b2 = $bip[1];
     $c2 = $eip[0];
     $d2 = $eip[1];
   } elsif ($num==3) {
     $a2 = $bip[0];
     $b2 = $eip[0];
     $c2 = $eip[1];
     $d2 = $eip[2];
   } elsif ($num==4) {
     $a2 = $eip[0];
     $b2 = $eip[1];
     $c2 = $eip[2];
     $d2 = $eip[3];
   }

  # Based on the IP subnet (Class A, B, C) set the
  # correct variables.
  check_end();
  $aend=$a2;

  # Create the array.
  while ($a1 <= $aend) {
   while ($b1 <= $bend) {
    while ($c1 <= $cend) {
     while ($d1 <= $dend) {
      push (@hosts, "$a1.$b1.$c1.$d1");
      $d1+=1;
      check_end();
     }
    $c1+=1;
    $d1=0;
   }
   $b1+=1;
   $c1=0;
   }
  $a1+=1;
  $b1=0;
  }
 }
 
}

# --------------------------------------------------------------------------
# shuffle_array() is the Fisher Yates shuffle which randomizes an array
# inline - very cool.
# --------------------------------------------------------------------------

sub shuffle_array {

  my $hosts = shift;
  my $i;

  for ($i = @$hosts; --$i; ) {
    my $j = int rand ($i+1);
    next if $i == $j;
    @$hosts[$i,$j] = @$hosts[$j,$i];
  }

}

# --------------------------------------------------------------------------
# Run_core() runs the main scanning engine, calling the various functions.
# --------------------------------------------------------------------------

sub run_core {
 
 if ($vvar == 1) {
  print "\nRunning core engine...\n";
 }

 @backup = @hosts;
 
 if ($rvar == 1) {
  shuffle_array ( \@hosts );
 }
 
 foreach $target (@hosts) {
 
  if ($nvar == 0) {       # If pinging is on, then ping.
   ping_host($target);
  } else {                # Otherwise, assume it is up and continue.
     $up = 1;
  }
 
  if ($up == 1) {
   write_html_head($target);
   check_for_nt($target);
   if ($pvar == 1) {
    portscan($target);
   }
  }
 
  if ($wnt == 1) {
 
   if ($snmpvar == 1) {    # Run SNMP checks.
    get_snmp($target);
   }
 
   $dir = class_c($target);
   open(OUTFILE, ">>scanresults.html");
   print OUTFILE "<A HREF=\"$dir\\$target.html\">$target<\/A><BR>";
   close OUTFILE;
 
   get_nbtstat($target);
 
   if ((set_netuse($target))==1) {
 
    get_local_administrators($target);
    get_orig_admin($target);
 
    if ($restrictanon == 1) {       # RestrictAnonymous key set.
     get_allusers($target);
    } else {
       get_global_admins($target);
       get_users($target);
       get_groups($target);
       get_shares($target);
       get_allshares($target);
     }
    get_mac($target);
    get_netdom($target);
    get_epdump($target);
    del_netuse($target);
 
   }
 
   # reinitialize used variables.
   $up  = 0;
   $wnt = 0;
  }
 
 
 
 }

 write_html_tail($target);
 
}

sub portscan {
 
 my $target = $_[0];
 
 if ($vvar == 1) {
  print "Port scanning $target.\n";
 }
 
 $dir = class_c($target);
 open (OUTFILE, ">>$dir\\$target.html");
 print OUTFILE "<H2>PORT information for $target<BR>";
 print OUTFILE "--------------------------------------------</H2>";
 
 foreach $item (@portsa) {
  chomp($item);
 
  local $/;
  open(SCAN, "nc -vzn -w 2 $target $item 2>&1 |");     # Port open
  $result = <SCAN>;
 
  if ($result=~/open/) {
 
   if ($vvar == 1) {
    print "\tPort $item on $target found open.\n";
   }
 
   print OUTFILE "$item open<BR>";
 
   if (($item eq "80") || ($item eq "81") || ($item eq "8000")) {
 
    open (HTTP, ">http.tmp");
    print HTTP "HEAD / HTTP/1.0\n\n";
    close HTTP;
    open(SCAN2, "type http.tmp | nc -nvv -w 2 $target $item 2>&1 |");    # Banners
    $result2 = <SCAN2>;
 
    if ($result2) {
     if ($result2=~/Microsoft-IIS/) {
      $msyes = 1;
     }
     $result2=~s/\n/<BR>/g;
     print OUTFILE "$result2";
    }

    print OUTFILE "<h3>MDAC results</h3>";
    open (HTTP, ">http.tmp");
    print HTTP "GET /msadc/msadcs.dll HTTP/1.0\n\n";
    close HTTP;
    open(SCAN2, "type http.tmp | nc -nvv -w 2 $target $item 2>&1 |");    # Banners
    $result2 = <SCAN2>;
 
    if ($result2) {
     if (($msyes == 1) && ($result2=~/x-varg/)) {
       print OUTFILE "The system IS vulnerable to MDAC attack.<BR><BR>";
     }
     $result2=~s/\n/<BR>/g;
     print OUTFILE "$result2";
    }
 
   }
 
  }
  close SCAN;
 
 }  # foreach
 
 close OUTFILE;
 
}

# --------------------------------------------------------------------------
# Check_for_nt() port scans a system for port 135 and 139,
# --------------------------------------------------------------------------

sub check_for_nt {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Checking for a Windows NT system..."; }
 
 local $/;
 open(SCAN1, "nc -vzn -w 1 $host 135 2>&1 |");
 $result1 = <SCAN1>;
 open(SCAN2, "nc -vzn -w 1 $host 139 2>&1 |");
 $result2 = <SCAN2>;
 
 if (($result1=~/open/) && ($result2=~/open/)) {
  $wnt = 1;
  print "NT found.\n";
 } elsif ($result2=~/open/) {
 
   if ($vvar == 1) {
    print "\n$host: 95/98 or Unix samba client - dumping shares and then skipping.\n";
   }
 
   # Windows 95 system?  Record it and try a one thing.
   get_shares($host);
   print "\n";
 
   $dir = class_c($host);
   open(OUTFILE, ">>scanresults.html");
   print OUTFILE "<A HREF=\"$dir\\$host.html\">$host<\/A><BR>";
   close OUTFILE;
 
 
 } else {
  if ($vvar == 1) { print "\nNeither 95 or NT - skipping $host.\n\n"; }
  return;
 }
 
}

# --------------------------------------------------------------------------
# Ping_host() pings a host and if it is up sets a variable.
# --------------------------------------------------------------------------

sub ping_host {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Pinging host $host.\n"; }
 local $/;
 open (PING, "ping -n 2 $host 2>&1 |");
 $ping = <PING>;
 
 if ($ping=~/Reply from/) {
 
  if (!($ping=~/unreachable/)) {
   $up = 1;
   if ($vvar == 1) { print "Host $host is alive!\n"; }
  }
 
 } else {
  $up = 0;
  if ($vvar == 1) {
   print "Host is dead - skipping $host.\n\n";
  }
 }
 
}

# --------------------------------------------------------------------------
# Get_domains() pulls the domains off the wire and puts them into an array..
# --------------------------------------------------------------------------

sub get_domains {
 if ($vvar == 1) { print "Retrieving domains...\n"; }
 
 open (DOM1, "net view /domain 2>&1 |");
 while ($dom1=<DOM1>) {
  if (!($dom1=~/---|Domain|successfully./)) {
   if ($dom1=~tr/ / /s) {
    chomp($dom1);
    chop($dom1);
    if ($vvar == 1) { print "\tFound $dom1 domain\n"; }
 
    push (@dom1, $dom1);
   }
  }
 }
 
 close DOM1;
}

# --------------------------------------------------------------------------
# Get_hosts_in_domains() enumerates the hosts from get_domains() and
# builds an array.
# --------------------------------------------------------------------------

sub get_hosts_in_domains {
 if ($vvar == 1) { print "Retrieving hosts from domains...\n"; }
 
 foreach $domitem (@dom1) {
  $domitem = uc($domitem);
  chomp($domitem);
  if ($vvar == 1) {  print "Scanning $domitem domain.\n"; }
 
  open (DOM2, "netviewx -D $domitem -On 2>&1 |");
  while ($tmp=<DOM2>) {
   chomp($tmp);
   print "\tFound $tmp.\n";
   push (@nbthosts, $tmp);
  }
 }
 
 res_nbt_name();
 close DOM2;
}

# --------------------------------------------------------------------------
# Res_nbt_name() resolves a netbios name by using the ping -a option.
# --------------------------------------------------------------------------

sub res_nbt_name {
 
 foreach $item (@nbthosts) {
  if ($vvar == 1) { print "Resolving Netbios host: $item"; }
  open (PING, "ping -n 1 -a $item 2>&1 |");
 
  while ($ping=<PING>) {
   if ($ping=~/Reply from/) {
    @ping = split/ /, $ping;
    $hostip = $ping[2];
    chop $hostip;
    print " - Resolved to $hostip.\n";
    push (@hosts, $hostip);
   }
  }
  close PING;
 }
 return;
}

# --------------------------------------------------------------------------
# Set_netuse() creates a null session using "net use".
# --------------------------------------------------------------------------

sub set_netuse {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Establishing null session.\n"; }
 
 open (NETUSE, "net use \\\\$host\\ipc\$ \"\" /u:\"\" 2>&1 |");
 $netuse = <NETUSE>;
 
 if ($netuse=~/successfully./) {
 
  if ($vvar == 1) {
   print "Initial IPC successful to $host...\n";
  }
 
 } else {
    if ($vvar == 1) {
     print "Initial IPC unsuccessful to $host...Exiting.\n\n";
    }
    return(0);
 
    # Without IPC you can still get nbtstat, getusers?, epdump, whoisadm.
 }
 close NETUSE;
}

# --------------------------------------------------------------------------
# Del_netuse() delete the null session.
# --------------------------------------------------------------------------

sub del_netuse {
 my ($host) = @_;
 local $/;
 open (NETDEL, "net use \\\\$host\\ipc\$ \/del 2>&1 |");
 $netdel = <NETDEL>;
 if ($netdel=~/successfully./) {
  if ($vvar == 1) { print "Removing IPC successful to $host...\n"; }
 }
 close NETDEL;
}

# --------------------------------------------------------------------------
# Get_nbtstat() runs nbtstat() and directs output to a file.
# --------------------------------------------------------------------------

sub get_nbtstat {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving NetBIOS information for $host\n"; }
 
 $dir = class_c($target);
 open (OUTFILE, ">>$dir\\$host.html");
 print OUTFILE "<H2>NBTSTAT information for $host<BR>";
 print OUTFILE "--------------------------------------------</H2>";
 open (NBT, "nbtstat -A $host 2>&1 |");
 while ($nbt=<NBT>) {
  if ($nbt=~/<|MAC/) {
   $nbt=~s/\n/<BR>/g;
   print OUTFILE $nbt;
  }
 }
 print OUTFILE "<BR>";
 close OUTFILE;
 close NBT;
}
 

# --------------------------------------------------------------------------
# Get_local_administrators() uses the NTRK "local" command to enumerate
# the local administrators on the box.
# --------------------------------------------------------------------------

sub get_local_administrators {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving LOCAL ADMINISTRATORS for $host\n"; }
 
 local $/;
 open (LOCAL, "local Administrators \\\\$host 2>&1 |");
 $local=<LOCAL>;

 if ($local=~/Error/) {
 
 } elsif ($local=~/Access Denied/) {
 
    $restrictanon = 1;
 
 } else {
 
     @tmp = split/\n/, $local;
 
     foreach $item (@tmp) {
      if (!($item=~/Domain Admins/)) {
 
       $dir = class_c($host);
       open (OUTFILE2, ">>$dir\\$host.admins.txt");
       print OUTFILE2 "$item\n";
       close OUTFILE2;
       chomp ($item);
       push (@admins, $item);
      }
     }
 
     $dir = class_c($host);
     $local =~ s/\n/<BR>/g;
     open (OUTFILE, ">>$dir\\$host.html");
     print OUTFILE "<H2>Local Administrators on $host<BR>";
     print OUTFILE "--------------------------------------------</H2>";
     print OUTFILE "<A HREF=\"$host.admins.txt\">ADMINS file<\/A><BR><BR>";
     print OUTFILE "$local<BR>";
     close OUTFILE;
 }
 
 close LOCAL;
}

# --------------------------------------------------------------------------
# Get_orig_admin() pulls the original administrator using user2sid/sid2user
# in the case where they renamed it.
# --------------------------------------------------------------------------

sub get_orig_admin {
 my ($host) = @_;
 if ($vvar == 1) { print "Retrieving ORIGINAL ADMINISTRATOR for $host\n"; }
 
 $dir = class_c($target);
 open (OUTFILE, ">>$dir\\$host.html");
 print OUTFILE "<H2>ORIGINAL ADMIN information on $host<BR>";
 print OUTFILE "--------------------------------------------</H2>";
 
 
 open (USER2SID, "user2sid \\\\$host Guest 2>&1 |");
 while ($user2sid=<USER2SID>) {
  if ($user2sid=~/S-1-5-/) {
   chomp $user2sid;
   $sidtmp = $user2sid;
   @sid = split/\-/, $sidtmp;
   open (SID2USER, "sid2user \\\\$host $sid[2] $sid[3] $sid[4] $sid[5] $sid[6] 500 2>&1 |");
   while ($sid2user=<SID2USER>) {
    if ($sid2user=~/Name is/) {
     @sid2tmp = split/ /, $sid2user;
     if (!($sid2tmp[2] eq "Domain")) {
      if ($restrictanon == 1) {
       print OUTFILE "<A HREF=\"$host.admins.txt\">ADMINS file.<\/A><BR><BR>";
       $dir = class_c($host);
       open (OUTFILE2, ">>$dir\\$host.admins.txt");
       print OUTFILE2 "$sid2tmp[2]\n";
       close OUTFILE2;
       chomp ($sid2tmp[2]);
       push (@admins, $item);
      } else {
         print OUTFILE "$sid2tmp[2]<BR>";
      }
     }
    }
   }
   $i+=1;
  }
  close SID2USER;
 }
 print OUTFILE "<BR>";
 close USER2SID;
 close OUTFILE;
 
 
 
}

# --------------------------------------------------------------------------
# Get_global_admins() uses the NTRK "global" command to retrieve the
# members of the "Domain Admins" group from an NT machine.
# --------------------------------------------------------------------------

sub get_global_admins {
 my ($host) = @_;
 if ($vvar == 1) { print "Retrieving GLOBAL ADMINISTRATORS for $host\n"; }
 
 local $/;
 open (GLOBAL, "global \"Domain Admins\" \\\\$host 2>&1 |");
 $global = <GLOBAL>;
 if (!($global=~/group not found/)) {
 
  $global=~s/\n/<BR>/g;
  $dir = class_c($target);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>Global Administrators on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "$global<BR>";
 }
 close GLOBAL;
 close OUTFILE;
}

# --------------------------------------------------------------------------
# Get_mac() uses the NTRK "getmac" command to retrieve the MAC information
# from an NT machine.
# --------------------------------------------------------------------------

sub get_mac {
 my ($host) = @_;
 if ($vvar == 1) { print "Retrieving MAC information for $host\n"; }
 
 local $/;
 open (GETMAC, "getmac \\\\$host 2>&1 |");
 $getmac = <GETMAC>;
 if ($getmac) {
  $getmac=~s/\n//;
  $getmac=~s/\n/<BR>/g;
  $dir = class_c($target);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>MAC information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "$getmac";
 }
 close GETMAC;
 close OUTFILE;
}

# --------------------------------------------------------------------------
# Get_netdom() uses "netdom" to retrieve more information from an NT
# box.
# --------------------------------------------------------------------------

sub get_netdom {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving NETDOM information for $host\n"; }
 
 local $/;
 open (NETDOM, "netdom query \\\\$host 2>&1 |");
 $netdom = <NETDOM>;
 if ($netdom) {
  $netdom=~s/\n/<BR>/g;
  $dir = class_c($target);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>NETDOM information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "$netdom<BR>";
 }
 close NETDOM;
 close OUTFILE;
}

# --------------------------------------------------------------------------
# Get_users() uses "dumpacl" to retrieve user information from an NT box.
# --------------------------------------------------------------------------

sub get_users {
 my ($host) = @_;
 
 @realusers = "";
 @userarray = "";
 @bdown = "";
 
 if ($vvar == 1) { print "Retrieving USERS for $host\n"; }
 
 $dir = class_c($host);
 open (GETUSERS, "dumpacl \/computer=\\\\$host \/rpt=users \/saveas=csv \/outfile=$dir\\$host.users.tmp 2>&1 |");
 close GETUSERS;
 
 open (FILE, "<$dir\\$host.users.tmp") or print "Cannot open $dir\\$host.users.tmp\n";
 while ($getusers=<FILE>) {
  chomp $getusers;
 
  if (!(($getusers=~/Somarsoft DumpAcl/) || ($getusers=~/UserName/) || ($getusers=~/rc\=6/) || ($getusers=~/rc\=5/))) {
   @getusers = split/,/, $getusers;
   if (!($getusers eq "")) {
    push (@userarray, "$getusers[0]\t$getusers[1]\t$getusers[3]\t$getusers[10]\t$getusers[12]\t$getusers[14]\t$getusers[15]\t$getusers[16]\t$getusers[17]");
   }
  }
 }
 
 if (@userarray) {
  $dir = class_c($host);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>GETUSERS information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "<A HREF=\"$host.users.txt\">USERS file<\/A><BR><BR>";
 
  foreach $item (@userarray) {
   if ($item) {
    @bdown = split/\t/, $item;
   }
 
   $foundit = 0;
 
   foreach $me (@admins) {        # Check if the user is an administrator.
    if ($me eq $bdown[0]) {       # If yes, then tag it.
     $foundit = 1;
    }
   }
 
   if ($foundit == 0) {
    push (@realusers, $bdown[0]);
   }
 
  }
 
  foreach $user (@realusers) {
   if ($user) {
    print OUTFILE "$user<BR>";
   }
  }
 
 
  foreach $item (@userarray) {
 
   if ($item) {
    @bdown = split/\t/, $item;
   }
 
   print OUTFILE "<H4>Username:\t\t$bdown[0]</H4>";  # Username
   print OUTFILE "Fullname:\t\t$bdown[1]<BR>";       # Fullname
   print OUTFILE "Comment:\t\t$bdown[2]<BR>";        # Comment
   print OUTFILE "PasswordLastSet:\t$bdown[3]<BR>";  # Password Last Set time
   print OUTFILE "PasswordExpires:\t$bdown[4]<BR>";  # Password expires
   print OUTFILE "AccountDisabled:\t$bdown[5]<BR>";  # Account Disabled
   print OUTFILE "AccountLockedOut:\t$bdown[6]<BR>"; # Account locked out
   print OUTFILE "AccountExpires:\t$bdown[7]<BR>"; # Account expires time
   print OUTFILE "LastLogon:\t$bdown[8]<BR><BR>"; # Last logon time
 
  }
 
  print OUTFILE "<BR>";
  close FILE;
  close OUTFILE;
 
  open (USRFILE, ">>$dir\\$host.users.txt");
 
  foreach $user (@realusers) {
   if ($user) {
    print USRFILE "$user\n";
   }
  }
 
  close USRFILE;
 }
 
 unlink("$dir\\$host.users.tmp");
}

# --------------------------------------------------------------------------
# Get_allusers() uses "user2sid" and "sid2user" to retrieve all users
# from an NT box.
# --------------------------------------------------------------------------

sub get_allusers {
 my ($host) = @_;
 
 if ($vvar == 1) { print "RestrictAnonymous: retrieving GETALLUSERS information for $host\n"; }
 
 $dir = class_c($host);
 open (OUTFILE, ">>$dir\\$host.html");
 print OUTFILE "<H2>GETALLUSERS information on $host<BR>";
 print OUTFILE "--------------------------------------------</H2>";
 print OUTFILE "<A HREF=\"$host.users.txt\">USERS file.<\/A><BR><BR>";
 
 open (USER2SID, "user2sid \\\\$host Guest 2>&1 |");
 while ($user2sid=<USER2SID>) {
  if ($user2sid=~/S-1-5-/) {
   chomp $user2sid;
   $sidtmp = $user2sid;
   @sid = split/\-/, $sidtmp;
   $i = 1000;
   while ($i < 1500) {
 
    local $/;
    open (SID2USER, "sid2user \\\\$host $sid[2] $sid[3] $sid[4] $sid[5] $sid[6] $i 2>&1 |");
    $sid2user=<SID2USER>;
    if ($sid2user=~/SidTypeUser/) {
     @sidstuff = split/\n/, $sid2user;
 
     foreach $item (@sidstuff) {
 
      if ($item=~/Name is/) {
       @sid2tmp = split/ /, $item;
 
       if (!($sid2tmp[2] eq "Domain")) {
        chomp $sid2tmp[2];
        push (@alluser, $sid2tmp[2]);
       }
      }
     }
    }
    $i+=1;
   }
 
   close SID2USER;
  }
 }
 
 close USER2SID;
 

  foreach $item (@alluser) {
   foreach $me (@admins) {        # Check if the user is an administrator.
    if ($me eq $item) {       # If yes, then tag it.
     $foundit = 1;
    }
   }
 
   if ($foundit == 0) {
    push (@realusers, $item);
   }
 
   $foundit = 0;
 
  }
 
  open (USRFILE, ">>$dir\\$host.users.txt");
  foreach $user (@realusers) {
   print OUTFILE "$user<BR>";
   print USRFILE "$user\n";
  }
 
  print OUTFILE "<BR>";
  close OUTFILE;
  close USRFILE;
 
}
 

# --------------------------------------------------------------------------
# Get_groups() uses "dumpacl" to retrieve group information from an NT box.
# --------------------------------------------------------------------------

sub get_groups {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving GROUPS for $host\n"; }
 
 $dir = class_c($host);
 open (GETGROUPS, "dumpacl \/computer=\\\\$host \/rpt=groups \/saveas=csv \/outfile=$dir\\$host.groups.tmp 2>&1 |");
 close GETGROUPS;
 
 open (FILE, "<$dir\\$host.groups.tmp") or print "Cannot open $dir\\$host.groups.tmp\n";
 while ($getgroups=<FILE>) {
  chomp $getgroups;
 
  if (!(($getgroups=~/Somarsoft DumpAcl/) || ($getgroups=~/Group,Comment/) || ($getgroups=~/rc=5/))) {
   @getgroup = split/,/, $getgroups;
   if (!($getgroups eq "")) {
    push (@groupsarray, "$getgroup[0]\t$getgroup[1]\t$getgroup[2]\t$getgroup[3]\t$getgroup[4]");
   }
  }
 }
 
 if (@groupsarray) {
  $dir = class_c($host);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>GETGROUPS information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
 
  foreach $item (@groupsarray) {
 
   if ($item) {
    @bdown = split/\t/, $item;
   }
 
   print OUTFILE "<H4>Group:\t\t$bdown[0]</H4>";  # Group
   print OUTFILE "Comment:\t\t$bdown[1]<BR>";  # Comment
   print OUTFILE "GroupType:\t\t$bdown[2]<BR>";  # GroupType
   print OUTFILE "GroupMember:\t$bdown[3]<BR>";    # GroupMember
   print OUTFILE "MemberType:\t$bdown[4]<BR><BR>";  # MemberType
  }
 
  print OUTFILE "<BR>";
  close FILE;
  close OUTFILE;
 
 }

 unlink("$dir\\$host.groups.tmp");
}

# --------------------------------------------------------------------------
# Get_epdump() uses "epdump" to retrieve user information from an NT box.
# --------------------------------------------------------------------------

sub get_epdump {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving EPDUMP information for $host\n"; }
 
 local $/;
 open (EPDUMP, "epdump $host 2>&1 |");
 $epdump = <EPDUMP>;
 if ($epdump) {
 
  $dir = class_c($target);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>EPDUMP information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "$epdump<BR>";
 }
 close EPDUMP;
 close OUTFILE;
}
 

# --------------------------------------------------------------------------
# Get_shares() uses "net view" to retrieve share information from an NT
# or 9x box.
# --------------------------------------------------------------------------

sub get_shares {
 my $host = $_[0];
 
 if ($vvar == 1) { print "Retrieving SHARES on $host\n"; }
 
 $dir = class_c($host);
 open (GETSHARES, "net view \\\\$host 2>&1 |");
 $getshares=<GETSHARES>;
 close GETSHARES;
 
 if (!(($getshares=~/\n/) || ($getshares=~/ /))) {
  @shares = split/\n/, $getshares;
 
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>GETSHARES information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
 
  $go = 0;
  foreach $item (@shares) {
 
   if ($go == 1) {
    if (!(($item eq "\n") || ($item=~/The command/) || ($item eq ""))) {
     print OUTFILE "$item<BR>";
    }
   }
 
   if ($item=~/------/) {
    $go = 1;
   }
  }
  print OUTFILE "<BR>";
  close OUTFILE;
 }
 
}

# --------------------------------------------------------------------------
# Get_allshares() uses "dumpacl" to retrieve share information from an NT
# box.
# --------------------------------------------------------------------------

sub get_allshares {
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving ALLSHARES for $host\n"; }
 
 $dir = class_c($host);
 open (GETALL, "dumpacl \/computer=\\\\$host \/rpt=shares \/saveas=csv \/outfile=$dir\\$host.shares.tmp 2>&1 |");
 $check=<GETALL>;
 close GETALL;
 
 if ($check) {
  open (FILE, "<$dir\\$host.shares.tmp");
  while ($getall=<FILE>) {
   chomp $getall;
 
   if (!(($getall=~/Somarsoft DumpAcl/) || ($getall=~/Share and path/))) {
    @getallshares = split/,/, $getall;
    if (!($getall eq "")) {
     push (@sharearray, "$getallshares[0]");
    }
   }
  }
 
  $dir = class_c($host);
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>GETALLSHARES information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "<A HREF=\"$host.shares.txt\">More SHARES information.<\/A><BR><BR>";
 
 
  open (SHAREFILE, ">>$dir\\$host.shares.txt");
 
  foreach $item (@sharearray) {
 
   print SHAREFILE "$item\n";
   print OUTFILE "$item<BR>";
 
  }
 
  print OUTFILE "<BR>";
  close FILE;
  close OUTFILE;
  close SHAREFILE;
 
 }
 unlink("$dir\\$host.shares.tmp");
}

# --------------------------------------------------------------------------
# Get_snmp() uses "snmputil" from the NTRK to retrieve gobs of information
# from an NT box.
# --------------------------------------------------------------------------

sub get_snmp {
 
 my ($host) = @_;
 
 if ($vvar == 1) { print "Retrieving SNMP information for $host\n"; }
 
 local $/;
 open (SNMPUTIL, "snmputil walk $host public .1.3.6.1.4.1.77 2>&1 |");
 $snmp = <SNMPUTIL>;

 if (!($snmp=~/error on SnmpMgrRequest 40/)) {
  $dir = class_c($host);
  open (SNMPFILE, ">>$dir\\$host.snmp.txt");
  print SNMPFILE "SNMP information on $host\n";
  print SNMPFILE "--------------------------------------------\n";
  print SNMPFILE "$snmp\n";
  open (OUTFILE, ">>$dir\\$host.html");
  print OUTFILE "<H2>SNMP information on $host<BR>";
  print OUTFILE "--------------------------------------------</H2>";
  print OUTFILE "<A HREF=\"$host.snmp.txt\">SNMP information with public community name<\/A><BR><BR>";
 }
 close SNMPUTIL;
 close SNMPFILE;
 close OUTFILE;

}

# --------------------------------------------------------------------------
# Write_html_head() writes the requisite HTML header tags to the beginning
# of each results file.
# --------------------------------------------------------------------------

sub write_html_head {
 
 my ($host) = $_[0];
 
 $mydate = localtime;
 
 $dir = class_c($host);
 open (OUTFILE, ">>$dir\\$host.html");

 print OUTFILE "<HTML>";
 print OUTFILE "<HEAD>";
 print OUTFILE "<TITLE>NTScan results for $host on $mydate<\/TITLE>";
 print OUTFILE "<\/HEAD>";
 print OUTFILE "<BODY>";
 print OUTFILE "<H1>NTScan results for $host on $mydate</H1>";
 print OUTFILE "<H4>Written for \"Hacking Exposed\" by Stuart McClure (July, 1999)</H4><BR>";
 
 close OUTFILE;
}

# --------------------------------------------------------------------------
# Write_html_tail() writes the requisite HTML header tags to the end
# of each results file.
# --------------------------------------------------------------------------

sub write_html_tail {
 
 my ($host) = $_[0];
 
 $dir = class_c($host);
 open (OUTFILE, ">>$dir\\$host.html");
 
 print OUTFILE "<\/BODY>";
 print OUTFILE "<\/HTML>";
 
 close OUTFILE;
}

# --------------------------------------------------------------------------
# Create_menu() builds the big menu file of all the IP addresses.
# --------------------------------------------------------------------------

sub create_menu_head {
 
 open(OUTFILE, ">>scanresults.html");
 
 $mydate = localtime;
 print OUTFILE "<HTML>";
 print OUTFILE "<HEAD>";
 print OUTFILE "<TITLE>NTScan results on $mydate<\/TITLE>";
 print OUTFILE "<\/HEAD>";
 print OUTFILE "<BODY>";
 print OUTFILE "<H1>NTScan results for $host on $mydate</H1>";
 print OUTFILE "<H4>Written for \"Hacking Exposed\" by Stuart McClure (July, 1999)</H4><BR>";

 close OUTFILE;
 
}

sub create_menu_tail {
 
 open(OUTFILE, ">>scanresults.html");
 
 print OUTFILE "<\/BODY>";
 print OUTFILE "<\/HTML>";
 close OUTFILE;
 
}