Stop trying more creds for a user after success

This is more like the behavior of the old AuthBrute mixin, where a
scanner module was expected to return :next_user in the block given to
each_user_pass when it successfully authenticated.

The advantage is a reduced number of attempts that are very unlikely to
be successful since we already know the password. However, note that
since we don't compare realms, this will cause a false negative in the
rare case where the same username exists with different realms on the
same service.

MSP-10686
bug/bundler_fix
James Lee 2014-07-10 17:48:58 -05:00
parent 097d5d68ce
commit 4b16985eb8
No known key found for this signature in database
GPG Key ID: 2D6094C7CEA0A321
2 changed files with 20 additions and 3 deletions

View File

@ -112,6 +112,9 @@ module Metasploit
# Attempt to login with every {Credential credential} in
# {#cred_details}, by calling {#attempt_login} once for each.
#
# If a successful login is found for a user, no more attempts
# will be made for that user.
#
# @yieldparam result [Result] The {Result} object for each attempt
# @yieldreturn [void]
# @return [void]
@ -123,7 +126,11 @@ module Metasploit
consecutive_error_count = 0
total_error_count = 0
successful_users = Set.new
each_credential do |credential|
next if successful_users.include?(credential.public)
result = attempt_login(credential)
result.freeze
@ -132,6 +139,7 @@ module Metasploit
if result.success?
consecutive_error_count = 0
break if stop_on_success
successful_users << credential.public
else
if result.status == :connection_error
consecutive_error_count += 1

View File

@ -263,12 +263,21 @@ shared_examples_for 'Metasploit::Framework::LoginScanner::Base' do | opts |
my_scanner.scan!
end
it 'should stop trying a user after success' do
my_scanner = login_scanner
my_scanner.should_receive(:valid!)
my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return failure_blank
my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return success
my_scanner.should_not_receive(:attempt_login)
my_scanner.scan!
end
it 'call attempt_login once for each cred_detail' do
my_scanner = login_scanner
my_scanner.should_receive(:valid!)
my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return success
my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return success
my_scanner.should_receive(:attempt_login).once.with(pub_pri).and_return success
my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return failure_blank
my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return failure_blank
my_scanner.should_receive(:attempt_login).once.with(pub_pri).and_return failure_blank
my_scanner.scan!
end