@@ -79,9 +79,25 @@ def report_exploit_failure(opts)
7979
8080 vuln = nil
8181 if rids . present?
82- # Try to find an existing vulnerability with the same service & references
83- # or, if svc is nil, with the same host & references
84- vuln = find_vuln_by_refs ( rids , host , svc , false )
82+ # Only perform vuln lookup when no check_code is present (normal
83+ # exploit flow) or the check result positively indicates vulnerability.
84+ # Safe, Unknown, and Detected results should not associate this attempt
85+ # with an existing vuln. Only key off check_code — fail_reason alone
86+ # is too broad (e.g. Failure::Unknown covers real exploit failures too).
87+ vuln_check_codes = [ Msf ::Exploit ::CheckCode ::Appears . code , Msf ::Exploit ::CheckCode ::Vulnerable . code ]
88+ if opts [ :check_code ] . nil? || vuln_check_codes . include? ( opts [ :check_code ] )
89+ # Try to find an existing vulnerability with the same service & references
90+ # or, if svc is nil, with the same host & references
91+ vuln = find_vuln_by_refs ( rids , host , svc , false )
92+
93+ # Fall back to a host-only lookup when the service-scoped query found
94+ # nothing. Only match vulns with no associated service to avoid
95+ # misattributing attempts to a vuln on a different service.
96+ if svc && vuln . nil?
97+ fallback_vuln = find_vuln_by_refs ( rids , host , nil , false )
98+ vuln = fallback_vuln if fallback_vuln && fallback_vuln . service_id . nil?
99+ end
100+ end
85101 end
86102
87103 opts [ :service ] = svc
@@ -158,8 +174,20 @@ def do_report_failure_or_success(opts)
158174 # Create a references map from the module list
159175 ref_objs = ::Mdm ::Ref . where ( name : ref_names )
160176
161- # Try find a matching vulnerability
162- vuln = find_vuln_by_refs ( ref_objs , host , svc , false )
177+ # Only perform vuln lookup when no check_code is present (normal
178+ # exploit flow) or the check result positively indicates vulnerability.
179+ # Safe, Unknown, and Detected results should not associate this attempt
180+ # with an existing vuln. Only key off check_code — fail_reason alone
181+ # is too broad (e.g. Failure::Unknown covers real exploit failures too).
182+ vuln_check_codes = [ Msf ::Exploit ::CheckCode ::Appears . code , Msf ::Exploit ::CheckCode ::Vulnerable . code ]
183+ if opts [ :check_code ] . nil? || vuln_check_codes . include? ( opts [ :check_code ] )
184+ # Try find a matching vulnerability
185+ vuln = find_vuln_by_refs ( ref_objs , host , svc , false )
186+ if svc && vuln . nil?
187+ fallback_vuln = find_vuln_by_refs ( ref_objs , host , nil , false )
188+ vuln = fallback_vuln if fallback_vuln && fallback_vuln . service_id . nil?
189+ end
190+ end
163191 end
164192
165193 attempt_info = {
@@ -170,12 +198,17 @@ def do_report_failure_or_success(opts)
170198 :module => mname ,
171199 :username => username || "unknown" ,
172200 }
201+ attempt_info [ :check_code ] = opts [ :check_code ] if opts [ :check_code ]
202+ attempt_info [ :check_detail ] = opts [ :check_detail ] if opts [ :check_detail ]
173203
174204 attempt_info [ :session_id ] = opts [ :session_id ] if opts [ :session_id ]
175205 attempt_info [ :loot_id ] = opts [ :loot_id ] if opts [ :loot_id ]
176206
177- # We have match, lets create a vuln_attempt record
178- if vuln
207+ # We have match, lets create a vuln_attempt record.
208+ # Skip if the caller already recorded a vuln attempt for this run
209+ # (e.g. Auxiliary::Report#report_vuln sets skip_vuln_attempt via
210+ # the last_vuln_attempt flag on the module).
211+ if vuln && !opts [ :skip_vuln_attempt ]
179212 attempt_info [ :vuln_id ] = vuln . id
180213 vuln . vuln_attempts . create ( attempt_info )
181214
@@ -200,7 +233,8 @@ def do_report_failure_or_success(opts)
200233 attempt_info [ :proto ] = prot || Msf ::DBManager ::DEFAULT_SERVICE_PROTO
201234 end
202235
203- host . exploit_attempts . create ( attempt_info )
236+ # check_code and check_detail are valid for VulnAttempt but not ExploitAttempt
237+ host . exploit_attempts . create ( attempt_info . except ( :check_code , :check_detail ) )
204238 }
205239
206240 end
0 commit comments