Files
metasploit-gs/lib/msf/core/db_manager/service.rb
T

131 lines
3.8 KiB
Ruby

module Msf::DBManager::Service
# Deletes a port and associated vulns matching this port
def del_service(wspace, address, proto, port, comm='')
host = get_host(:workspace => wspace, :address => address)
return unless host
::ActiveRecord::Base.connection_pool.with_connection {
host.services.where({:proto => proto, :port => port}).each { |s| s.destroy }
}
end
# Iterates over the services table calling the supplied block with the
# service instance of each entry.
def each_service(wspace=workspace, &block)
::ActiveRecord::Base.connection_pool.with_connection {
services(wspace).each do |service|
block.call(service)
end
}
end
def find_or_create_service(opts)
report_service(opts)
end
def get_service(wspace, host, proto, port)
::ActiveRecord::Base.connection_pool.with_connection {
host = get_host(:workspace => wspace, :address => host)
return if !host
return host.services.find_by_proto_and_port(proto, port)
}
end
#
# Record a service in the database.
#
# opts MUST contain
# +:host+:: the host where this service is running
# +:port+:: the port where this service listens
# +:proto+:: the transport layer protocol (e.g. tcp, udp)
#
# opts may contain
# +:name+:: the application layer protocol (e.g. ssh, mssql, smb)
# +:sname+:: an alias for the above
# +:workspace+:: the workspace for the service
#
def report_service(opts)
return if !active
::ActiveRecord::Base.connection_pool.with_connection { |conn|
addr = opts.delete(:host) || return
hname = opts.delete(:host_name)
hmac = opts.delete(:mac)
host = nil
wspace = opts.delete(:workspace) || workspace
hopts = {:workspace => wspace, :host => addr}
hopts[:name] = hname if hname
hopts[:mac] = hmac if hmac
# Other report_* methods take :sname to mean the service name, so we
# map it here to ensure it ends up in the right place despite not being
# a real column.
if opts[:sname]
opts[:name] = opts.delete(:sname)
end
if addr.kind_of? ::Mdm::Host
host = addr
addr = host.address
else
host = report_host(hopts)
end
if opts[:port].to_i.zero?
dlog("Skipping port zero for service '%s' on host '%s'" % [opts[:name],host.address])
return nil
end
ret = {}
=begin
host = get_host(:workspace => wspace, :address => addr)
if host
host.updated_at = host.created_at
host.state = HostState::Alive
host.save!
end
=end
proto = opts[:proto] || Msf::DBManager::DEFAULT_SERVICE_PROTO
service = host.services.where(port: opts[:port].to_i, proto: proto).first_or_initialize
opts.each { |k,v|
if (service.attribute_names.include?(k.to_s))
service[k] = ((v and k == :name) ? v.to_s.downcase : v)
elsif !v.blank?
dlog("Unknown attribute for Service: #{k}")
end
}
service.state ||= Msf::ServiceState::Open
service.info ||= ""
if (service and service.changed?)
msf_import_timestamps(opts,service)
service.save!
end
if opts[:task]
Mdm::TaskService.create(
:task => opts[:task],
:service => service
)
end
ret[:service] = service
}
end
# Returns a list of all services in the database
def services(wspace = workspace, only_up = false, proto = nil, addresses = nil, ports = nil, names = nil)
::ActiveRecord::Base.connection_pool.with_connection {
conditions = {}
conditions[:state] = [Msf::ServiceState::Open] if only_up
conditions[:proto] = proto if proto
conditions["hosts.address"] = addresses if addresses
conditions[:port] = ports if ports
conditions[:name] = names if names
wspace.services.includes(:host).where(conditions).order("hosts.address, port")
}
end
end