metasploit-framework/modules/auxiliary/scanner/snmp/snmp_enum.rb

985 lines
28 KiB
Ruby

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::SNMPClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'SNMP Enumeration Module',
'Description' => 'This module allows enumeration of any devices with SNMP
protocol support. It supports hardware, software, and network information.
The default community used is "public".',
'References' =>
[
[ 'URL', 'http://en.wikipedia.org/wiki/Simple_Network_Management_Protocol' ],
[ 'URL', 'http://net-snmp.sourceforge.net/docs/man/snmpwalk.html' ],
[ 'URL', 'http://www.nothink.org/perl/snmpcheck/' ],
],
'Author' => 'Matteo Cantoni <goony[at]nothink.org>',
'License' => MSF_LICENSE
))
end
def run_host(ip)
begin
snmp = connect_snmp
#
#
#
fields_order = [
"Host IP", "Hostname", "Description", "Contact",
"Location", "Uptime snmp", "Uptime system",
"System date", "domain", "User accounts",
"Network information", "Network interfaces",
"Network IP", "Routing information",
"TCP connections and listening ports", "Listening UDP ports",
"Network services", "Share", "IIS server information",
"Storage information", "File system information",
"Device information", "Software components",
"Processes"
]
output_data = {}
output_data = {"Host IP"=>ip}
sysName = snmp.get_value('1.3.6.1.2.1.1.5.0').to_s
output_data["Hostname"] = sysName.strip
# print connected status after the first query so if there are
# any timeout or connectivity errors; the code would already
# have jumped to error handling where the error status is
# already being displayed.
print_good("#{ip}, Connected.")
sysDesc = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s
sysDesc.gsub!(/^\s+|\s+$|\n+|\r+/, ' ')
output_data["Description"] = sysDesc.strip
sysContact = snmp.get_value('1.3.6.1.2.1.1.4.0').to_s
output_data["Contact"] = sysContact.strip
sysLocation = snmp.get_value('1.3.6.1.2.1.1.6.0').to_s
output_data["Location"] = sysLocation.strip
sysUpTimeInstance = snmp.get_value('1.3.6.1.2.1.1.3.0').to_s
output_data["Uptime system"] = sysUpTimeInstance.strip
hrSystemUptime = snmp.get_value('1.3.6.1.2.1.25.1.1.0').to_s
output_data["Uptime snmp"] = hrSystemUptime.strip
hrSystemUptime = '-' if hrSystemUptime.to_s =~ /Null/
year = month = day = hour = minutes = seconds = tenths = 0
systemDate = snmp.get_value('1.3.6.1.2.1.25.1.2.0')
str = systemDate.to_s
if (str.empty? or str =~ /Null/ or str =~ /^noSuch/)
output_data["System date"] = '-'
else
# RFC 2579 - Textual Conventions for SMIv2
# http://www.faqs.org/rfcs/rfc2579.html
systemDate = systemDate.unpack('C*')
year = systemDate[0] * 256 + systemDate[1]
month = systemDate[2] || 0
day = systemDate[3] || 0
hour = systemDate[4] || 0
minutes = systemDate[5] || 0
seconds = systemDate[6] || 0
tenths = systemDate[7] || 0
output_data["System date"] = sprintf("%d-%d-%d %02d:%02d:%02d.%d", year, month, day, hour, minutes, seconds, tenths)
end
#
#
if (sysDesc =~ /Windows/)
domPrimaryDomain = snmp.get_value('1.3.6.1.4.1.77.1.4.1.0').to_s
output_data["Domain"] = domPrimaryDomain.strip
#
#
#
users = []
snmp.walk(["1.3.6.1.4.1.77.1.2.25.1.1","1.3.6.1.4.1.77.1.2.25.1"]) do |user,entry|
users.push([[user.value]])
end
if not users.empty?
output_data["User accounts"] = users
end
end
#
#
#
network_information = {}
ipForwarding = snmp.get_value('1.3.6.1.2.1.4.1.0')
if ipForwarding == 0 || ipForwarding == 2
ipForwarding = "no"
network_information["IP forwarding enabled"] = ipForwarding
elsif ipForwarding == 1
ipForwarding = "yes"
network_information["IP forwarding enabled"] = ipForwarding
end
ipDefaultTTL = snmp.get_value('1.3.6.1.2.1.4.2.0')
if ipDefaultTTL.to_s !~ /Null/
network_information["Default TTL"] = ipDefaultTTL
end
tcpInSegs = snmp.get_value('1.3.6.1.2.1.6.10.0')
if tcpInSegs.to_s !~ /Null/
network_information["TCP segments received"] = tcpInSegs
end
tcpOutSegs = snmp.get_value('1.3.6.1.2.1.6.11.0')
if tcpOutSegs.to_s !~ /Null/
network_information["TCP segments sent"] = tcpOutSegs
end
tcpRetransSegs = snmp.get_value('1.3.6.1.2.1.6.12.0')
if tcpRetransSegs.to_s !~ /Null/
network_information["TCP segments retrans"] = tcpRetransSegs
end
ipInReceives = snmp.get_value('1.3.6.1.2.1.4.3.0')
if ipInReceives.to_s !~ /Null/
network_information["Input datagrams"] = ipInReceives
end
ipInDelivers = snmp.get_value('1.3.6.1.2.1.4.9.0')
if ipInDelivers.to_s !~ /Null/
network_information["Delivered datagrams"]=ipInDelivers
end
ipOutRequests = snmp.get_value('1.3.6.1.2.1.4.10.0')
if ipOutRequests.to_s !~ /Null/
network_information["Output datagrams"]=ipOutRequests
end
if not network_information.empty?
output_data["Network information"] = network_information
end
#
#
#
network_interfaces = []
snmp.walk([
"1.3.6.1.2.1.2.2.1.1", "1.3.6.1.2.1.2.2.1.2", "1.3.6.1.2.1.2.2.1.6",
"1.3.6.1.2.1.2.2.1.3", "1.3.6.1.2.1.2.2.1.4", "1.3.6.1.2.1.2.2.1.5",
"1.3.6.1.2.1.2.2.1.10", "1.3.6.1.2.1.2.2.1.16", "1.3.6.1.2.1.2.2.1.7"
]) do |index,descr,mac,type,mtu,speed,inoc,outoc,status|
ifindex = index.value
ifdescr = descr.value
ifmac = mac.value.unpack("H2H2H2H2H2H2").join(":")
iftype = type.value
ifmtu = mtu.value
ifspeed = speed.value.to_i
ifinoc = inoc.value
ifoutoc = outoc.value
ifstatus = status.value
case iftype
when 1
iftype = "other"
when 2
iftype = "regular1822"
when 3
iftype = "hdh1822"
when 4
iftype = "ddn-x25"
when 5
iftype = "rfc877-x25"
when 6
iftype = "ethernet-csmacd"
when 7
iftype = "iso88023-csmacd"
when 8
iftype = "iso88024-tokenBus"
when 9
iftype = "iso88025-tokenRing"
when 10
iftype = "iso88026-man"
when 11
iftype = "starLan"
when 12
iftype = "proteon-10Mbit"
when 13
iftype = "proteon-80Mbit"
when 14
iftype = "hyperchannel"
when 15
iftype = "fddi"
when 16
iftype = "lapb"
when 17
iftype = "sdlc"
when 18
iftype = "ds1"
when 19
iftype = "e1"
when 20
iftype = "basicISDN"
when 21
iftype = "primaryISDN"
when 22
iftype = "propPointToPointSerial"
when 23
iftype = "ppp"
when 24
iftype = "softwareLoopback"
when 25
iftype = "eon"
when 26
iftype = "ethernet-3Mbit"
when 27
iftype = "nsip"
when 28
iftype = "slip"
when 29
iftype = "ultra"
when 30
iftype = "ds3"
when 31
iftype = "sip"
when 32
iftype = "frame-relay"
else
iftype = "unknown"
end
case ifstatus
when 1
ifstatus = "up"
when 2
ifstatus = "down"
when 3
ifstatus = "testing"
else
ifstatus = "unknown"
end
ifspeed = ifspeed / 1000000
network_interfaces.push({
"Interface" => "[ #{ifstatus} ] #{ifdescr}",
"Id" => ifindex,
"Mac Address" => ifmac,
"Type" => iftype,
"Speed" => "#{ifspeed} Mbps",
"MTU" => ifmtu,
"In octets" => ifinoc,
"Out octets" => ifoutoc
})
end
if not network_interfaces.empty?
output_data["Network interfaces"] = network_interfaces
end
#
#
#
network_ip = []
snmp.walk([
"1.3.6.1.2.1.4.20.1.2", "1.3.6.1.2.1.4.20.1.1",
"1.3.6.1.2.1.4.20.1.3", "1.3.6.1.2.1.4.20.1.4"
]) do |ifid,ipaddr,netmask,bcast|
network_ip.push([ifid.value, ipaddr.value, netmask.value, bcast.value])
end
if not network_ip.empty?
output_data["Network IP"] = [["Id","IP Address","Netmask","Broadcast"]] + network_ip
end
#
#
#
routing = []
snmp.walk([
"1.3.6.1.2.1.4.21.1.1", "1.3.6.1.2.1.4.21.1.7",
"1.3.6.1.2.1.4.21.1.11","1.3.6.1.2.1.4.21.1.3"
]) do |dest,hop,mask,metric|
if (metric.value.to_s.empty?)
metric.value = '-'
end
routing.push([dest.value, hop.value, mask.value, metric.value])
end
if not routing.empty?
output_data["Routing information"] = [["Destination","Next hop","Mask","Metric"]] + routing
end
#
#
#
tcp = []
snmp.walk([
"1.3.6.1.2.1.6.13.1.2","1.3.6.1.2.1.6.13.1.3","1.3.6.1.2.1.6.13.1.4",
"1.3.6.1.2.1.6.13.1.5","1.3.6.1.2.1.6.13.1.1"
]) do |ladd,lport,radd,rport,state|
if (ladd.value.to_s.empty? or ladd.value.to_s =~ /noSuchInstance/)
ladd = "-"
else
ladd = ladd.value
end
if (lport.value.to_s.empty? or lport.value.to_s =~ /noSuchInstance/)
lport = "-"
else
lport = lport.value
end
if (radd.value.to_s.empty? or radd.value.to_s =~ /noSuchInstance/)
radd = "-"
else
radd = radd.value
end
if (rport.value.to_s.empty? or rport.value.to_s =~ /noSuchInstance/)
rport = "-"
else
rport = rport.value
end
case state.value
when 1
state = "closed"
when 2
state = "listen"
when 3
state = "synSent"
when 4
state = "synReceived"
when 5
state = "established"
when 6
state = "finWait1"
when 7
state = "finWait2"
when 8
state = "closeWait"
when 9
state = "lastAck"
when 10
state = "closing"
when 11
state = "timeWait"
when 12
state = "deleteTCB"
else
state = "unknown"
end
tcp.push([ladd, lport, radd, rport, state])
end
if not tcp.empty?
output_data["TCP connections and listening ports"] = [["Local address","Local port","Remote address","Remote port","State"]] + tcp
end
#
#
#
udp = []
snmp.walk(["1.3.6.1.2.1.7.5.1.1","1.3.6.1.2.1.7.5.1.2"]) do |ladd,lport|
udp.push([ladd.value, lport.value])
end
if not udp.empty?
output_data["Listening UDP ports"] = [["Local address","Local port"]] + udp
end
#
#
#
if (sysDesc =~ /Windows/)
#
#
#
network_services = []
n = 0
snmp.walk(["1.3.6.1.4.1.77.1.2.3.1.1","1.3.6.1.4.1.77.1.2.3.1.2"]) do |name,installed|
network_services.push([n,name.value])
n+=1
end
if not network_services.empty?
output_data["Network services"] = [["Index","Name"]] + network_services
end
#
#
#
share = []
snmp.walk([
"1.3.6.1.4.1.77.1.2.27.1.1","1.3.6.1.4.1.77.1.2.27.1.2","1.3.6.1.4.1.77.1.2.27.1.3"
]) do |name,path,comment|
share.push({" Name"=>name.value, " Path"=>path.value, " Comment"=>comment.value})
end
if not share.empty?
output_data["Share"] = share
end
#
#
#
iis = {}
http_totalBytesSentLowWord = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.2.0')
if http_totalBytesSentLowWord.to_s !~ /Null/
iis["TotalBytesSentLowWord"] = http_totalBytesSentLowWord
end
http_totalBytesReceivedLowWord = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.4.0')
if http_totalBytesReceivedLowWord.to_s !~ /Null/
iis["TotalBytesReceivedLowWord"] = http_totalBytesReceivedLowWord
end
http_totalFilesSent = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.5.0')
if http_totalFilesSent.to_s !~ /Null/
iis["TotalFilesSent"] = http_totalFilesSent
end
http_currentAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.6.0')
if http_currentAnonymousUsers.to_s !~ /Null/
iis["CurrentAnonymousUsers"] = http_currentAnonymousUsers
end
http_currentNonAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.7.0')
if http_currentNonAnonymousUsers.to_s !~ /Null/
iis["CurrentNonAnonymousUsers"] = http_currentNonAnonymousUsers
end
http_totalAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.8.0')
if http_totalAnonymousUsers.to_s !~ /Null/
iis["TotalAnonymousUsers"] = http_totalAnonymousUsers
end
http_totalNonAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.9.0')
if http_totalNonAnonymousUsers.to_s !~ /Null/
iis["TotalNonAnonymousUsers"] = http_totalNonAnonymousUsers
end
http_maxAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.10.0')
if http_maxAnonymousUsers.to_s !~ /Null/
iis["MaxAnonymousUsers"] = http_maxAnonymousUsers
end
http_maxNonAnonymousUsers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.11.0')
if http_maxNonAnonymousUsers.to_s !~ /Null/
iis["MaxNonAnonymousUsers"] = http_maxNonAnonymousUsers
end
http_currentConnections = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.12.0')
if http_currentConnections.to_s !~ /Null/
iis["CurrentConnections"] = http_currentConnections
end
http_maxConnections = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.13.0')
if http_maxConnections.to_s !~ /Null/
iis["MaxConnections"] = http_maxConnections
end
http_connectionAttempts = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.14.0')
if http_connectionAttempts.to_s !~ /Null/
iis["ConnectionAttempts"] = http_connectionAttempts
end
http_logonAttempts = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.15.0')
if http_logonAttempts.to_s !~ /Null/
iis["LogonAttempts"] = http_logonAttempts
end
http_totalGets = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.16.0')
if http_totalGets.to_s !~ /Null/
iis["Gets"] = http_totalGets
end
http_totalPosts = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.17.0')
if http_totalPosts.to_s !~ /Null/
iis["Posts"] = http_totalPosts
end
http_totalHeads = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.18.0')
if http_totalHeads.to_s !~ /Null/
iis["Heads"] = http_totalHeads
end
http_totalOthers = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.19.0')
if http_totalOthers.to_s !~ /Null/
iis["Others"] = http_totalOthers
end
http_totalCGIRequests = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.20.0')
if http_totalCGIRequests.to_s !~ /Null/
iis["CGIRequests"] = http_totalCGIRequests
end
http_totalBGIRequests = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.21.0')
if http_totalBGIRequests.to_s !~ /Null/
iis["BGIRequests"] = http_totalBGIRequests
end
http_totalNotFoundErrors = snmp.get_value('1.3.6.1.4.1.311.1.7.3.1.22.0')
if http_totalNotFoundErrors.to_s !~ /Null/
iis["NotFoundErrors"] = http_totalNotFoundErrors
end
if not iis.empty?
output_data["IIS server information"] = iis
end
end
#
#
#
storage_information = []
snmp.walk([
"1.3.6.1.2.1.25.2.3.1.1", "1.3.6.1.2.1.25.2.3.1.2", "1.3.6.1.2.1.25.2.3.1.3",
"1.3.6.1.2.1.25.2.3.1.4", "1.3.6.1.2.1.25.2.3.1.5", "1.3.6.1.2.1.25.2.3.1.6"
]) do |index,type,descr,allocation,size,used|
case type.value.to_s
when /^1.3.6.1.2.1.25.2.1.1$/
type.value = "Other"
when /^1.3.6.1.2.1.25.2.1.2$/
type.value = "Ram"
when /^1.3.6.1.2.1.25.2.1.3$/
type.value = "Virtual Memory"
when /^1.3.6.1.2.1.25.2.1.4$/
type.value = "Fixed Disk"
when /^1.3.6.1.2.1.25.2.1.5$/
type.value = "Removable Disk"
when /^1.3.6.1.2.1.25.2.1.6$/
type.value = "Floppy Disk"
when /^1.3.6.1.2.1.25.2.1.7$/
type.value = "Compact Disc"
when /^1.3.6.1.2.1.25.2.1.8$/
type.value = "RamDisk"
when /^1.3.6.1.2.1.25.2.1.9$/
type.value = "Flash Memory"
when /^1.3.6.1.2.1.25.2.1.10$/
type.value = "Network Disk"
else
type.value = "unknown"
end
allocation.value = "unknown" if allocation.value.to_s =~ /noSuchInstance/
size.value = "unknown" if size.value.to_s =~ /noSuchInstance/
used.value = "unknown" if used.value.to_s =~ /noSuchInstance/
storage_information.push([[descr.value],[index.value],[type.value],[allocation.value],[size.value],[used.value]])
end
if not storage_information.empty?
storage = []
storage_information.each {|a,b,c,d,e,f|
s = {}
e = number_to_human_size(e,d)
f = number_to_human_size(f,d)
s["Description"]= a
s["Device id"] = b
s["Filesystem type"] = c
s["Device unit"] = d
s["Memory size"] = e
s["Memory used"] = f
storage.push(s)
}
output_data["Storage information"] = storage
end
#
#
#
file_system = {}
hrFSIndex = snmp.get_value('1.3.6.1.2.1.25.3.8.1.1.1')
if hrFSIndex.to_s !~ /Null/
file_system["Index"] = hrFSIndex
end
hrFSMountPoint = snmp.get_value('1.3.6.1.2.1.25.3.8.1.2.1')
if hrFSMountPoint.to_s !~ /Null/
file_system["Mount point"] = hrFSMountPoint
end
hrFSRemoteMountPoint = snmp.get_value('1.3.6.1.2.1.25.3.8.1.3.1')
if hrFSRemoteMountPoint.to_s !~ /Null/ and hrFSRemoteMountPoint.to_s !~ /^noSuch/
if hrFSRemoteMountPoint.empty?
hrFSRemoteMountPoint = '-'
end
file_system["Remote mount point"] = hrFSRemoteMountPoint
end
hrFSType = snmp.get_value('1.3.6.1.2.1.25.3.8.1.4.1')
case hrFSType.to_s
when /^1.3.6.1.2.1.25.3.9.1$/
hrFSType = "Other"
when /^1.3.6.1.2.1.25.3.9.2$/
hrFSType = "Unknown"
when /^1.3.6.1.2.1.25.3.9.3$/
hrFSType = "BerkeleyFFS"
when /^1.3.6.1.2.1.25.3.9.4$/
hrFSType = "Sys5FS"
when /^1.3.6.1.2.1.25.3.9.5$/
hrFSType = "Fat"
when /^1.3.6.1.2.1.25.3.9.6$/
hrFSType = "HPFS"
when /^1.3.6.1.2.1.25.3.9.7$/
hrFSType = "HFS"
when /^1.3.6.1.2.1.25.3.9.8$/
hrFSType = "MFS"
when /^1.3.6.1.2.1.25.3.9.9$/
hrFSType = "NTFS"
when /^1.3.6.1.2.1.25.3.9.10$/
hrFSType = "VNode"
when /^1.3.6.1.2.1.25.3.9.11$/
hrFSType = "Journaled"
when /^1.3.6.1.2.1.25.3.9.12$/
hrFSType = "iso9660"
when /^1.3.6.1.2.1.25.3.9.13$/
hrFSType = "RockRidge"
when /^1.3.6.1.2.1.25.3.9.14$/
hrFSType = "NFS"
when /^1.3.6.1.2.1.25.3.9.15$/
hrFSType = "Netware"
when /^1.3.6.1.2.1.25.3.9.16$/
hrFSType = "AFS"
when /^1.3.6.1.2.1.25.3.9.17$/
hrFSType = "DFS"
when /^1.3.6.1.2.1.25.3.9.18$/
hrFSType = "Appleshare"
when /^1.3.6.1.2.1.25.3.9.19$/
hrFSType = "RFS"
when /^1.3.6.1.2.1.25.3.9.20$/
hrFSType = "DGCFS"
when /^1.3.6.1.2.1.25.3.9.21$/
hrFSType = "BFS"
when /^1.3.6.1.2.1.25.3.9.22$/
hrFSType = "FAT32"
when /^1.3.6.1.2.1.25.3.9.23$/
hrFSType = "LinuxExt2"
else
hrFSType = "Null"
end
if hrFSType.to_s !~ /Null/
file_system["Type"] = hrFSType
end
hrFSAccess = snmp.get_value('1.3.6.1.2.1.25.3.8.1.5.1')
if hrFSAccess.to_s !~ /Null/
file_system["Access"] = hrFSAccess
end
hrFSBootable = snmp.get_value('1.3.6.1.2.1.25.3.8.1.6.1')
if hrFSBootable.to_s !~ /Null/
file_system["Bootable"] = hrFSBootable
end
if not file_system.empty?
output_data["File system information"] = file_system
end
#
#
#
device_information = []
snmp.walk([
"1.3.6.1.2.1.25.3.2.1.1", "1.3.6.1.2.1.25.3.2.1.2",
"1.3.6.1.2.1.25.3.2.1.5", "1.3.6.1.2.1.25.3.2.1.3"
]) do |index,type,status,descr|
case type.value.to_s
when /^1.3.6.1.2.1.25.3.1.1$/
type.value = "Other"
when /^1.3.6.1.2.1.25.3.1.2$/
type.value = "Unknown"
when /^1.3.6.1.2.1.25.3.1.3$/
type.value = "Processor"
when /^1.3.6.1.2.1.25.3.1.4$/
type.value = "Network"
when /^1.3.6.1.2.1.25.3.1.5$/
type.value = "Printer"
when /^1.3.6.1.2.1.25.3.1.6$/
type.value = "Disk Storage"
when /^1.3.6.1.2.1.25.3.1.10$/
type.value = "Video"
when /^1.3.6.1.2.1.25.3.1.11$/
type.value = "Audio"
when /^1.3.6.1.2.1.25.3.1.12$/
type.value = "Coprocessor"
when /^1.3.6.1.2.1.25.3.1.13$/
type.value = "Keyboard"
when /^1.3.6.1.2.1.25.3.1.14$/
type.value = "Modem"
when /^1.3.6.1.2.1.25.3.1.15$/
type.value = "Parallel Port"
when /^1.3.6.1.2.1.25.3.1.16$/
type.value = "Pointing"
when /^1.3.6.1.2.1.25.3.1.17$/
type.value = "Serial Port"
when /^1.3.6.1.2.1.25.3.1.18$/
type.value = "Tape"
when /^1.3.6.1.2.1.25.3.1.19$/
type.value = "Clock"
when /^1.3.6.1.2.1.25.3.1.20$/
type.value = "Volatile Memory"
when /^1.3.6.1.2.1.25.3.1.21$/
type.value = "Non Volatile Memory"
else
type.value = "unknown"
end
case status.value
when 1
status.value = "unknown"
when 2
status.value = "running"
when 3
status.value = "warning"
when 4
status.value = "testing"
when 5
status.value = "down"
else
status.value = "unknown"
end
descr.value = "unknown" if descr.value.to_s =~ /noSuchInstance/
device_information.push([index.value, type.value, status.value, descr.value])
end
if not device_information.empty?
output_data["Device information"] = [["Id","Type","Status","Descr"]] + device_information
end
#
#
#
software_list = []
snmp.walk(["1.3.6.1.2.1.25.6.3.1.1","1.3.6.1.2.1.25.6.3.1.2"]) do |index,name|
software_list.push([index.value,name.value])
end
if not software_list.empty?
output_data["Software components"] = [["Index","Name"]] + software_list
end
#
#
#
process_interfaces = []
snmp.walk([
"1.3.6.1.2.1.25.4.2.1.1", "1.3.6.1.2.1.25.4.2.1.2", "1.3.6.1.2.1.25.4.2.1.4",
"1.3.6.1.2.1.25.4.2.1.5", "1.3.6.1.2.1.25.4.2.1.7"
]) do |id,name,path,param,status|
if status.value == 1
status.value = "running"
elsif status.value == 2
status.value = "runnable"
else
status.value = "unknown"
end
process_interfaces.push([id.value, status.value, name.value, path.value, param.value])
end
if not process_interfaces.empty?
output_data["Processes"] = [["Id","Status","Name","Path","Parameters"]] + process_interfaces
end
#
#
#
print_line("\n[*] System information:\n")
line = ""
width = 30 # name field width
twidth = 32 # table like display cell width
fields_order.each {|k|
if not output_data.has_key?(k)
next
end
v = output_data[k]
case v
when Array
content = ""
v.each{ |a|
case a
when Hash
a.each{ |sk, sv|
sk = truncate_to_twidth(sk, twidth)
content << sprintf("%s%s: %s\n", sk, " "*([0,width-sk.length].max), sv)
}
content << "\n"
when Array
a.each { |sv|
sv = sv.to_s.strip
# I don't like cutting info
#sv = truncate_to_twidth(sv, twidth)
content << sprintf("%-20s", sv)
}
content << "\n"
else
content << sprintf(" %s\n", a)
content << "\n"
end
}
report_note(
:host => ip,
:proto => 'udp',
:sname => 'snmp',
:port => datastore['RPORT'].to_i,
:type => "snmp.#{k}",
:data => content
)
line << "\n[*] #{k}:\n\n#{content}"
when Hash
content = ""
v.each{ |sk, sv|
sk = truncate_to_twidth(sk,twidth)
content << sprintf("%s%s: %s\n", sk, " "*([0,width-sk.length].max), sv)
}
report_note(
:host => ip,
:proto => 'udp',
:sname => 'snmp',
:port => datastore['RPORT'].to_i,
:type => "snmp.#{k}",
:data => content
)
line << "\n[*] #{k}:\n\n#{content}"
content << "\n"
else
if (v.nil? or v.empty? or v =~ /Null/)
v = '-'
end
report_note(
:host => ip,
:proto => 'udp',
:sname => 'snmp',
:port => datastore['RPORT'].to_i,
:type => "snmp.#{k}",
:data => v
)
k = truncate_to_twidth(k,twidth)
line << sprintf("%s%s: %s\n", k, " "*([0,width-k.length].max), v)
end
}
print_line(line)
#
#
#
print_line('')
rescue SNMP::RequestTimeout
print_error("#{ip} SNMP request timeout.")
rescue Rex::ConnectionError
print_error("#{ip} Connection refused.")
rescue SNMP::InvalidIpAddress
print_error("#{ip} Invalid IP Address. Check it with 'snmpwalk tool'.")
rescue SNMP::UnsupportedVersion
print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.")
rescue ::Interrupt
raise $!
rescue ::Exception => e
print_error("Unknown error: #{e.class} #{e}")
elog("Unknown error: #{e.class} #{e}")
elog("Call stack:\n#{e.backtrace.join "\n"}")
ensure
disconnect_snmp
end
end
def truncate_to_twidth(string,twidth)
string.slice(0..twidth-2)
end
def number_to_human_size(size,unit)
size = size.first.to_i * unit.first.to_i
if size < 1024
"#{size} bytes"
elsif size < 1024.0 * 1024.0
"%.02f KB" % (size / 1024.0)
elsif size < 1024.0 * 1024.0 * 1024.0
"%.02f MB" % (size / 1024.0 / 1024.0)
else
"%.02f GB" % (size / 1024.0 / 1024.0 / 1024.0)
end
end
end