#!/usr/local/bin/perl
#
# snmpscan	scan snmp services for commonly known snmp communities
#
#		This script can automate the scanning of your network to
#		check for possible "vulnerabilities" regarding your snmp
#		community "passwords" for access to your routers and/or
#		snmp services.
#
#		Even though you may be running a unix snmp daemon that
#		does not allow control of any services, access to the snmp
#		service provides alot of information about the machine it
#		is running on. Afterall, that is what snmp is for.
#
#		All routers and machines running snmp services should be 
#		protected with a password composed of upper and lower case 
#		characters, numbers, and symbols. Those that aren't can be
#		easily brute forced.
#
#		Knight / Phunc
#		knight@phunc.com
#
#		This script was written to help protect your network.
#
#		www.phunc.com

use strict;
use Net::SNMP;

my $version = "0.05 alpha";
my $dict = shift || 0;
my $debug = shift || 0;

my $dictfile = "dict.txt";
my $commfile = "comm.txt";
my $hostfile = "hosts";

my @comms = ( 	"public",
		"private",
		"router",
		"test"
	);

my @hosts = ( "localhost" );
my $i=0;
my $comret=0;
my $hostname='';

print "SNMPscan (version: $version) by knight\@phunc.com of phunc\n\n";

if (-e $hostfile) {
  (@hosts)=gethosts($hostfile);
} else {
  print "Hosts file '$hostfile' does not exist.\n";
}

for ($a=0;$a<scalar(@hosts);$a++)
{
  $hostname=$hosts[$a];
  print "Guessing community on host '$hostname':\n";

  for ($i=0;$i<=3;$i++)
  {
    $comret = getuptime($comms[$i]);

    if($comret eq 1)
    {
      print "\tCommunity '$comms[$i]' *** successful ***.\n";
    } else
    { 
      print "\tCommunity '$comms[$i]' unsuccessful.\n";
    }
  }
  if ($dict eq "-dict") {
     open(DICT,"<$dictfile") || die "Unable to open dict file '$dictfile'";
     print "\tUsing communities from dictionary.\n";
     while(<DICT>) {
        my $community = $_;
        chop($community);
        my $dictret = getuptime($community);
        if ($dictret eq 1)
        {
          print "\tCommunity '$community' *** successful ***.\n";
	} else {
          print "\tCommunity $community unsuccessful.\n";
        }
     }
  }
}

sub gethosts {
  my $hfile = shift;
  print "Reading host file '$hfile': ";
  
  open(HFILE,"<$hfile") || die "\nUnable to read $hfile";
  my $k=0;
  while(<HFILE>) {
    chop;
    $hosts[$k++]=$_;
    print "$_\n" if ($debug);
  }
  close(HFILE);
  print "$k hosts read.\n";
  return @hosts;
}  


sub getuptime {
  my ($community) = @_;
  my $port = 161;
  print "Hostname: $hostname\n" if ($debug);
  print "Community: $community\n" if ($debug);
  print "Port: $port\n\n" if ($debug);

  my ($session, $error) = Net::SNMP->session(
			Hostname	=> $hostname,
			Community	=> $community,
			Port		=> $port
			);

  if (!defined($session)) {
     printf("ERROR: %s\n", $error) if ($debug);
     return 0;
  }

  my $sysUpTime='1.3.6.1.2.1.1.3.0';

  $session->timeout(2);
  $session->retries(2);
#  $session->debug;
  my $response='';
  if (!defined($response = $session->get_request($sysUpTime))) {
     printf("ERROR: %s\n",$session->error) if ($debug);
     $session->close;
     return 0 ;
  }

  printf("Uptime for host '%s' is: %s\n", $hostname,
	$response->{$sysUpTime}) if ($debug);

  $session->close;

  return 1;  
}
