massive changes to the database api. Auxiliary::Report is now just a bunch of stubs into the main DBManager, most aux modules should just work, but they haven't all been tested. introduces a get_auth_info method for pulling credentials out of the db. other db api methods should be more standardized now. cross your fingers
git-svn-id: file:///home/svn/framework3/trunk@8028 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
c3038d4027
commit
02eb7ab80d
|
@ -8,31 +8,6 @@ module Msf
|
||||||
|
|
||||||
module Auxiliary::Report
|
module Auxiliary::Report
|
||||||
|
|
||||||
|
|
||||||
module HttpClients
|
|
||||||
IE = "MSIE"
|
|
||||||
FF = "Firefox"
|
|
||||||
SAFARI = "Safari"
|
|
||||||
OPERA = "Opera"
|
|
||||||
|
|
||||||
UNKNOWN = "Unknown"
|
|
||||||
end
|
|
||||||
module OperatingSystems
|
|
||||||
LINUX = "Linux"
|
|
||||||
MAC_OSX = "MacOSX"
|
|
||||||
WINDOWS = "Windows"
|
|
||||||
|
|
||||||
module WindowsVersions
|
|
||||||
XP = "XP"
|
|
||||||
TWOK = "2000"
|
|
||||||
TWOK3 = "2003"
|
|
||||||
VISTA = "Vista"
|
|
||||||
end
|
|
||||||
|
|
||||||
UNKNOWN = "Unknown"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# Shortcut method for detecting when the DB is active
|
# Shortcut method for detecting when the DB is active
|
||||||
def db
|
def db
|
||||||
framework.db.active
|
framework.db.active
|
||||||
|
@ -48,22 +23,12 @@ module Auxiliary::Report
|
||||||
#
|
#
|
||||||
def report_host(opts)
|
def report_host(opts)
|
||||||
return if not db
|
return if not db
|
||||||
addr = opts[:host] || return
|
framework.db.report_host(opts)
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
host = nil
|
|
||||||
|
|
||||||
opts.delete(:host)
|
|
||||||
if (opts.length > 0)
|
|
||||||
host = framework.db.report_host(self, addr, opts)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_host(addr)
|
def get_host(addr)
|
||||||
return nil if not db
|
return if not db
|
||||||
framework.db.get_host(self, addr)
|
framework.db.get_host(addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -78,17 +43,12 @@ module Auxiliary::Report
|
||||||
#
|
#
|
||||||
def report_client(opts={})
|
def report_client(opts={})
|
||||||
return if not db
|
return if not db
|
||||||
addr = opts.delete(:host) || return
|
framework.db.report_client(opts)
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
cli = framework.db.report_client(self, addr, opts)
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_client(addr, ua_string)
|
def get_client(opts={})
|
||||||
return nil if not db
|
return if not db
|
||||||
framework.db.get_client(self, addr, ua_string)
|
framework.db.get_client(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -96,114 +56,27 @@ module Auxiliary::Report
|
||||||
#
|
#
|
||||||
def report_service(opts={})
|
def report_service(opts={})
|
||||||
return if not db
|
return if not db
|
||||||
addr = opts[:host] || return
|
framework.db.report_service(opts)
|
||||||
port = opts[:port] || return
|
|
||||||
proto = opts[:proto] || 'tcp'
|
|
||||||
name = opts[:name]
|
|
||||||
state = opts[:state] || 'open'
|
|
||||||
info = opts[:info]
|
|
||||||
hname = opts[:host_name]
|
|
||||||
maddr = opts[:host_mac]
|
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
|
|
||||||
serv = framework.db.report_service_state(
|
|
||||||
self,
|
|
||||||
addr,
|
|
||||||
proto,
|
|
||||||
port,
|
|
||||||
state
|
|
||||||
)
|
|
||||||
|
|
||||||
changed = false
|
|
||||||
if(hname)
|
|
||||||
self.host.name = hname
|
|
||||||
changed = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if(maddr)
|
|
||||||
self.host.mac = maddr
|
|
||||||
changed = true
|
|
||||||
end
|
|
||||||
serv.host.save! if changed
|
|
||||||
|
|
||||||
|
|
||||||
changed = false
|
|
||||||
if (name and name.length > 1)
|
|
||||||
serv.name = name.downcase
|
|
||||||
changed = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if (info and info.length > 1)
|
|
||||||
serv.info = info
|
|
||||||
changed = true
|
|
||||||
end
|
|
||||||
|
|
||||||
serv.save! if changed
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_note(opts={})
|
def report_note(opts={})
|
||||||
return if not db
|
return if not db
|
||||||
addr = opts[:host] || return
|
framework.db.report_note(opts)
|
||||||
ntype = opts[:type] || return
|
|
||||||
data = opts[:data] || return
|
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
host = framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
note = framework.db.get_note(self, host, ntype, data)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_vuln_service(opts={})
|
|
||||||
return if not db
|
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
serv = report_service(opts)
|
|
||||||
return if not serv
|
|
||||||
|
|
||||||
vname = opts[:vname]
|
|
||||||
vdata = opts[:vdata] || ''
|
|
||||||
|
|
||||||
host = serv.host
|
|
||||||
vuln = framework.db.get_vuln(self, host, serv, vname, vdata)
|
|
||||||
|
|
||||||
framework.db.vuln_add_refs(self, vuln, opts[:refs])
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def report_vuln_host(opts={})
|
|
||||||
return if not db
|
|
||||||
addr = opts[:host] || return
|
|
||||||
|
|
||||||
framework.db.queue Proc.new {
|
|
||||||
host = framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
vname = opts[:vname]
|
|
||||||
vdata = opts[:vdata] || ''
|
|
||||||
|
|
||||||
vuln = framework.db.get_vuln(self, host, nil, vname, vdata)
|
|
||||||
|
|
||||||
framework.db.vuln_add_refs(self, vuln, opts[:refs])
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def report_auth_info(opts={})
|
def report_auth_info(opts={})
|
||||||
return if not db
|
return if not db
|
||||||
addr = opts[:host] || return
|
framework.db.report_auth_info(opts)
|
||||||
data = opts[:proto] || return
|
|
||||||
|
|
||||||
opts[:type] = "auth_#{opts[:proto]}"
|
|
||||||
opts[:data] =
|
|
||||||
"AUTH #{ opts[:targ_host] || 'unknown' }:#{ opts[:targ_port] || 'unknown' } " +
|
|
||||||
"#{opts[:user] || "<NULL>"} #{opts[:pass] || "<NULL>" } #{opts[:extra]}"
|
|
||||||
print_status("Recording successful #{data} credentials for #{addr}")
|
|
||||||
report_note(opts)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_note(host, ntype)
|
def report_vuln_service(opts={})
|
||||||
return if not db
|
return if not db
|
||||||
framework.db.find_note(host, ntype)
|
framework.db.report_vuln_service(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def report_vuln_host(opts={})
|
||||||
|
return if not db
|
||||||
|
framework.db.report_vuln_host(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,28 @@ RankingName =
|
||||||
ExcellentRanking => "excellent"
|
ExcellentRanking => "excellent"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module HttpClients
|
||||||
|
IE = "MSIE"
|
||||||
|
FF = "Firefox"
|
||||||
|
SAFARI = "Safari"
|
||||||
|
OPERA = "Opera"
|
||||||
|
|
||||||
|
UNKNOWN = "Unknown"
|
||||||
|
end
|
||||||
|
module OperatingSystems
|
||||||
|
LINUX = "Linux"
|
||||||
|
MAC_OSX = "MacOSX"
|
||||||
|
WINDOWS = "Windows"
|
||||||
|
|
||||||
|
module WindowsVersions
|
||||||
|
XP = "XP"
|
||||||
|
TWOK = "2000"
|
||||||
|
TWOK3 = "2003"
|
||||||
|
VISTA = "Vista"
|
||||||
|
end
|
||||||
|
|
||||||
|
UNKNOWN = "Unknown"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -65,4 +87,4 @@ LICENSES =
|
||||||
BSD_LICENSE,
|
BSD_LICENSE,
|
||||||
ARTISTIC_LICENSE,
|
ARTISTIC_LICENSE,
|
||||||
UNKNOWN_LICENSE
|
UNKNOWN_LICENSE
|
||||||
]
|
]
|
||||||
|
|
|
@ -50,47 +50,47 @@ module DatabaseEvent
|
||||||
#
|
#
|
||||||
# Called when an existing host's state changes
|
# Called when an existing host's state changes
|
||||||
#
|
#
|
||||||
def on_db_host_state(context, host, ostate)
|
def on_db_host_state(host, ostate)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when an existing service's state changes
|
# Called when an existing service's state changes
|
||||||
#
|
#
|
||||||
def on_db_service_state(context, host, port, ostate)
|
def on_db_service_state(host, port, ostate)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when a new host is added to the database. The host parameter is
|
# Called when a new host is added to the database. The host parameter is
|
||||||
# of type Host.
|
# of type Host.
|
||||||
#
|
#
|
||||||
def on_db_host(context, host)
|
def on_db_host(host)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when a new client is added to the database. The client
|
# Called when a new client is added to the database. The client
|
||||||
# parameter is of type Client.
|
# parameter is of type Client.
|
||||||
#
|
#
|
||||||
def on_db_client(context, client)
|
def on_db_client(client)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when a new service is added to the database. The service
|
# Called when a new service is added to the database. The service
|
||||||
# parameter is of type Service.
|
# parameter is of type Service.
|
||||||
#
|
#
|
||||||
def on_db_service(context, service)
|
def on_db_service(service)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when an applicable vulnerability is found for a service. The vuln
|
# Called when an applicable vulnerability is found for a service. The vuln
|
||||||
# parameter is of type Vuln.
|
# parameter is of type Vuln.
|
||||||
#
|
#
|
||||||
def on_db_vuln(context, vuln)
|
def on_db_vuln(vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Called when a new reference is created.
|
# Called when a new reference is created.
|
||||||
#
|
#
|
||||||
def on_db_ref(context, ref)
|
def on_db_ref(ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -109,42 +109,52 @@ class DBManager
|
||||||
res = Host.find(:all)
|
res = Host.find(:all)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Reports a host as being in a given state by address.
|
|
||||||
#
|
|
||||||
def report_host_state(mod, addr, state, context = nil)
|
|
||||||
|
|
||||||
# TODO: use the current thread's Comm to find the host
|
def default_workspace
|
||||||
comm = ''
|
Workspace.default
|
||||||
host = get_host(context, addr, comm)
|
end
|
||||||
|
|
||||||
ostate = host.state
|
def find_workspace(name)
|
||||||
host.state = state
|
Workspace.find_by_name(name)
|
||||||
host.save
|
|
||||||
|
|
||||||
framework.events.on_db_host_state(context, host, ostate)
|
|
||||||
return host
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Report a host's attributes such as operating system and service pack
|
# Creates a new workspace in the database
|
||||||
#
|
#
|
||||||
# At the time of this writing, the opts parameter can contain:
|
def add_workspace(name)
|
||||||
# :state -- one of the Msf::HostState constants
|
Workspace.find_or_create_by_name(name)
|
||||||
# :os_name -- one of the Msf::Auxiliary::Report::OperatingSystems constants
|
end
|
||||||
# :os_flavor -- something like "XP" or "Gentoo"
|
|
||||||
# :os_sp -- something like "SP2"
|
|
||||||
# :os_lang -- something like "English" or "French"
|
|
||||||
# :arch -- one of the ARCH_* constants
|
|
||||||
#
|
|
||||||
# See <MSF install dir>/data/sql/*.sql for more info
|
|
||||||
#
|
|
||||||
def report_host(mod, addr, opts = {}, context = nil)
|
|
||||||
|
|
||||||
report_host_state(mod, addr, opts[:state] || Msf::HostState::Alive)
|
def workspaces
|
||||||
opts.delete(:state)
|
Workspace.find(:all)
|
||||||
|
end
|
||||||
|
|
||||||
host = get_host(context, addr, '')
|
|
||||||
|
#
|
||||||
|
# Find a host. Performs no database writes.
|
||||||
|
#
|
||||||
|
def get_host(opts)
|
||||||
|
if opts.kind_of? Host
|
||||||
|
return opts
|
||||||
|
elsif opts.kind_of? String
|
||||||
|
address = opts
|
||||||
|
else
|
||||||
|
address = opts[:addr] || opts[:address] || opts[:host] || return
|
||||||
|
return address if address.kind_of? Host
|
||||||
|
end
|
||||||
|
host = workspace.hosts.find_by_address(address)
|
||||||
|
return host
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_initialize_host(opts)
|
||||||
|
addr = opts.delete(:host) || return
|
||||||
|
return addr if addr.kind_of? Host
|
||||||
|
|
||||||
|
#if opts[:comm] and opts[:comm].length > 0
|
||||||
|
# host = workspace.hosts.find_or_initialize_by_address_and_comm(addr, opts[:comm])
|
||||||
|
#else
|
||||||
|
host = workspace.hosts.find_or_initialize_by_address(addr)
|
||||||
|
#end
|
||||||
|
|
||||||
opts.each { |k,v|
|
opts.each { |k,v|
|
||||||
if (host.attribute_names.include?(k.to_s))
|
if (host.attribute_names.include?(k.to_s))
|
||||||
|
@ -153,67 +163,62 @@ class DBManager
|
||||||
dlog("Unknown attribute for Host: #{k}")
|
dlog("Unknown attribute for Host: #{k}")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
host.state = HostState::Unknown if not host.state
|
||||||
host.save
|
host.comm = '' if not host.comm
|
||||||
|
host.workspace = workspace if not host.workspace
|
||||||
|
|
||||||
return host
|
return host
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Exactly like report_host but ensures that the returned Host has been
|
||||||
|
# written to the database. Returns nil on error.
|
||||||
#
|
#
|
||||||
# Report a client running on a host.
|
def find_or_create_host(opts)
|
||||||
#
|
host = find_or_initialize_host(opts)
|
||||||
# opts must contain :ua_string
|
|
||||||
# opts can contain :ua_name and :ua_ver
|
if (host and host.changed?)
|
||||||
#
|
host.created = Time.now
|
||||||
def report_client(mod, addr, opts = {}, context = nil)
|
task = framework.db.queue( Proc.new { host.save! } )
|
||||||
if opts[:ua_string].nil?
|
task.wait
|
||||||
elog("report_client requires a ua_string", 'db', LEV_0, caller)
|
if task.status != :done
|
||||||
return
|
return nil
|
||||||
end
|
|
||||||
# TODO: use the current thread's Comm to find the host
|
|
||||||
comm = ''
|
|
||||||
host = get_host(context, addr, comm)
|
|
||||||
cli = get_client(context, host, opts[:ua_string])
|
|
||||||
|
|
||||||
opts.each { |k,v|
|
|
||||||
if (cli.attribute_names.include?(k.to_s))
|
|
||||||
cli[k] = v
|
|
||||||
else
|
|
||||||
dlog("Unknown attribute for Client: #{k}")
|
|
||||||
end
|
end
|
||||||
}
|
|
||||||
cli.save
|
|
||||||
return cli
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# This method reports a host's service state.
|
|
||||||
#
|
|
||||||
def report_service_state(mod, addr, proto, port, state, context = nil)
|
|
||||||
|
|
||||||
# TODO: use the current thread's Comm to find the host
|
|
||||||
comm = ''
|
|
||||||
host = get_host(context, addr, comm)
|
|
||||||
port = get_service(context, host, proto, port, state)
|
|
||||||
|
|
||||||
ostate = port.state
|
|
||||||
port.state = state
|
|
||||||
port.save
|
|
||||||
|
|
||||||
if (ostate != state)
|
|
||||||
framework.events.on_db_service_state(context, host, port, ostate)
|
|
||||||
end
|
end
|
||||||
|
return host
|
||||||
return port
|
|
||||||
end
|
|
||||||
|
|
||||||
def workspaces
|
|
||||||
Workspace.find(:all)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# This method iterates the hosts table calling the supplied block with the
|
# Report a host's attributes such as operating system and service pack
|
||||||
# host instance of each entry.
|
#
|
||||||
|
# The opts parameter MUST contain
|
||||||
|
# :address -- the host's ip address
|
||||||
|
#
|
||||||
|
# The opts parameter can contain:
|
||||||
|
# :state -- one of the Msf::HostState constants
|
||||||
|
# :os_name -- one of the Msf::OperatingSystems constants
|
||||||
|
# :os_flavor -- something like "XP" or "Gentoo"
|
||||||
|
# :os_sp -- something like "SP2"
|
||||||
|
# :os_lang -- something like "English" or "French"
|
||||||
|
# :arch -- one of the ARCH_* constants
|
||||||
|
# :mac -- the host's MAC address
|
||||||
|
#
|
||||||
|
# Returns a Host that may not have been written to the database yet.
|
||||||
|
# If you need to be sure that the insert succeeded, use
|
||||||
|
# find_or_create_host.
|
||||||
|
#
|
||||||
|
def report_host(opts)
|
||||||
|
host = find_or_initialize_host(opts)
|
||||||
|
if (host.changed?)
|
||||||
|
host.created = Time.now
|
||||||
|
framework.db.queue( Proc.new { host.save! } )
|
||||||
|
end
|
||||||
|
return host
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Iterates over the hosts table calling the supplied block with the host
|
||||||
|
# instance of each entry.
|
||||||
#
|
#
|
||||||
def each_host(&block)
|
def each_host(&block)
|
||||||
workspace.hosts.each do |host|
|
workspace.hosts.each do |host|
|
||||||
|
@ -222,7 +227,7 @@ class DBManager
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# This methods returns a list of all hosts in the database
|
# Returns a list of all hosts in the database
|
||||||
#
|
#
|
||||||
def hosts(only_up = false, addresses = nil)
|
def hosts(only_up = false, addresses = nil)
|
||||||
conditions = {}
|
conditions = {}
|
||||||
|
@ -231,8 +236,63 @@ class DBManager
|
||||||
workspace.hosts.all(:conditions => conditions, :order => :address)
|
workspace.hosts.all(:conditions => conditions, :order => :address)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def find_or_initialize_service(opts)
|
||||||
|
addr = opts.delete(:host) || return
|
||||||
|
host = find_or_create_host({:host => addr})
|
||||||
|
service = host.services.find_or_initialize_by_port_and_proto(opts[:port], opts[:proto])
|
||||||
|
opts.each { |k,v|
|
||||||
|
if (service.attribute_names.include?(k.to_s))
|
||||||
|
service[k] = v
|
||||||
|
else
|
||||||
|
dlog("Unknown attribute for Service: #{k}")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return service
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create_service(opts)
|
||||||
|
service = find_or_initialize_service(opts)
|
||||||
|
if (service and service.changed?)
|
||||||
|
service.created = Time.now
|
||||||
|
task = framework.db.queue(Proc.new { service.save! })
|
||||||
|
task.wait
|
||||||
|
if task.status != :done
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return service
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Record a service in the database.
|
||||||
#
|
#
|
||||||
# This method iterates the services table calling the supplied block with the
|
# opts must contain
|
||||||
|
# :port -- the port where this service listens
|
||||||
|
# :proto -- the protocol (e.g. tcp, udp...)
|
||||||
|
#
|
||||||
|
# Returns a Service. Not guaranteed to have been written to the db yet.
|
||||||
|
# If you need to be sure that the insert succeeded, use
|
||||||
|
# find_or_create_service.
|
||||||
|
#
|
||||||
|
def report_service(opts)
|
||||||
|
service = find_or_initialize_service(opts)
|
||||||
|
if (service and service.changed?)
|
||||||
|
service.created = Time.now
|
||||||
|
framework.db.queue(Proc.new { service.save! })
|
||||||
|
end
|
||||||
|
return service
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_service(host, proto, port)
|
||||||
|
host = get_host(host)
|
||||||
|
return if not host
|
||||||
|
return host.services.find_by_proto_and_port(proto, port)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Iterates over the services table calling the supplied block with the
|
||||||
# service instance of each entry.
|
# service instance of each entry.
|
||||||
#
|
#
|
||||||
def each_service(&block)
|
def each_service(&block)
|
||||||
|
@ -242,7 +302,7 @@ class DBManager
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# This methods returns a list of all services in the database
|
# Returns a list of all services in the database
|
||||||
#
|
#
|
||||||
def services(only_up = false, proto = nil, addresses = nil, ports = nil, names = nil)
|
def services(only_up = false, proto = nil, addresses = nil, ports = nil, names = nil)
|
||||||
conditions = {}
|
conditions = {}
|
||||||
|
@ -254,6 +314,66 @@ class DBManager
|
||||||
workspace.services.all(:include => :host, :conditions => conditions, :order => "hosts.address, port")
|
workspace.services.all(:include => :host, :conditions => conditions, :order => "hosts.address, port")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def get_client(opts)
|
||||||
|
host = get_host(:host => opts[:host]) || return
|
||||||
|
client = host.clients.find(:first, :conditions => {:ua_string => opts[:ua_string]})
|
||||||
|
return client
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_initialize_client(opts)
|
||||||
|
host = find_or_create_host(:host => opts.delete(:host))
|
||||||
|
return if not host
|
||||||
|
client = host.clients.find_or_initialize_by_ua_string(opts[:ua_string])
|
||||||
|
opts.each { |k,v|
|
||||||
|
if (client.attribute_names.include?(k.to_s))
|
||||||
|
client[k] = v
|
||||||
|
else
|
||||||
|
dlog("Unknown attribute for Client: #{k}")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return client
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create_client(opts)
|
||||||
|
client = find_or_initialize_client(opts)
|
||||||
|
|
||||||
|
if (client and client.changed?)
|
||||||
|
client.created = Time.now
|
||||||
|
task = framework.db.queue(Proc.new { client.save! })
|
||||||
|
task.wait
|
||||||
|
if task.status != :done
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return client
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Report a client running on a host.
|
||||||
|
#
|
||||||
|
# opts must contain
|
||||||
|
# :ua_string -- the value of the User-Agent header
|
||||||
|
#
|
||||||
|
# opts can contain
|
||||||
|
# :ua_name -- one of the Msf::HttpClients constants
|
||||||
|
# :ua_ver -- detected version of the given client
|
||||||
|
#
|
||||||
|
# Returns a Client. Not guaranteed to have been written to the database.
|
||||||
|
# If you need to be sure that the insert succeeded, use
|
||||||
|
# find_or_create_client.
|
||||||
|
#
|
||||||
|
def report_client(opts)
|
||||||
|
client = find_or_initialize_client(opts)
|
||||||
|
if (client and client.changed?)
|
||||||
|
client.created = Time.now
|
||||||
|
framework.db.queue(Proc.new { client.save! })
|
||||||
|
end
|
||||||
|
|
||||||
|
return client
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# This method iterates the vulns table calling the supplied block with the
|
# This method iterates the vulns table calling the supplied block with the
|
||||||
# vuln instance of each entry.
|
# vuln instance of each entry.
|
||||||
|
@ -282,12 +402,50 @@ class DBManager
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find a note matching this host address and note type
|
# Find or create a note matching this type/data
|
||||||
#
|
#
|
||||||
def find_note(address, ntype)
|
def find_or_create_note(opts)
|
||||||
host = workspace.hosts.find_by_address(address)
|
note = find_or_initialize_note(opts)
|
||||||
return nil if host.nil?
|
if (note.changed?)
|
||||||
host.notes.find_by_ntype(ntype)
|
note.created = Time.now
|
||||||
|
task = framework.db.queue(Proc.new {note.save!})
|
||||||
|
task.wait
|
||||||
|
if (task.status != :done)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return note
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_initialize_note(opts)
|
||||||
|
ntype = opts.delete(:type) || opts.delete(:ntype) || return
|
||||||
|
data = opts[:data] || return
|
||||||
|
|
||||||
|
note = workspace.notes.find_or_initialize_by_ntype_and_data(ntype, data.to_yaml)
|
||||||
|
p note
|
||||||
|
|
||||||
|
if opts[:host]
|
||||||
|
if opts[:host].kind_of? Host
|
||||||
|
host = opts[:host].dup
|
||||||
|
else
|
||||||
|
host = find_or_create_host({:host => opts[:host]})
|
||||||
|
end
|
||||||
|
note.host = host
|
||||||
|
end
|
||||||
|
if opts[:service] and opts[:service].kind_of? Service
|
||||||
|
note.service = service
|
||||||
|
end
|
||||||
|
|
||||||
|
return note
|
||||||
|
end
|
||||||
|
|
||||||
|
def report_note(opts)
|
||||||
|
note = find_or_initialize_note(opts)
|
||||||
|
if (note and note.changed?)
|
||||||
|
note.created = Time.now
|
||||||
|
task = framework.db.queue(Proc.new {note.save!})
|
||||||
|
end
|
||||||
|
return note
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -297,141 +455,150 @@ class DBManager
|
||||||
workspace.notes
|
workspace.notes
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_workspace
|
###
|
||||||
Workspace.default
|
# Specific notes
|
||||||
end
|
###
|
||||||
|
|
||||||
def find_workspace(name)
|
|
||||||
Workspace.find_by_name(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Creates a new workspace in the database
|
# opts must contain
|
||||||
|
# :data -- a hash containing the authentication info
|
||||||
|
#
|
||||||
|
# opts can contain
|
||||||
|
# :host -- an ip address or Host
|
||||||
|
# :service -- a Service
|
||||||
|
# :proto -- the protocol
|
||||||
|
# :port -- the port
|
||||||
#
|
#
|
||||||
def add_workspace(context, name)
|
def report_auth_info(opts={})
|
||||||
Workspace.find_or_create_by_name(name)
|
return if not framework.db.active
|
||||||
|
host = opts.delete(:host)
|
||||||
|
service = opts.delete(:service)
|
||||||
|
proto = opts.delete(:proto) || "generic"
|
||||||
|
proto = proto.downcase
|
||||||
|
|
||||||
|
note = {
|
||||||
|
:ntype => "auth:#{proto}",
|
||||||
|
:host => host,
|
||||||
|
:service => service,
|
||||||
|
:data => opts
|
||||||
|
}
|
||||||
|
|
||||||
|
report_note(note)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
def get_auth_info(opts={})
|
||||||
# Find or create a host matching this address/comm
|
return if not framework.db.active
|
||||||
#
|
condition = ""
|
||||||
def get_host(context, address, comm='')
|
condition_values = []
|
||||||
if comm.length > 0
|
if opts[:host]
|
||||||
host = workspace.hosts.find_by_address_and_comm(address, comm)
|
host = get_host(opts[:host])
|
||||||
|
condition = "host_id == ?"
|
||||||
|
condition_values = host.id
|
||||||
|
end
|
||||||
|
if opts[:proto]
|
||||||
|
if condition.length > 0
|
||||||
|
condition << " and "
|
||||||
|
end
|
||||||
|
condition << "ntype = ?"
|
||||||
|
condition_values << "auth:#{opts[:proto].downcase}"
|
||||||
else
|
else
|
||||||
host = workspace.hosts.find_by_address(address)
|
if condition.length > 0
|
||||||
|
condition << " and "
|
||||||
|
end
|
||||||
|
condition << "ntype LIKE ?"
|
||||||
|
condition_values << "auth:%"
|
||||||
end
|
end
|
||||||
if (not host)
|
conditions = [ condition ] + condition_values
|
||||||
host = workspace.hosts.create(
|
info = framework.db.notes.find(:all, :conditions => conditions )
|
||||||
:address => address,
|
return info.map{|i| i.data} if info
|
||||||
:comm => comm,
|
|
||||||
:state => HostState::Unknown,
|
|
||||||
:created => Time.now)
|
|
||||||
framework.events.on_db_host(context, host)
|
|
||||||
end
|
|
||||||
|
|
||||||
return host
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Find or create a client on host that matches ua_string
|
|
||||||
#
|
|
||||||
def get_client(context, host, ua_string, comm='')
|
|
||||||
# Allow host to be an address to look up
|
|
||||||
if !host.kind_of? Host
|
|
||||||
host = get_host(context, host, comm)
|
|
||||||
end
|
|
||||||
return nil if host.nil?
|
|
||||||
rec = host.clients.find_by_ua_string(ua_string)
|
|
||||||
if (not rec)
|
|
||||||
rec = host.clients.create(
|
|
||||||
:ua_string => ua_string,
|
|
||||||
:created => Time.now
|
|
||||||
)
|
|
||||||
framework.events.on_db_client(context, rec)
|
|
||||||
end
|
|
||||||
return rec
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find or create a service matching this host/proto/port/state
|
|
||||||
#
|
#
|
||||||
def get_service(context, host, proto, port, state=ServiceState::Up)
|
#
|
||||||
rec = host.services.find_by_proto_and_port(proto, port)
|
def find_or_initialize_vuln(opts)
|
||||||
if (not rec)
|
host = find_or_create_host({:host => opts[:host]}) || return
|
||||||
rec = host.services.create(
|
name = opts[:name] || return
|
||||||
:proto => proto,
|
data = opts[:data]
|
||||||
:port => port,
|
|
||||||
:state => state,
|
if data
|
||||||
:created => Time.now
|
vuln = host.vulns.find_or_initialize_by_name_and_data(name, data)
|
||||||
)
|
else
|
||||||
framework.events.on_db_service(context, rec)
|
vuln = host.vulns.find_or_initialize_by_name(name)
|
||||||
end
|
end
|
||||||
return rec
|
p vuln
|
||||||
|
|
||||||
|
if opts[:service] and opts[:service].kind_of? Service
|
||||||
|
vuln.service = opts[:service]
|
||||||
|
end
|
||||||
|
|
||||||
|
return vuln
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find or create a vuln matching this service/name
|
# Find or create a vuln matching this service/name
|
||||||
#
|
#
|
||||||
def get_vuln(context, host, service, name, data='')
|
def find_or_create_vuln(opts)
|
||||||
vuln = nil
|
vuln = find_or_initialize_vuln(opts)
|
||||||
|
if vuln and vuln.changed?
|
||||||
|
vuln.created = Time.now
|
||||||
|
task = framework.db.queue(Proc.new { vuln.save! })
|
||||||
|
task.wait
|
||||||
|
if task.status != :done
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return vuln
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
def report_vuln(opts)
|
||||||
|
if vuln.changed?
|
||||||
|
vuln.created = Time.now
|
||||||
|
framework.db.queue(Proc.new { vuln.save! })
|
||||||
|
end
|
||||||
|
return vuln
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_vuln(host, service, name, data='')
|
||||||
|
vuln = nil
|
||||||
if (service)
|
if (service)
|
||||||
vuln = Vuln.find(:first, :conditions => [ "name = ? and service_id = ? and host_id = ?", name, service.id, host.id])
|
vuln = Vuln.find(:first, :conditions => [ "name = ? and service_id = ? and host_id = ?", name, service.id, host.id])
|
||||||
else
|
else
|
||||||
vuln = Vuln.find(:first, :conditions => [ "name = ? and host_id = ?", name, host.id])
|
vuln = Vuln.find(:first, :conditions => [ "name = ? and host_id = ?", name, host.id])
|
||||||
end
|
end
|
||||||
|
|
||||||
if (not vuln)
|
|
||||||
vuln = Vuln.create(
|
|
||||||
:service_id => service ? service.id : 0,
|
|
||||||
:host_id => host.id,
|
|
||||||
:name => name,
|
|
||||||
:data => data,
|
|
||||||
:created => Time.now
|
|
||||||
)
|
|
||||||
framework.events.on_db_vuln(context, vuln)
|
|
||||||
end
|
|
||||||
|
|
||||||
return vuln
|
return vuln
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find or create a reference matching this name
|
# Find or create a reference matching this name
|
||||||
#
|
#
|
||||||
def get_ref(context, name)
|
def find_or_create_ref(opts)
|
||||||
ref = Ref.find_by_name(name)
|
ref = Ref.find_or_initialize_by_name(opts[:name])
|
||||||
if (not ref)
|
if ref and ref.changed?
|
||||||
ref = Ref.create(
|
ref.created = Time.now
|
||||||
:name => name,
|
task = framework.db.queue(Proc.new { ref.save! })
|
||||||
:created => Time.now
|
task.wait
|
||||||
)
|
if task.status != :done
|
||||||
framework.events.on_db_ref(context, ref)
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return ref
|
return ref
|
||||||
end
|
end
|
||||||
|
def get_ref(name)
|
||||||
#
|
Ref.find_by_name(name)
|
||||||
# Find or create a note matching this type/data
|
|
||||||
#
|
|
||||||
def get_note(context, host, ntype, data)
|
|
||||||
rec = host.notes.find_by_ntype_and_data(ntype, data)
|
|
||||||
if (not rec)
|
|
||||||
rec = host.notes.create(
|
|
||||||
:ntype => ntype,
|
|
||||||
:data => data,
|
|
||||||
:created => Time.now
|
|
||||||
)
|
|
||||||
framework.events.on_db_note(context, rec)
|
|
||||||
end
|
|
||||||
return rec
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Deletes a host and associated data matching this address/comm
|
# Deletes a host and associated data matching this address/comm
|
||||||
#
|
#
|
||||||
def del_host(context, address, comm='')
|
def del_host(address, comm='')
|
||||||
host = workspace.hosts.find_by_address_and_comm(address, comm)
|
host = workspace.hosts.find_by_address_and_comm(address, comm)
|
||||||
host.destroy if host
|
host.destroy if host
|
||||||
end
|
end
|
||||||
|
@ -439,8 +606,8 @@ class DBManager
|
||||||
#
|
#
|
||||||
# Deletes a port and associated vulns matching this port
|
# Deletes a port and associated vulns matching this port
|
||||||
#
|
#
|
||||||
def del_service(context, address, proto, port, comm='')
|
def del_service(address, proto, port, comm='')
|
||||||
host = get_host(context, address, comm)
|
host = get_host(address, comm)
|
||||||
return unless host
|
return unless host
|
||||||
|
|
||||||
host.services.find(:all, :conditions => { :proto => proto, :port => port}).destroy_all
|
host.services.find(:all, :conditions => { :proto => proto, :port => port}).destroy_all
|
||||||
|
@ -467,9 +634,9 @@ class DBManager
|
||||||
workspace.hosts.find_by_address(addr)
|
workspace.hosts.find_by_address(addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
def vuln_add_refs(context, vuln, refs)
|
def vuln_add_refs(vuln, refs)
|
||||||
return vuln if not refs
|
return vuln if not refs
|
||||||
rids = refs.map{|r| get_ref(context, "#{r[0]}-#{r[1]}") }
|
rids = refs.map{|r| get_ref("#{r[0]}-#{r[1]}") }
|
||||||
vuln.refs << rids
|
vuln.refs << rids
|
||||||
vuln
|
vuln
|
||||||
end
|
end
|
||||||
|
@ -669,7 +836,7 @@ class DBManager
|
||||||
:ssl => ssl,
|
:ssl => ssl,
|
||||||
:selected => sel
|
:selected => sel
|
||||||
)
|
)
|
||||||
#framework.events.on_db_target(context, rec)
|
#framework.events.on_db_target(rec)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,10 +857,9 @@ class DBManager
|
||||||
:body => body,
|
:body => body,
|
||||||
:respcode => respcode,
|
:respcode => respcode,
|
||||||
:resphead => resphead,
|
:resphead => resphead,
|
||||||
:response => response,
|
:response => response
|
||||||
:created => Time.now
|
|
||||||
)
|
)
|
||||||
#framework.events.on_db_request(context, rec)
|
#framework.events.on_db_request(rec)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -152,6 +152,7 @@ class DBManager
|
||||||
rescue ::Exception => e
|
rescue ::Exception => e
|
||||||
self.error = e
|
self.error = e
|
||||||
elog("DB.connect threw an exception: #{e}")
|
elog("DB.connect threw an exception: #{e}")
|
||||||
|
dlog("Call stack: #{$@.join"\n"}", LEV_1)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,10 @@ class Host < ActiveRecord::Base
|
||||||
has_many :vulns, :dependent => :destroy
|
has_many :vulns, :dependent => :destroy
|
||||||
has_many :notes, :dependent => :destroy
|
has_many :notes, :dependent => :destroy
|
||||||
|
|
||||||
|
has_many :service_notes, :through => :services
|
||||||
|
|
||||||
validates_uniqueness_of :address, :scope => :workspace_id
|
validates_uniqueness_of :address, :scope => :workspace_id
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,8 +3,13 @@ class DBManager
|
||||||
|
|
||||||
class Note < ActiveRecord::Base
|
class Note < ActiveRecord::Base
|
||||||
include DBSave
|
include DBSave
|
||||||
|
|
||||||
|
belongs_to :workspace
|
||||||
belongs_to :host
|
belongs_to :host
|
||||||
|
belongs_to :service
|
||||||
|
|
||||||
|
serialize :data
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,8 +4,9 @@ class DBManager
|
||||||
class Service < ActiveRecord::Base
|
class Service < ActiveRecord::Base
|
||||||
include DBSave
|
include DBSave
|
||||||
has_many :vulns, :dependent => :destroy
|
has_many :vulns, :dependent => :destroy
|
||||||
|
has_many :notes, :dependent => :destroy
|
||||||
belongs_to :host
|
belongs_to :host
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,11 +7,12 @@ class Workspace < ActiveRecord::Base
|
||||||
DEFAULT = "default"
|
DEFAULT = "default"
|
||||||
|
|
||||||
has_many :hosts, :dependent => :destroy
|
has_many :hosts, :dependent => :destroy
|
||||||
|
has_many :notes, :dependent => :destroy
|
||||||
|
|
||||||
has_many :services, :through => :hosts
|
has_many :services, :through => :hosts
|
||||||
has_many :clients, :through => :hosts
|
has_many :clients, :through => :hosts
|
||||||
has_many :vulns, :through => :hosts
|
has_many :vulns, :through => :hosts
|
||||||
has_many :notes, :through => :hosts
|
#has_many :notes, :through => :hosts
|
||||||
|
|
||||||
validates_uniqueness_of :name
|
validates_uniqueness_of :name
|
||||||
validates_presence_of :name
|
validates_presence_of :name
|
||||||
|
@ -26,4 +27,4 @@ class Workspace < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -319,16 +319,24 @@ class Db
|
||||||
|
|
||||||
end
|
end
|
||||||
framework.db.each_note do |note|
|
framework.db.each_note do |note|
|
||||||
next if(hosts and hosts.index(note.host.address) == nil)
|
next if(hosts and (note.host == nil or hosts.index(note.host.address) == nil))
|
||||||
next if(types and types.index(note.ntype) == nil)
|
next if(types and types.index(note.ntype) == nil)
|
||||||
print_status("Time: #{note.created} Note: host=#{note.host.address} type=#{note.ntype} data=#{note.data}")
|
if (note.host and note.service)
|
||||||
|
print_status("Time: #{note.created} Note: host=#{note.host.address} service=#{note.service.name} type=#{note.ntype} data=#{note.data}")
|
||||||
|
elsif (note.host)
|
||||||
|
print_status("Time: #{note.created} Note: host=#{note.host.address} type=#{note.ntype} data=#{note.data}")
|
||||||
|
elsif (note.service)
|
||||||
|
print_status("Time: #{note.created} Note: service=#{note.service.name} type=#{note.ntype} data=#{note.data}")
|
||||||
|
else
|
||||||
|
print_status("Time: #{note.created} Note: type=#{note.ntype} data=#{note.data}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def cmd_db_add_host(*args)
|
def cmd_db_add_host(*args)
|
||||||
print_status("Adding #{args.length} hosts...")
|
print_status("Adding #{args.length} hosts...")
|
||||||
args.each do |address|
|
args.each do |address|
|
||||||
host = framework.db.get_host(nil, address)
|
host = framework.db.find_or_create_host(address)
|
||||||
print_status("Time: #{host.created} Host: host=#{host.address}")
|
print_status("Time: #{host.created} Host: host=#{host.address}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -339,10 +347,10 @@ class Db
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
host = framework.db.get_host(nil, args[0])
|
host = framework.db.find_or_create_host(args[0])
|
||||||
return if not host
|
return if not host
|
||||||
|
|
||||||
service = framework.db.get_service(nil, host, args[2].downcase, args[1].to_i)
|
service = framework.db.get_service(host, args[2].downcase, args[1].to_i)
|
||||||
return if not service
|
return if not service
|
||||||
|
|
||||||
print_status("Time: #{service.created} Service: host=#{service.host.address} port=#{service.port} proto=#{service.proto} state=#{service.state}")
|
print_status("Time: #{service.created} Service: host=#{service.host.address} port=#{service.port} proto=#{service.proto} state=#{service.state}")
|
||||||
|
@ -369,10 +377,10 @@ class Db
|
||||||
ntype = args.shift
|
ntype = args.shift
|
||||||
ndata = args.join(" ")
|
ndata = args.join(" ")
|
||||||
|
|
||||||
host = framework.db.get_host(nil, naddr)
|
host = framework.db.find_or_create_host(naddr)
|
||||||
return if not host
|
return if not host
|
||||||
|
|
||||||
note = framework.db.get_note(nil, host, ntype, ndata)
|
note = framework.db.find_or_create_note(host, ntype, ndata)
|
||||||
return if not note
|
return if not note
|
||||||
|
|
||||||
print_status("Time: #{note.created} Note: host=#{note.host.address} type=#{note.ntype} data=#{note.data}")
|
print_status("Time: #{note.created} Note: host=#{note.host.address} type=#{note.ntype} data=#{note.data}")
|
||||||
|
@ -819,14 +827,14 @@ class Db
|
||||||
p = port.match(/^([^\(]+)\((\d+)\/([^\)]+)\)/)
|
p = port.match(/^([^\(]+)\((\d+)\/([^\)]+)\)/)
|
||||||
return if not p
|
return if not p
|
||||||
|
|
||||||
host = framework.db.get_host(nil, addr)
|
host = framework.db.find_or_create_host(addr)
|
||||||
return if not host
|
return if not host
|
||||||
|
|
||||||
if host.state != Msf::HostState::Alive
|
if host.state != Msf::HostState::Alive
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
framework.db.report_host_state(addr, Msf::HostState::Alive)
|
||||||
end
|
end
|
||||||
|
|
||||||
service = framework.db.get_service(nil, host, p[3].downcase, p[2].to_i)
|
service = framework.db.get_service(host, p[3].downcase, p[2].to_i)
|
||||||
name = p[1].strip
|
name = p[1].strip
|
||||||
if name != "unknown"
|
if name != "unknown"
|
||||||
service.name = name
|
service.name = name
|
||||||
|
@ -860,11 +868,11 @@ class Db
|
||||||
|
|
||||||
nss = 'NSS-' + nasl.to_s
|
nss = 'NSS-' + nasl.to_s
|
||||||
|
|
||||||
vuln = framework.db.get_vuln(nil, host, service, nss, data)
|
vuln = framework.db.get_vuln(host, service, nss, data)
|
||||||
|
|
||||||
rids = []
|
rids = []
|
||||||
refs.keys.each do |r|
|
refs.keys.each do |r|
|
||||||
rids << framework.db.get_ref(nil, r)
|
rids << framework.db.get_ref(r)
|
||||||
end
|
end
|
||||||
|
|
||||||
vuln.refs << (rids - vuln.refs)
|
vuln.refs << (rids - vuln.refs)
|
||||||
|
@ -1007,26 +1015,32 @@ class Db
|
||||||
# Whenever the parser pulls a host out of the nmap results, store
|
# Whenever the parser pulls a host out of the nmap results, store
|
||||||
# it, along with any associated services, in the database.
|
# it, along with any associated services, in the database.
|
||||||
parser.on_found_host = Proc.new { |h|
|
parser.on_found_host = Proc.new { |h|
|
||||||
|
data = {}
|
||||||
if (h["addrs"].has_key?("ipv4"))
|
if (h["addrs"].has_key?("ipv4"))
|
||||||
addr = h["addrs"]["ipv4"]
|
data[:host] = h["addrs"]["ipv4"]
|
||||||
elsif (h.has_key?("ipv6"))
|
elsif (h["addrs"].has_key?("ipv6"))
|
||||||
addr = h["addrs"]["ipv6"]
|
data[:host] = h["addrs"]["ipv6"]
|
||||||
else
|
else
|
||||||
# Don't care about addresses other than IP
|
# Can't report it if it doesn't have an IP
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
host = framework.db.get_host(nil, addr)
|
if (h["addrs"].has_key?("mac"))
|
||||||
status = (h["status"] == "up" ? Msf::HostState::Alive : Msf::HostState::Dead)
|
data[:mac] = h["addrs"]["mac"]
|
||||||
framework.db.report_host_state(self, addr, status)
|
end
|
||||||
|
data[:state] = (h["status"] == "up" ? Msf::HostState::Alive : Msf::HostState::Dead)
|
||||||
|
host = framework.db.find_or_create_host(data)
|
||||||
|
|
||||||
# Put all the ports, regardless of state, into the db.
|
# Put all the ports, regardless of state, into the db.
|
||||||
h["ports"].each { |p|
|
h["ports"].each { |p|
|
||||||
service = framework.db.get_service(nil, host, p["protocol"].downcase, p["portid"].to_i)
|
data = {}
|
||||||
service.state = p["state"]
|
data[:proto] = p["protocol"].downcase
|
||||||
|
data[:port] = p["portid"].to_i
|
||||||
|
data[:state] = p["state"]
|
||||||
|
data[:host] = host
|
||||||
if p["name"] != "unknown"
|
if p["name"] != "unknown"
|
||||||
service.name = p["name"]
|
data[:name] = p["name"]
|
||||||
end
|
end
|
||||||
service.save
|
framework.db.report_service(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1063,14 +1077,14 @@ class Db
|
||||||
|
|
||||||
next if status != "open"
|
next if status != "open"
|
||||||
|
|
||||||
host = framework.db.get_host(nil, addr)
|
host = framework.db.find_or_create_host(addr)
|
||||||
next if not host
|
next if not host
|
||||||
|
|
||||||
if host.state != Msf::HostState::Alive
|
if host.state != Msf::HostState::Alive
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
framework.db.report_host_state(addr, Msf::HostState::Alive)
|
||||||
end
|
end
|
||||||
|
|
||||||
service = framework.db.get_service(nil, host, proto, port)
|
service = framework.db.get_service(host, proto, port)
|
||||||
if not service.name and name != "unidentified"
|
if not service.name and name != "unidentified"
|
||||||
service.name = name
|
service.name = name
|
||||||
service.save
|
service.save
|
||||||
|
|
|
@ -10,11 +10,11 @@ module Exploitation
|
||||||
# Provides several javascript functions for determining the OS and browser versions of a client.
|
# Provides several javascript functions for determining the OS and browser versions of a client.
|
||||||
#
|
#
|
||||||
# getVersion(): returns an object with the following properties
|
# getVersion(): returns an object with the following properties
|
||||||
# os_name - OS name, one of the Msf::Auxiliary::Report::OperatingSystems constants
|
# os_name - OS name, one of the Msf::OperatingSystems constants
|
||||||
# os_flavor - OS flavor as a string (e.g.: "XP", "2000")
|
# os_flavor - OS flavor as a string (e.g.: "XP", "2000")
|
||||||
# os_sp - OS service pack (e.g.: "SP2", will be empty on non-Windows)
|
# os_sp - OS service pack (e.g.: "SP2", will be empty on non-Windows)
|
||||||
# os_lang - OS language (e.g.: "en-us")
|
# os_lang - OS language (e.g.: "en-us")
|
||||||
# ua_name - Client name, one of the Msf::Auxiliary::Report::HttpClients constants
|
# ua_name - Client name, one of the Msf::HttpClients constants
|
||||||
# ua_version - Client version as a string (e.g.: "3.5.1", "6.0;SP2")
|
# ua_version - Client version as a string (e.g.: "3.5.1", "6.0;SP2")
|
||||||
# arch - Architecture, one of the ARCH_* constants
|
# arch - Architecture, one of the ARCH_* constants
|
||||||
#
|
#
|
||||||
|
@ -28,8 +28,8 @@ module Exploitation
|
||||||
class JavascriptOSDetect < ObfuscateJS
|
class JavascriptOSDetect < ObfuscateJS
|
||||||
|
|
||||||
def initialize(custom_js = '', opts = {})
|
def initialize(custom_js = '', opts = {})
|
||||||
clients = ::Msf::Auxiliary::Report::HttpClients
|
clients = ::Msf::HttpClients
|
||||||
oses = ::Msf::Auxiliary::Report::OperatingSystems
|
oses = ::Msf::OperatingSystems
|
||||||
@js = custom_js
|
@js = custom_js
|
||||||
@js = <<ENDJS + @js
|
@js = <<ENDJS + @js
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -132,6 +132,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
addrs = "Addresses:(" + host[:addrs].map{|n| n[0]}.uniq.join(", ") + ")"
|
addrs = "Addresses:(" + host[:addrs].map{|n| n[0]}.uniq.join(", ") + ")"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
report_host(:host => ip, :mac => host[:mac], :os_name => os)
|
||||||
print_status("#{ip} [#{host[:name]}] OS:#{os}#{user}#{names} #{addrs} Mac:#{host[:mac]}")
|
print_status("#{ip} [#{host[:name]}] OS:#{os}#{user}#{names} #{addrs} Mac:#{host[:mac]}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,7 +64,13 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status(info)
|
print_status(info)
|
||||||
report_service(:host => ip, :port => info[0], :name => 'smb', :info => "#{res['os']} #{res['sp']} (language: #{res['lang']})")
|
report_service({
|
||||||
|
:host => ip,
|
||||||
|
:port => info[0],
|
||||||
|
:proto => 'tcp',
|
||||||
|
:name => 'smb',
|
||||||
|
:info => "#{res['os']} #{res['sp']} (language: #{res['lang']})"
|
||||||
|
})
|
||||||
case res['os']
|
case res['os']
|
||||||
when /Windows/
|
when /Windows/
|
||||||
os = OperatingSystems::WINDOWS
|
os = OperatingSystems::WINDOWS
|
||||||
|
|
|
@ -336,7 +336,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
# build the appropriate tests for it.
|
# build the appropriate tests for it.
|
||||||
method = apo[:vuln_test].dup
|
method = apo[:vuln_test].dup
|
||||||
apo[:vuln_test] = ""
|
apo[:vuln_test] = ""
|
||||||
apo[:ua_name] = ::Msf::Auxiliary::Report::HttpClients::IE
|
apo[:ua_name] = HttpClients::IE
|
||||||
if apo[:classid].kind_of?(Array) # then it's many classids
|
if apo[:classid].kind_of?(Array) # then it's many classids
|
||||||
apo[:classid].each { |clsid|
|
apo[:classid].each { |clsid|
|
||||||
apo[:vuln_test] << "if (testAXO('#{clsid}', '#{method}')) {\n"
|
apo[:vuln_test] << "if (testAXO('#{clsid}', '#{method}')) {\n"
|
||||||
|
@ -477,7 +477,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_noscript_response(cli, request)
|
def build_noscript_response(cli, request)
|
||||||
client_info = get_client(cli.peerhost, request['User-Agent'])
|
client_info = get_client(:host => cli.peerhost, :ua_string => request['User-Agent'])
|
||||||
|
|
||||||
response = create_response()
|
response = create_response()
|
||||||
response['Expires'] = '0'
|
response['Expires'] = '0'
|
||||||
|
@ -518,9 +518,9 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
response['Expires'] = '0'
|
response['Expires'] = '0'
|
||||||
response['Cache-Control'] = 'must-revalidate'
|
response['Cache-Control'] = 'must-revalidate'
|
||||||
|
|
||||||
client_info = get_client(cli.peerhost, request['User-Agent'])
|
|
||||||
#print_status("Client info: #{client_info.inspect}")
|
#print_status("Client info: #{client_info.inspect}")
|
||||||
host_info = get_host(cli.peerhost)
|
host_info = get_host(cli.peerhost)
|
||||||
|
client_info = get_client(:host => host_info, :ua_string => request['User-Agent'])
|
||||||
|
|
||||||
js = ::Rex::Exploitation::ObfuscateJS.new
|
js = ::Rex::Exploitation::ObfuscateJS.new
|
||||||
# If we didn't get a client from the database, then the detection
|
# If we didn't get a client from the database, then the detection
|
||||||
|
@ -710,25 +710,25 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
detected_version = Rex::Text.decode_base64(Rex::Text.uri_decode(detected_version))
|
detected_version = Rex::Text.decode_base64(Rex::Text.uri_decode(detected_version))
|
||||||
print_status("JavaScript Report: #{detected_version}")
|
print_status("JavaScript Report: #{detected_version}")
|
||||||
(os_name, os_flavor, os_sp, os_lang, arch, ua_name, ua_ver) = detected_version.split(':')
|
(os_name, os_flavor, os_sp, os_lang, arch, ua_name, ua_ver) = detected_version.split(':')
|
||||||
report_host(
|
host = framework.db.find_or_create_host({
|
||||||
:host => cli.peerhost,
|
:host => cli.peerhost,
|
||||||
:os_name => os_name,
|
:os_name => os_name,
|
||||||
:os_flavor => os_flavor,
|
:os_flavor => os_flavor,
|
||||||
:os_sp => os_sp,
|
:os_sp => os_sp,
|
||||||
:os_lang => os_lang,
|
:os_lang => os_lang,
|
||||||
:arch => arch
|
:arch => arch
|
||||||
)
|
})
|
||||||
report_client(
|
report_client({
|
||||||
:host => cli.peerhost,
|
:host => host,
|
||||||
:ua_string => request['User-Agent'],
|
:ua_string => request['User-Agent'],
|
||||||
:ua_name => ua_name,
|
:ua_name => ua_name,
|
||||||
:ua_ver => ua_ver
|
:ua_ver => ua_ver
|
||||||
)
|
})
|
||||||
report_note(
|
report_note({
|
||||||
:host => cli.peerhost,
|
:host => host,
|
||||||
:type => 'http_request',
|
:type => 'http_request',
|
||||||
:data => "#{@myhost}:#{@myport} #{request.method} #{request.resource} #{os_name} #{ua_name} #{ua_ver}"
|
:data => "#{@myhost}:#{@myport} #{request.method} #{request.resource} #{os_name} #{ua_name} #{ua_ver}"
|
||||||
)
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -736,9 +736,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
# This is less reliable because we're not treating different user
|
# This is less reliable because we're not treating different user
|
||||||
# agents from the same IP as different hosts.
|
# agents from the same IP as different hosts.
|
||||||
if (framework.db.active)
|
if (framework.db.active)
|
||||||
# There really ought to be a report_client, instead of having
|
report_client(:host => cli.peerhost, :ua_string => request['User-Agent'])
|
||||||
# get_client create a new one if it can't find one.
|
|
||||||
get_client(cli.peerhost, request['User-Agent'])
|
|
||||||
else
|
else
|
||||||
warn_no_database
|
warn_no_database
|
||||||
@targetcache ||= {}
|
@targetcache ||= {}
|
||||||
|
@ -768,8 +766,9 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
# essentially creating an in-memory database. The upside is that it works
|
# essentially creating an in-memory database. The upside is that it works
|
||||||
# if the database is broken. The downside of course is that querying from
|
# if the database is broken. The downside of course is that querying from
|
||||||
# a hash is not as simple or efficient as a database.
|
# a hash is not as simple or efficient as a database.
|
||||||
def get_client(host, ua)
|
def get_client(opts)
|
||||||
return super(host, ua) || @targetcache[host]
|
host = opts[:host]
|
||||||
|
return super || @targetcache[host]
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_iframe(resource)
|
def build_iframe(resource)
|
||||||
|
|
|
@ -23,9 +23,9 @@ class Plugin::CredCollect < Msf::Plugin
|
||||||
print_error("Database not connected")
|
print_error("Database not connected")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
framework.db.each_note do |note|
|
framework.db.get_auth_info(:proto=>"smb").each do |info|
|
||||||
if note.ntype == "auth_HASH"
|
if info.kind_of? Hash and info.has_key? :hash_string
|
||||||
print_line(note.data)
|
print_line(info[:hash_string])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -35,9 +35,9 @@ class Plugin::CredCollect < Msf::Plugin
|
||||||
print_error("Database not connected")
|
print_error("Database not connected")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
framework.db.each_note do |note|
|
framework.db.get_auth_info(:proto=>"smb").each do |info|
|
||||||
if note.ntype == "auth_TOKEN"
|
if info.kind_of? Hash and info.has_key? :token
|
||||||
print_line("#{note.host.address} - #{note.data}")
|
print_line(info[:host] + " - " + info[:token])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -60,28 +60,37 @@ class Plugin::CredCollect < Msf::Plugin
|
||||||
|
|
||||||
# Target infos for the db record
|
# Target infos for the db record
|
||||||
addr = session.sock.peerhost
|
addr = session.sock.peerhost
|
||||||
host = self.framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
host = self.framework.db.find_or_create_host(
|
||||||
|
:host => addr,
|
||||||
|
:state => Msf::HostState::Alive
|
||||||
|
)
|
||||||
|
|
||||||
# Record hashes to the running db instance as auth_HASH type
|
# Record hashes to the running db instance as auth_HASH type
|
||||||
hashes.each do |user|
|
hashes.each do |hash|
|
||||||
|
data = {}
|
||||||
|
data[:host] = host
|
||||||
|
data[:targ_host] = host.address
|
||||||
|
data[:proto] = 'smb'
|
||||||
|
data[:user] = hash.user_name
|
||||||
|
data[:hash] = hash.lanman + ":" + hash.ntlm
|
||||||
|
data[:hash_string] = hash.hash_string
|
||||||
|
|
||||||
type = "auth_HASH"
|
self.framework.db.report_auth_info(data)
|
||||||
data = user.to_s
|
|
||||||
|
|
||||||
# We'll make this look like an auth note anyway
|
|
||||||
self.framework.db.get_note(self, host, type, data)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Record user tokens
|
# Record user tokens
|
||||||
tokens = session.incognito.incognito_list_tokens(0).values
|
tokens = session.incognito.incognito_list_tokens(0).values
|
||||||
# Meh, tokens come to us as a formatted string
|
# Meh, tokens come to us as a formatted string
|
||||||
tokens = tokens.to_s.strip!.split("\n")
|
tokens = tokens.join.strip!.split("\n")
|
||||||
|
|
||||||
tokens.each do |token|
|
tokens.each do |token|
|
||||||
type = "auth_TOKEN"
|
data = {}
|
||||||
data = token
|
data[:host] = host
|
||||||
|
data[:targ_host] = host.address
|
||||||
|
data[:proto] = 'smb'
|
||||||
|
data[:token] = token
|
||||||
|
|
||||||
self.framework.db.get_note(self, host, type, data)
|
self.framework.db.report_auth_info(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -398,66 +398,62 @@ class Plugin::Nexpose < Msf::Plugin
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_nexpose_data_rxml(data)
|
def process_nexpose_data_rxml(data)
|
||||||
doc = REXML::Document.new(data)
|
doc = REXML::Document.new(data)
|
||||||
doc.elements.each('/NexposeReport/nodes/node') do |host|
|
doc.elements.each('/NexposeReport/nodes/node') do |host|
|
||||||
addr = host.attributes['address']
|
addr = host.attributes['address']
|
||||||
xhost = addr
|
xhost = addr
|
||||||
refs = {}
|
refs = {}
|
||||||
|
|
||||||
# os based vuln
|
# os based vuln
|
||||||
host.elements['tests'].elements.each('test') do |vuln|
|
host.elements['tests'].elements.each('test') do |vuln|
|
||||||
if vuln.attributes['status'] == 'vulnerable-exploited' or vuln.attributes['status'] == 'vulnerable-version'
|
if vuln.attributes['status'] == 'vulnerable-exploited' or vuln.attributes['status'] == 'vulnerable-version'
|
||||||
dhost = framework.db.get_host(nil, addr)
|
dhost = framework.db.find_or_create_host(:host => addr)
|
||||||
next if not dhost
|
next if not dhost
|
||||||
|
|
||||||
vid = vuln.attributes['id'].to_s
|
vid = vuln.attributes['id'].to_s
|
||||||
nexpose_vuln_lookup(doc,vid,refs,dhost)
|
nexpose_vuln_lookup(doc,vid,refs,dhost)
|
||||||
nexpose_vuln_lookup(doc,vid.upcase,refs,dhost)
|
nexpose_vuln_lookup(doc,vid.upcase,refs,dhost)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# skip if no endpoints
|
# skip if no endpoints
|
||||||
next unless host.elements['endpoints']
|
next unless host.elements['endpoints']
|
||||||
|
|
||||||
# parse the ports and add the vulns
|
# parse the ports and add the vulns
|
||||||
host.elements['endpoints'].elements.each('endpoint') do |port|
|
host.elements['endpoints'].elements.each('endpoint') do |port|
|
||||||
prot = port.attributes['protocol']
|
prot = port.attributes['protocol']
|
||||||
pnum = port.attributes['port']
|
pnum = port.attributes['port']
|
||||||
stat = port.attributes['status']
|
stat = port.attributes['status']
|
||||||
next if not port.elements['services']
|
next if not port.elements['services']
|
||||||
name = port.elements['services'].elements['service'].attributes['name'].downcase
|
name = port.elements['services'].elements['service'].attributes['name'].downcase
|
||||||
|
|
||||||
next if not port.elements['services'].elements['service'].elements['fingerprints']
|
next if not port.elements['services'].elements['service'].elements['fingerprints']
|
||||||
prod = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['product']
|
prod = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['product']
|
||||||
vers = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['version']
|
vers = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['version']
|
||||||
vndr = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['vendor']
|
vndr = port.elements['services'].elements['service'].elements['fingerprints'].elements['fingerprint'].attributes['vendor']
|
||||||
|
|
||||||
next if stat != 'open'
|
next if stat != 'open'
|
||||||
|
|
||||||
dhost = framework.db.get_host(nil, addr)
|
dhost = framework.db.find_or_create_host(:host => addr, :state => Msf::HostState::Alive)
|
||||||
next if not dhost
|
next if not dhost
|
||||||
|
|
||||||
if dhost.state != Msf::HostState::Alive
|
if name != "unknown"
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
service = framework.db.find_or_create_service(:host => dhost, :proto => prot.downcase, :port => pnum.to_i, :name => name)
|
||||||
end
|
else
|
||||||
|
service = framework.db.find_or_create_service(:host => dhost, :proto => prot.downcase, :port => pnum.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
service = framework.db.get_service(nil, dhost, prot.downcase, pnum.to_i)
|
port.elements['services'].elements['service'].elements['tests'].elements.each('test') do |vuln|
|
||||||
if name != "unknown"
|
if vuln.attributes['status'] == 'vulnerable-exploited' or vuln.attributes['status'] == 'vulnerable-version'
|
||||||
service.name = name
|
vid = vuln.attributes['id'].to_s
|
||||||
service.save
|
# TODO, improve the vuln_lookup check so case of the vuln_id doesnt matter
|
||||||
end
|
nexpose_vuln_lookup(doc,vid,refs,dhost,service)
|
||||||
|
nexpose_vuln_lookup(doc,vid.upcase,refs,dhost,service)
|
||||||
port.elements['services'].elements['service'].elements['tests'].elements.each('test') do |vuln|
|
end
|
||||||
if vuln.attributes['status'] == 'vulnerable-exploited' or vuln.attributes['status'] == 'vulnerable-version'
|
end
|
||||||
vid = vuln.attributes['id'].to_s
|
end
|
||||||
# TODO, improve the vuln_lookup check so case of the vuln_id doesnt matter
|
end
|
||||||
nexpose_vuln_lookup(doc,vid,refs,dhost,service)
|
end
|
||||||
nexpose_vuln_lookup(doc,vid.upcase,refs,dhost,service)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# NeXpose vuln lookup
|
# NeXpose vuln lookup
|
||||||
|
@ -483,11 +479,15 @@ class Plugin::Nexpose < Msf::Plugin
|
||||||
|
|
||||||
refs[ 'NEXPOSE-' + vid.downcase ] = true
|
refs[ 'NEXPOSE-' + vid.downcase ] = true
|
||||||
|
|
||||||
vuln = framework.db.get_vuln(nil, host, serv, 'NEXPOSE-' + vid.downcase, title)
|
vuln = framework.db.find_or_create_vuln(
|
||||||
|
:host => host,
|
||||||
|
:service => serv,
|
||||||
|
:name => 'NEXPOSE-' + vid.downcase,
|
||||||
|
:data => title)
|
||||||
|
|
||||||
rids = []
|
rids = []
|
||||||
refs.keys.each do |r|
|
refs.keys.each do |r|
|
||||||
rids << framework.db.get_ref(nil, r)
|
rids << framework.db.find_or_create_ref(:name => r)
|
||||||
end
|
end
|
||||||
|
|
||||||
vuln.refs << (rids - vuln.refs)
|
vuln.refs << (rids - vuln.refs)
|
||||||
|
@ -503,21 +503,20 @@ class Plugin::Nexpose < Msf::Plugin
|
||||||
desc = fdesc.text.to_s.strip
|
desc = fdesc.text.to_s.strip
|
||||||
end
|
end
|
||||||
|
|
||||||
host = framework.db.get_host(nil, addr)
|
host = framework.db.find_or_create_host(:host => addr, :state => Msf::HostState::Alive)
|
||||||
next if not host
|
next if not host
|
||||||
|
|
||||||
if host.state != Msf::HostState::Alive
|
|
||||||
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Load vulnerabilities not associated with a service
|
# Load vulnerabilities not associated with a service
|
||||||
dev.elements.each('vulnerabilities/vulnerability') do |vuln|
|
dev.elements.each('vulnerabilities/vulnerability') do |vuln|
|
||||||
vid = vuln.attributes['id'].to_s.downcase
|
vid = vuln.attributes['id'].to_s.downcase
|
||||||
rids = []
|
rids = []
|
||||||
refs = process_nexpose_data_sxml_refs(vuln)
|
refs = process_nexpose_data_sxml_refs(vuln)
|
||||||
next if not refs
|
next if not refs
|
||||||
vuln = framework.db.get_vuln(nil, host, nil, 'NEXPOSE-' + vid, vid)
|
vuln = framework.db.find_or_create_vuln(
|
||||||
refs.each { |r| rids << framework.db.get_ref(nil, r) }
|
:host => host,
|
||||||
|
:name => 'NEXPOSE-' + vid
|
||||||
|
:data => vid)
|
||||||
|
refs.each { |r| rids << framework.db.find_or_create_ref(:name => r) }
|
||||||
vuln.refs << (rids - vuln.refs)
|
vuln.refs << (rids - vuln.refs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -527,10 +526,11 @@ class Plugin::Nexpose < Msf::Plugin
|
||||||
sprot = svc.attributes['protocol'].to_s.downcase
|
sprot = svc.attributes['protocol'].to_s.downcase
|
||||||
sport = svc.attributes['port'].to_s.to_i
|
sport = svc.attributes['port'].to_s.to_i
|
||||||
|
|
||||||
serv = framework.db.get_service(nil, host, sprot, sport)
|
name = sname.split('(')[0].strip
|
||||||
if(sname.downcase != '<unknown>')
|
if(sname.downcase != '<unknown>')
|
||||||
serv.name = sname.split('(')[0].strip
|
serv = framework.db.find_or_create_service(:host => host, :proto => sprot, :port => sport, :name => name)
|
||||||
serv.save
|
else
|
||||||
|
serv = framework.db.find_or_create_service(:host => host, :proto => sprot, :port => sport)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load vulnerabilities associated with this service
|
# Load vulnerabilities associated with this service
|
||||||
|
@ -539,11 +539,11 @@ class Plugin::Nexpose < Msf::Plugin
|
||||||
rids = []
|
rids = []
|
||||||
refs = process_nexpose_data_sxml_refs(vuln)
|
refs = process_nexpose_data_sxml_refs(vuln)
|
||||||
next if not refs
|
next if not refs
|
||||||
vuln = framework.db.get_vuln(nil, host, serv, 'NEXPOSE-' + vid, vid)
|
vuln = framework.db.find_or_create_vuln(:host => host, :service => serv, :name => 'NEXPOSE-' + vid, :data => vid)
|
||||||
refs.each { |r| rids << framework.db.get_ref(nil, r) }
|
refs.each { |r| rids << framework.db.find_or_create_ref(:name => r) }
|
||||||
vuln.refs << (rids - vuln.refs)
|
vuln.refs << (rids - vuln.refs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue