986 lines
24 KiB
Ruby
986 lines
24 KiB
Ruby
##
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
# web site for more information on licensing and terms of use.
|
|
# http://metasploit.com/
|
|
##
|
|
|
|
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/)
|
|
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]
|
|
day = systemDate[3]
|
|
hour = systemDate[4]
|
|
minutes = systemDate[5]
|
|
seconds = systemDate[6]
|
|
tenths = systemDate[7]
|
|
output_data["System date"] = sprintf("%d-%d-%d %02d:%02d:%02d.%d", year, month, day, hour, minutes, seconds, tenths)
|
|
end
|
|
|
|
#
|
|
#
|
|
if (sysDesc =~ /Windows/)
|
|
usersLine = ""
|
|
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/
|
|
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
|
|
vprint_status("#{ip} SNMP request timeout.")
|
|
rescue Rex::ConnectionError
|
|
print_status("#{ip} Connection refused.")
|
|
rescue SNMP::InvalidIpAddress
|
|
print_status("#{ip} Invalid IP Address. Check it with 'snmpwalk tool'.")
|
|
rescue SNMP::UnsupportedVersion
|
|
print_status("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.")
|
|
rescue ::Interrupt
|
|
raise $!
|
|
rescue ::Exception => e
|
|
print_status("Unknown error: #{e.class} #{e}")
|
|
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
|