This script was developed and tested on NT4.0 running
ActiveState's ActivePerl build 506.  With minor mods,
and the addition of the shebang syntax, it should work
on Un*x, as well.  

sweep.pl is a port scanner (I put a the ports in the 
'@ports' array...I kept the number small for testing
purposes) that lists which ports are active, grabs 
banners/HTTP server/finger output (where available) and
writes it all to a logfile at the same time as to 
STDOUT.  

Feel free to use or modify...just be sure to give 
credit where credit is due!!

Keydet89

#####################################################
# sweep.pl
# by Keydet89 <keydet89@yahoo.com>
#    12 Nov 1998
#
# written and tested on NT 4.0 w/ ActivePerl build 506 
#
# usage 'perl sweep.pl [options]
#   [options] => hostname or IP
# 
# sweep a host looking for open ports; 
# list of active ports are placed into an array, 
# and further information is gathered;
# performs auto-logging
#####################################################
# for www_svr
use LWP::Simple;

# for socket
use IO::Socket;

# for Win32-specific functions
use Win32;

if ($#ARGV < 0) {
  usage();
  exit;
}

# Ports to check
@ports = (21,23,25,79,80,139,12345);
@active_ports;

# Assign hostname/IP to variable
$target = $ARGV[0];

print "Checking $target...\n";
#################################################
# main section
#################################################

# open log file
# all data written to screen and log
# new scans of same system overwritten
open (LOG,">$target.log");

$ip = name($target);
foreach $port (@ports) {
  check_port($ip,$port);
}

# Now, collect banner from active ports
print "\nNow checking active ports...\n";
print LOG "\nNow checking active ports...\n";
get_data($ip);

#################################################
# Get name or IP, do lookup
#################################################
sub name {
  my ($host) = @_;
#  print "\nUsing gethostbyaddr()...\n";
  ($name,$alias,$addrtype,$length,$new_addr) = 
      gethostbyaddr(inet_aton($host),AF_INET);
  print "Hostname:\t$name\n";
  print LOG "Hostname:\t$name\n";
  $ipaddr = inet_ntoa(scalar($new_addr));
  print "IP:\t\t$ipaddr\n";
  print LOG "IP:\t\t$ipaddr\n";

  return $ipaddr;
}

#################################################
# Get name of WWW Server
#################################################
sub www_svr {
  my ($host) = @_;
  ($content_type, $document_length, $modified_time,$expires, 
    $server) = head("http://$host");

  print "HTTP Server:\t$server\n";
  print LOG "HTTP Server:\t$server\n";

}

#################################################
# Check to see if a port is open
#################################################
sub check_port {
  my ($host,$port) = @_;
  
  $remote = IO::Socket::INET -> new (
             Proto => "tcp",
             PeerAddr => $host,
             PeerPort => $port
             ) ;
  if ($remote) { 
    close $remote;
    print "$host:$port=>\tActive\n";
    print LOG "$host:$port=>\tActive\n";
    push @active_ports, $port;
  }
  else { 
    print "$host:$port=>\tInactive\n"; 
    print LOG "$host:$port=>\tInactive\n";
  }  
}

#################################################
# subroutine to collect data from active ports
#################################################
sub get_data {
  my ($host) = @_;
  
  foreach $port (@active_ports) {
    if ($port == 80) {www_svr($host);}
    if ($port == 21) {get_banner($host,$port);}
    if ($port == 25) {get_banner($host,$port);}
    if ($port == 79) {finger($host);}
    if ($port == 110) {get_banner($host,$port);}
    if (($port == 139) && Win32::IsWinNT()) {nbt($host);}
  }
}

#################################################
# Get banner (single line) from port
#################################################
sub get_banner {
  my ($host,$port) = @_;
  $remote = IO::Socket::INET -> new (
          Proto => "tcp",
          PeerAddr => $host,
          PeerPort => $port
          ) or die "Could not open socket.\n";

  $line = <$remote>;
  print "$line\n";
  print LOG "$line\n";
  close $remote;
}

#################################################
# Send data to a port, read back all data
# (finger)
#################################################
sub finger {
  my ($host) = @_;
  print "Finger $host...\n";
  print LOG "Finger $host...\n";
  $remote = IO::Socket::INET -> new (
          Proto => "tcp",
          PeerAddr => $host,
          PeerPort => 79
          );
  print $remote "\n";
  @lines = <$remote>;
  close $remote;
  foreach $line (@lines) { 
    print "$line";
    print LOG "$line";
  }
  print "\n";
  print LOG "\n";
}

#################################################
# Run nbtstat on the target
#################################################
sub nbt {
  print "\nRunning nbtstat...\n";
  my ($host) = @_;
  open(NBT,"nbtstat -A $host |");
  while(<NBT>) { 
    print ; 
    print LOG ;
  }
}

#################################################
# Print out usage 
#################################################
sub usage {
 print "usage: perl sweep.pl [options]\n\n";
 print "\t[options]\tHostname or IP address of target\n";
}




