diff --git a/lib/msf/core/db_manager/exploit_attempt.rb b/lib/msf/core/db_manager/exploit_attempt.rb index 792b31e89e..a36ebdc70c 100644 --- a/lib/msf/core/db_manager/exploit_attempt.rb +++ b/lib/msf/core/db_manager/exploit_attempt.rb @@ -28,136 +28,112 @@ module Msf::DBManager::ExploitAttempt end def report_exploit_failure(opts) + return unless opts.has_key?(:refs) && !opts[:refs].blank? + host = opts[:host] || return - ::ActiveRecord::Base.connection_pool.with_connection { - wspace = opts.delete(:workspace) || workspace - mrefs = opts.delete(:refs) || return - host = opts.delete(:host) - port = opts.delete(:port) - prot = opts.delete(:proto) - svc = opts.delete(:service) - vuln = opts.delete(:vuln) - - timestamp = opts.delete(:timestamp) - freason = opts.delete(:fail_reason) - fdetail = opts.delete(:fail_detail) - username = opts.delete(:username) - mname = opts.delete(:module) - - # Bail if we dont have a host object - return if not host + wspace = opts[:workspace] || workspace + port = opts[:port] + prot = opts[:proto] || "tcp" + svc = opts[:service] # Look up the service as appropriate if port and svc.nil? - prot ||= "tcp" - svc = get_service(wspace, host, prot, port) + opts[:proto] ||= prot + opts[:service] = get_service(wspace, host, prot, port) end - if not vuln - # Create a references map from the module list - ref_objs = ::Mdm::Ref.where(:name => mrefs.map { |ref| - if ref.respond_to?(:ctx_id) and ref.respond_to?(:ctx_val) - "#{ref.ctx_id}-#{ref.ctx_val}" - else - ref.to_s - end - }) - - # Try find a matching vulnerability - vuln = find_vuln_by_refs(ref_objs, host, svc) - end - - attempt_info = { - :attempted_at => timestamp || Time.now.utc, - :exploited => false, - :fail_detail => fdetail, - :fail_reason => freason, - :module => mname, - :username => username || "unknown", - } - - # We have match, lets create a vuln_attempt record - if vuln - attempt_info[:vuln_id] = vuln.id - vuln.vuln_attempts.create(attempt_info) - end - - # Report an exploit attempt all the same - - if svc - attempt_info[:port] = svc.port - attempt_info[:proto] = svc.proto - end - - if port and svc.nil? - attempt_info[:port] = port - attempt_info[:proto] = prot || "tcp" - end - - host.exploit_attempts.create(attempt_info) - } + do_report_failure_or_success(opts) end def report_exploit_success(opts) + opts[:refs] || return + host = opts[:host] || return - ::ActiveRecord::Base.connection_pool.with_connection { - wspace = opts.delete(:workspace) || workspace - mrefs = opts.delete(:refs) || return - host = opts.delete(:host) - svc = opts.delete(:service) - vuln = opts.delete(:vuln) + wspace = opts[:workspace] || workspace + port = opts[:port] + prot = opts[:proto] || "tcp" + svc = opts[:service] - timestamp = opts.delete(:timestamp) - username = opts.delete(:username) - mname = opts.delete(:module) - - # Bail if we dont have a host object - return if not host - - if not vuln - # Create a references map from the module list - ref_objs = ::Mdm::Ref.where(:name => mrefs.map { |ref| - if ref.respond_to?(:ctx_id) and ref.respond_to?(:ctx_val) - "#{ref.ctx_id}-#{ref.ctx_val}" - else - ref.to_s - end - }) - - # Try find a matching vulnerability - vuln = find_vuln_by_refs(ref_objs, host, svc) + # Look up or generate the service as appropriate + if port and svc.nil? + opts[:proto] ||= "tcp" + opts[:service] = report_service( + workspace: wspace, host: host, port: port, proto: prot + ) end - attempt_info = { + do_report_failure_or_success(opts) + end + + private + + def do_report_failure_or_success(opts) + ::ActiveRecord::Base.connection_pool.with_connection { + mrefs = opts.delete(:refs) || return + host = opts.delete(:host) + port = opts.delete(:port) + prot = opts.delete(:proto) + svc = opts.delete(:service) + vuln = opts.delete(:vuln) + + timestamp = opts.delete(:timestamp) + freason = opts.delete(:fail_reason) + fdetail = opts.delete(:fail_detail) + username = opts.delete(:username) + mname = opts.delete(:module) + + if not vuln + # Create a references map from the module list + ref_objs = ::Mdm::Ref.where(:name => mrefs.map { |ref| + if ref.respond_to?(:ctx_id) and ref.respond_to?(:ctx_val) + "#{ref.ctx_id}-#{ref.ctx_val}" + else + ref.to_s + end + }) + + # Try find a matching vulnerability + vuln = find_vuln_by_refs(ref_objs, host, svc) + end + + attempt_info = { :attempted_at => timestamp || Time.now.utc, - :exploited => true, + :exploited => (freason.nil? ? true : false), + :fail_detail => fdetail, + :fail_reason => freason, :module => mname, :username => username || "unknown", + } + + attempt_info[:session_id] = opts[:session_id] if opts[:session_id] + attempt_info[:loot_id] = opts[:loot_id] if opts[:loot_id] + + # We have match, lets create a vuln_attempt record + if vuln + attempt_info[:vuln_id] = vuln.id + vuln.vuln_attempts.create(attempt_info) + + # Correct the vuln's associated service if necessary + if svc and vuln.service_id.nil? + vuln.service = svc + vuln.save + end + end + + # Report an exploit attempt all the same + + if svc + attempt_info[:port] = svc.port + attempt_info[:proto] = svc.proto + end + + if port and svc.nil? + attempt_info[:port] = port + attempt_info[:proto] = prot || "tcp" + end + + host.exploit_attempts.create(attempt_info) } - attempt_info[:session_id] = opts[:session_id] if opts[:session_id] - attempt_info[:loot_id] = opts[:loot_id] if opts[:loot_id] - - # We have match, lets create a vuln_attempt record - if vuln - attempt_info[:vuln_id] = vuln.id - vuln.vuln_attempts.create(attempt_info) - - # Correct the vuln's associated service if necessary - if svc and vuln.service_id.nil? - vuln.service = svc - vuln.save - end - end - - # Report an exploit attempt all the same - - if svc - attempt_info[:port] = svc.port - attempt_info[:proto] = svc.proto - end - - host.exploit_attempts.create(attempt_info) - } end end