#!/usr/bin/perl#Written Andrew Stringer 09/09/2004 onwards.#Copyright Andrew Stringer 09/09.2004.#This script is licenced under the GPL.##This script tests a range of ip addresses and #attempts to get information about each host from snmp & netbios#This requires the nbtscan package and net::SNMP perl module. It deliberately uses nslookup rather#than any perl modules to reduce dependancies. nmap is used for port scanning.#You will have to ensure the paths are set for your#environment and that the web server user can run nmap for os fingerprinting. You may have to use #chmod 4755 nmap to set the setuid bit. Also for nbtscan as it tries to #bind to a port lower than 1024.##0.1 - basic script, reads in from config file and outputs to stdout.#It reads in ./hosts2probe.txt for the config info, #format is network (3 octets),start host & end host.#This will change in future verions to allow the script to be configured via cgi parameters.##0.2 - 16/09/2004#html tags addded to convert to suitable format for running as cgi script.sub Ping{#first read in the ip address to ping from arraylocal ($host)=@_;#test if $host contains a "#" - treat as commented out line#$comment is true(1) if $host contains a #$comment = ($host =~ m/#/) ;#if $comment is false (ie does not contain a #), proceed with pingif ($comment == "0"){ #generate ping timeout 2 seconds & 1 ping #on linux $result= `/bin/ping -c1 -w2 $host`; #on SGI #$result= `/usr/etc/ping -c1 $host`;#print "$result \n"; #attempt to extract time from $result, $time contains time and $units the unit #first split ping res up by : char @array= split (/:/, $result); $sequence=@array[2]; #next remove everything after --- in ping response @array1= split (/---/, $sequence); $sequence=@array1[0]; #remove first two fields (icmp and seq no.) and extract time and units @array2= split (/ /, $sequence); $time=@array2[3]; $units=@array2[4]; #remove time= from $time @array3= split (/=/, $time); $time=@array3[1];  #pattern match for reply to ping  if ($result=~ m/1 received/){$alive="1" ;  $colour= $green;  }  else   {$alive="0";  $colour= $red;  $time= "";  $units="No Response"; } #test time returned if longer than 20ms, set $colour = amber if ($time>20) { $colour="$amber" ; }#end of test for #}#else if $comment is true(1), just set variables and exitelse{ $alive = "Not tested" ; $snmp = "Not tested" ; $time = "&nbsp;" ; $units = "&nbsp;" ; $colour = "$grey" ;}#print $alive ;#return resultreturn $alive, $time, $units, $colour ;#end sub with curly brace}sub SNMPget{use Net::SNMP;#read in variablesmy $host = shift;my $mib = shift;my $community = shift;my ($session, $error) = Net::SNMP->session(      -hostname  => shift || $host,      -community => shift || $community,      -port      => shift || 161    );   if (!defined($session))   {      my $result1 = $error ;      #print "\nSession not defined, \$error is $error\n" ;   }   my $result = $session->get_request(-varbindlist => [$mib]);      #print "\nInside SNMP sub..\nsnmp result is $result->{$mib}\n" ;      my $result1 = $result->{$mib} ;   if (!defined($result))   {      $value = "Not Defined.$error" ;      my $result1 = "Not Def" ;      #print "\n\$result1 not defined.\n" ;   }   $session->close;return $result1  ;#end sub with curly brace}sub nbtscan{#first read in the ip address to scan from arraylocal ($host)=@_;#print "nbtscan \n";#generate netbios probe to host, use -q for banner suppression & -s: for delimiter$nbtresult= `/bin/nbtscan -q -s : $host`;@nbtresult= split /:/,$nbtresult ;return ($nbtresult[1],$nbtresult[2],$nbtresult[3],$nbtresult[4]) ;}sub ipscan{#first read in the ip address to scan from arraylocal ($host)=@_;#generate nmap scan$nmapresult = `/usr/bin/nmap -O $host`;@nmapresult1 = split /OS details: /,$nmapresult ;@nmapreturn = split /Nmap run completed/,$nmapresult1[1] ;#print "$nmapresult \n";#print "sub nmap $nmapreturn[0]\n";return ($nmapreturn[0]) ;}sub dnslookup{local ($host)=@_;$lookup = `/opt/bin/nslookup -sil $host` ;@lookuparray = split /name = /,$lookup ;return ($lookuparray[1]) ;}#MAIN:#start of body of program{#set up environment variables#print "Start of main: \n";$green = "#00bb00" ;$amber = "#ffff00" ;$red = "#cc0000" ;$lightred = "#cc8888" ;$green = "#00cc00" ;$lightgreen = "#88cc88" ;$blue = "#0000cc" ;$lightblue = "#8888cc" ;$white = "#ffffff" ;$grey = "#999999" ;#Define MIB valuemy $sysUpTime = ".1.3.6.1.2.1.1.3.0" ;my $sysDescr =  ".1.3.6.1.2.1.1.1.0" ;my $sysName   = ".1.3.6.1.2.1.1.5.0" ;#number of interfaces present on devicemy $ifNumber      = ".1.3.6.1.2.1.2.1.0";my $ifDescr       = ".1.3.6.1.2.1.2.2.1.2.";my $ifSpeed       = ".1.3.6.1.2.1.2.2.1.5.";my $ifAdminStatus = ".1.3.6.1.2.1.2.2.1.7.";my $ifOperStatus  = ".1.3.6.1.2.1.2.2.1.8.";my $ifName	  = ".1.3.6.1.2.1.31.1.1.1.1.";my $community = "public" ;#get system date$date = localtime;#end of variable setup#print out html headerprint "Content-type: text/html\n\n";print <<ENDOFTEXT1 ;<html><head><title>en400.jobs4brum.org.uk Host Probe $date</title></head><body text="#000000" bgcolor="#ffffff" link="0000EE" vlink="#551A8B"><center><table border="0" Width="80%"><tr><td><a href="/index.html"><img SRC="/media_logo_sml.gif" border="0"  title="Up a level" alt="Click hereto return to en400's web page"></a></td><td align="center"><font size=+3>en400.jobs4brum.org.uk</font><br>Generated $date .</td></tr></table></center><br><center><table border="1" bgcolor="#ffffcc" width="95%"><tr><th>IPaddress</th><th>NetBIOS<br><font color="magenta">Name</font><br>User<br>Server</th><th>MACaddress<br>(NetBIOS)</th><th><font color="magenta">DNS name</font><br>SNMP name<br>SNMP uptime</th><th>OS Guess</th><th>SNMPdescr</th></tr>ENDOFTEXT1#read in hosts2probe.txt for devices to test.open HOSTS, "<hosts2probe.txt" or die "Cannot open file hosts2probe.txt for input." ;#read in all of sites.txt in to array "@hostsarray"@hostsarray = <HOSTS> ;#close hosts2probe.txtclose HOSTS ;#start loop through inputarray#print "Hostsarray is $#hostsarray long\n";for ($index = 0; $index < $#hostsarray ; $index++){#split out pairs of ipaddress and text string on "," ie.convert scalar to array@value = split /,/, $hostsarray[$index] ;#print "$value[0] $value[1] $value[2]";#loop round, start with host $value[2]for ($loopcount1 = $value[1]; $loopcount1 < ($value[2]+1) ; $loopcount1++){$network=$value[0]."." ;$ipaddress=$network.$loopcount1 ;#print "$ipaddress \n";#first test if device is alive$host=$ipaddress;#call ping sub&Ping ($host);if ($alive == "1") { $devuptime   = &SNMPget ($host, $sysUpTime, $community); $interfaces  = &SNMPget ($host, $ifNumber, $community); $description = &SNMPget ($host, $sysDescr, $community); $sysname     = &SNMPget ($host, $sysName, $community); ($netbiosname, $server, $user, $MACaddress)= &nbtscan ($host);#remove "<" & ">" from $server $server =~ s/<// ; $server =~ s/>// ; $nmapresult = &ipscan ($host) ; $dnsname = &dnslookup ($host); print <<endoftext20 <tr><td>$ipaddress</td><td><font color="magenta">n=$netbiosname&nbsp;</font><br>u=$user&nbsp;<br>s=$server&nbsp;</td><td>$MACaddress&nbsp;</td><td><font color="magenta">$dnsname&nbsp;</font><br>$sysname&nbsp;<br>$devuptime&nbsp;</td><td>$nmapresult&nbsp;</td><td>$description&nbsp;</td></tr>endoftext20# print "Ping reply ($host) is $alive. \n";# print "SNMP Name = $sysname\n";# print "SNMP sysDescr = $description \n";# print "Uptime is $devuptime \n";# print "$host has $interfaces interfaces.\n"; # print "NetBIOS Name $netbiosname\nServer(?) $server\nUser Name $user\nMAC address $MACaddress \n"; # print "\n";# print "Nmap reports:- $nmapresult \n";  } else {print <<endoftext30<tr><td>$ipaddress</td><td colspan="5">did not reply to ping.</td></tr>endoftext30# print "Device $host did not return a ping response.\n"; }#end 2nd for loop, once round for each ipaddress}#end 1st for loop (how many lines in config file}#get system date$date = localtime;print "</center>";print "</table>";print "<br>";print "Run Complete, ", ($value[2]+1)-$value[1]," addresses scanned" ;print "&nbsp;&nbsp;&nbsp;<img src=\"/green-tick.gif\">&nbsp;&nbsp;$date<br>" ;print "</body>";print "</html>";#end program Main section}exit (0);