#!/usr/pkg/bin/perl -w ## DO NOT DISTRIBUTE THIS TOOL !!! ## IF YOU HAVE COME ACROSS THIS TOOL AND YOU AREN'T ONE OF MY TESTERS, ## PLEASE LET ME KNOW AT THE E-MAIL ADDRESS BELOW, THANKS ####################################################################### # gosh-nt.pl - A Windows NT/200 SNMP Auditing Tool # (C) 2001 jshaw[at]sps[dot]lane[dot]edu # version: 2001APR21 (For UNIX & WIN32 using ActivePerl # url: http://www.sps.lane.edu/~jshaw # # I more than welcome ideas, contributions, and constructive criticism # # Part of my G.O.S.H. Toolkit # GOSH is an acronym for "Groper Of SNMP Hosts", or at your leisure: # "GOSH! I didn't know the Windows NT SNMP Service gave out that # much information!", although if it's your machine, I'm sure you'd # rather use another four-letter word in place of "GOSH". # # I plan to work on more tools as part of the GOSH Kit, specifically # a cisco device and HP printer device tool, that essentially does the # same thing as this one. Also, a UNIX one would be handy (maybe for the # UCD-SNMP kit? # # Submissions and ideas welcome. I will give you proper credits. :-) # # # Synopsis: # This program takes a flurry of arguments and returns the data you # request. As you can see, it gives you a lot of information, and # I see it as being valuable to both network administrators and security # engineers. # # # Background/Rant/More Information/Etc: # Most network administrators these days block the handful of NetBIOS # ports at their firewall. An alarming number of net admins don't bother # blocking port 161/udp from the outside world. To make it worse, the # SNMP Service is (perhaps unnecessarily) required for a host of add-on # programs that come with Windows NT and 2000. Administrators don't bother # to properly configure the SNMP services with remote host access controls # or even changing the community strings. Some day, I expect Microsoft # to get a clue about security, but first their customers do, and they # have to let Microsoft know they won't settle for anything less than # proactively secure. They won't change until they see a financial # incentive to do so. # # Now, more than ever, security is an essential part of any network. You # read in the news daily about company's servers being cracked and # credit card databases being stolen due to lax security practices and # procedures. This is unacceptable. # # # What You Can Do To Fix Your Network: # Learn the basics of SNMP, there are several good sources on the web. # Use my gosh-scan.pl (formerly snoopy.pl), and this tool to scan your # network for "open" devices. Set their community strings to something # other than "public" and "private" AND set access controls so that only # certain IP addresses can query the equipment in question. # # # A Final Word: (Trying not to make it political ;-) ) # # script kiddy : a person who uses this script to crack into other # people's equipment. # # Many network and system administrators out there are overworked, under- # budgetted, and underskilled. But they all generally try to do the best # they can to support themselves and their families. And the last thing # they need is someone most likely a lot less skilled than them, trying # to break into their network with this script. # # You haven't proved anything, except that you can make someone's hard # job, harder. And if you can't at least follow the above, don't change # their webpage to point out how lame the system administrator is. # # In short, be good & have some respect and compassion! Thanks :-) # # Installation: # 1. Install the Net::SNMP perl module. Don't worry about Getopt::Std, it # comes with PERL. # 2. chmod u+x this script and type /path/to/this/script and hit [Enter]. # The program will give you a list of options along with a couple of # simple options. # # # Thanks: (Yes, most have funny names.) # LnkStern - for *lots* of patience, WIN32 testing, and input # Rob Beck from @Stake - patience, testing, input, help with some PERLisms # providing a box for testing, thanks :-) # SirDystic - for input and ideas to help make this more full-featured # SPS Techs - for having test machines ready to go # # # Hello's To Important People: # t12, sangfroid, nee, athena, captain skynyrd, ells & the rest of the cDc # shep@juniper, syke & the rest of NHC, valsmith, diluted, optyx, bronc # the networking folks @ the University of Oregon, the Casas family # use strict; use Net::SNMP; # Get this use Getopt::Std; # Comes with PERL # Program variables my $version = ".9beta 2001 APR 23"; my $port = 161; my $session; my $error; my $response; my %option; my $remote; my $community; # MIBs Involved - do not touch my $mibDescr = "1.3.6.1.2.1.1.1.0"; # System Descri ption my $mibNTDomain = "1.3.6.1.4.1.77.1.4.1.0"; # NT Primary Do main my $mibUptime = "1.3.6.1.2.1.1.3.0"; # System Uptime my $mibContact = "1.3.6.1.2.1.1.4.0"; # System Contac t my $mibName = "1.3.6.1.2.1.1.5.0"; # Syste m Name my $mibLocation = "1.3.6.1.2.1.1.6.0"; # System Locati on my $mibRunning = "1.3.6.1.2.1.25.4.2.1.2"; # Running Progr ams my $mibRunPid = "1.3.6.1.2.1.25.4.2.1.1"; # Running PIDs my $mibInstalled = "1.3.6.1.2.1.25.6.3.1.2"; # Installed Pro grams my $mibInstDate = "1.3.6.1.2.1.25.6.3.1.5"; # Installed Dat e my $mibServices = "1.3.6.1.4.1.77.1.2.3.1.1"; # Services (add to it) my $mibAccounts = "1.3.6.1.4.1.77.1.2.25"; # User Accounts my $mibDateTime = "1.3.6.1.2.1.25.1.2.0"; # System Date & Time my $mibMemSize = "1.3.6.1.2.1.25.2.2.0"; # Total System Memory # Storage my $mibStorDescr = "1.3.6.1.2.1.25.2.3.1.3"; # Storage Descr iption my $mibStorSize = "1.3.6.1.2.1.25.2.3.1.5"; # Storage Total Size my $mibStorUsed = "1.3.6.1.2.1.25.2.3.1.6"; # Storage Used my $mibPtype = "1.3.6.1.2.1.25.3.8.1.4"; # Partition Typ e my $mibSDType = "1.3.6.1.2.1.25.2.3.1.2"; # Storage Devic e Type # Network my $mibInt = "1.3.6.1.2.1.2.2.1.2"; # Network Interfaces my $mibIntMTU = "1.3.6.1.2.1.2.2.1.4"; # Net Int MTU S ize my $mibIntSpeed = "1.3.6.1.2.1.2.2.1.5"; # Net Int Speed my $mibIntBytesIn = "1.3.6.1.2.1.2.2.1.10"; # Net Int Octet s In my $mibIntBytesOut = "1.3.6.1.2.1.2.2.1.16"; # Net Int Octec ts Out my $mibIntPhys = "1.3.6.1.2.1.2.2.1.6"; # Int MAC addr my $mibAdminStat = "1.3.6.1.2.1.2.2.1.7"; # Int up/down? my $mibIPForward = "1.3.6.1.2.1.4.1.0"; # IP Forwarding ? my $mibIPAddr = "1.3.6.1.2.1.4.20.1.1"; # Int IP Addres s my $mibNetmask = "1.3.6.1.2.1.4.20.1.3"; # Int IP Netmas k ###################### M A I N ####################################### # Duh... getopts("aghrisunt:c:", \%option); # Start queries... if(!$option{t}) { &Usage; } # rtfm else { $remote = $option{t}; } if(!$option{c}) { $community = "public"; } # community str ing else { $community = $option{c}; } &Init; if($option{g} || $option{a}) { &General; } # -g if($option{h} || $option{a}) { &Hardware; } # -h if($option{r} || $option{a}) { &Running; } # -r if($option{i} || $option{a}) { &Installed; } # -i if($option{s} || $option{a}) { &Services; } # -s if($option{u} || $option{a}) { &UserAccounts; } # -u if($option{n} || $option{a}) { &Network; } # -n # Finished $session->close; ###################### SUBROUTINES ################################## sub Init { # Establish SNMP session... ($session, $error) = Net::SNMP->session( Hostname => $remote, Community => $community, Port => $port ); # Die if SNMP session fails to work... if(!defined($session)) { die "ERROR: $error\nIs the host running SNMP?\n\n"; } # Set session timeout value to 1 second (Default is 5 secs) $session->timeout(1); } sub General { my $Name = &GetRequest($mibName); my $NTDomain = &GetRequest($mibNTDomain); my $Descr = &GetRequest($mibDescr); my $Contact = &GetRequest($mibContact); my $Location = &GetRequest($mibLocation); my $DateTime = &GetDate(&GetRequest($mibDateTime)); #$DateTime = &GetDate($response->{$mibDateTime}); print <<"EOF"; Information for $Name [$remote] Primary Domain: $NTDomain ----------------------------------------------------------- Description: -------------- $Descr Contact: $Contact Location: $Location System Date \& Time: $DateTime EOF } sub Hardware { my $MemSize = &GetRequest($mibMemSize); # Total Memory my @StorDescr = &GetTable($mibStorDescr); # Device Descri ption my @SDType = &GetTable($mibSDType); # Devic e Type #my @StorSize = &GetTable($mibStorSize); # Device Size #my @StorUsed = &GetTable($mibStorUsed); # Device Used my @Ptype = &GetTable($mibPtype); # Parti tion Type print <<"EOF"; Hardware Configuration: ----------------------------------------------------------- Total Memory: $MemSize KB Storage: -------------- EOF # Process garbagely looking variables & then print!!! for ($a = 0; $a < scalar(@StorDescr); $a++) { ## Convert device type to human-readable if($SDType[$a] eq "1.3.6.1.2.1.25.2.1.3") { $SDType[$a] = "Virtual Memory"; } if($SDType[$a] eq "1.3.6.1.2.1.25.2.1.4") { $SDType[$a] = "Fixed Disk"; } if($SDType[$a] eq "1.3.6.1.2.1.25.2.1.5") { $SDType[$a] = "Removable Disk"; } if($SDType[$a] eq "1.3.6.1.2.1.25.2.1.7") { $SDType[$a] = "Compact Disc"; } ## fudge for the chocolate cluebies #if($StorSize[$a] eq "0") { $StorSize[$a] = "N/A"; } ## Convert partition type to human-readable #my $spork = scalar(@Ptype); #my $spoon = scalar(@StorDescr); #print "DEBUG: StorDescr: $spoon a: $a Ptype: $spork $Ptyp e[$a]\n\n\n\n"; if($Ptype[$a] eq "1.3.6.1.2.1.25.3.9.2") { $Ptype[$a] = "UNKNOWN"; } if($Ptype[$a] eq "1.3.6.1.2.1.25.3.9.9") { $Ptype[$a] = "NTFS"; } ## a kludge, yes i know if($StorDescr[$a] ne "Virtual Memory") { print <<"EOF"; $StorDescr[$a] Device Type: $SDType[$a] Partition Type: $Ptype[$a] EOF ############## BROKEN ############################ #### print "\tPartition Type: $Ptype[$a]\t\t\n"; } } } sub Running { my $temp; my @Running = GetTable($mibRunning); my @RunPid = GetTable($mibRunPid); #my @Running = reverse @RevRunning; print "\n\nRunning Applications:\n"; print "-----------------------------------------------------------\n"; #foreach $temp (@Running) { print "$temp\n"; } for ($a = 0; $a < scalar(@RunPid); $a++) { if($Running[$a] ne "System Idle Process") { print "$RunPid[$a]\t\t$Running[$a] \n"; } } } sub Installed { my $temp; my @Installed = &GetTable($mibInstalled); my @InstDate = &GetTable($mibInstDate); print "\n\nInstalled Applications:\n"; print "-----------------------------------------------------------\n"; # header for below info print "Date Installed\tTime\n"; for($a = 0; $a < scalar(@Installed); $a++) { my $Date = &GetDate($InstDate[$a]); print "$Date\t$Installed[$a]\n"; } } sub Services { my $temp; my @Services = GetTable($mibServices); print "\n\nServices:\n"; print "-----------------------------------------------------------\n"; foreach $temp (@Services) { print "$temp\n"; } } sub UserAccounts { my $temp; my @Accounts = GetTable($mibAccounts); print "\n\nUser Accounts:\n"; print "-----------------------------------------------------------\n"; foreach $temp (@Accounts) { print "$temp\n"; } } sub Network { my @Int = &GetTable($mibInt); # inter face names my @MTU = &GetTable($mibIntMTU); # inter face MTU size my @IntSpeed = &GetTable($mibIntSpeed); # interface spe eds my @IntBytesIn = &GetTable($mibIntBytesIn); # interface byt es in my @IntBytesOut = &GetTable($mibIntBytesOut); # interface bytes out my @IntPhys = &GetTable($mibIntPhys); # MAC address my @IPAddr = &GetTable($mibIPAddr); # inter face IP addresses my @Netmask = &GetTable($mibNetmask); # interface IP netmask my @AdminStat = &GetTable($mibAdminStat); # admin status my $IPForward = &GetRequest($mibIPForward); # IP Fwding? if ($IPForward eq "0" || $IPForward eq "2") { $IPForward = "no"; } # Hell if I know why we need this, chalk it up as a bug # For whatever reason, the netmask values return opposite of # what everything else does. *beats head against dead goat* @Netmask = reverse @Netmask; print "\n\nNetwork:\n"; print "-----------------------------------------------------------\n"; print "IP Forwarding Enabled: $IPForward\n"; # Output data print "\n\nInterfaces:\n--------------\n"; for ($a = 0; $a < scalar(@Int); $a++) { chop $Int[$a]; if($AdminStat[$a] eq "0") {$AdminStat[$a] = "down"} else { $AdminStat[$a] = "up"; } $IntSpeed[$a] = $IntSpeed[$a] / 1000000; print "Interface: [ $AdminStat[$a] ] $Int[$a]\n"; print "\tHardware Address: $IntPhys[$a]\n"; print "\tInterface Speed: $IntSpeed[$a] Mbps\n"; print "\tIP Address: $IPAddr[$a]\n"; print "\tNetmask: $Netmask[$a]\n"; print "\tBytes In: $IntBytesIn[$a]\n"; print "\tBytes Out: $IntBytesOut[$a]\n"; print "\n"; } } sub GetRequest { # Takes only one MIB as an argument! my $response; if(!defined($response = $session->get_request($_[0]))) { $session->close; die "GetRequest() for $_[0] failed!\n"; } my $Return = $response->{$_[0]}; return $Return; } sub GetTable { # Takes only one MIB as argument! my @Return; my $response; # Grab all the MIBs under the specified OID if(!defined($response = $session->get_table($_[0]))) { $session->close; die "GetTable() for $_[0] failed!\n"; } my $x = 0; my $key; foreach $key (sort keys %$response) { if($$response{$key} ne "Virtual Memory") { $Return[$x] = $$response{$key}; $x++; } } # Jam information into array #while(my ($currOID, $Back) = each %$response) { # $Return[$x] = $Back; # $x++; #push(@Return, $Back); #print "DEBUG: $currOID\t$Back\n"; #} #for($a = 0; $a < scalar(@Return); $a++) { # print "$a\t$Return[$a]\n"; #} return @Return; } sub GetDate { # Converts yay byte string to human-readable my $year = hex(substr($_[0], 2, 4)); my $day = hex(substr($_[0], 6, 2)); my $month = hex(substr($_[0], 8, 2)); my $hour = hex(substr($_[0], 10, 2)); my $minute = hex(substr($_[0], 12, 2)); my $Return = "$day/$month/$year\t$hour:$minute"; return $Return; } sub Usage { print <<"EOF"; gosh-nt.pl v$version - A Windows NT/2000 SNMP auditing tool (C) 2001 jshaw [at] sps [dot] lane [dot] edu http://www.sps.lane.edu/~jshaw Usage: ./gosh-nt.pl Options: -------- -t - specify target hostname/ip *REQUIRED* ---------------------------------------------------------- *Plus one or more of the below* -a - ALL; lists all information about the remote host -g - provides general information about the remote host -h - provides hardware information about the remote host -r - lists running processes on remote host -i - lists installed applications & install date on remote host -c - lists services on remote host -u - lists user accounts on remote host -n - lists network information from remote host Examples: -------- ./gosh-nt.pl -a -t 10.0.0.1 -c public (Would report ALL information for host 10.0.0.1 using community "public") ./gosh-nt.pl -gn -t 10.0.0.1 -c public (Would only report general & network information for host 10.0.0.1) EOF exit; }