Merge pull request #4364 from todb-r7/bug/bruteforce-speed-3904

Modules should respect bruteforce_speed again
bug/bundler_fix
dmaloney-r7 2014-12-11 13:19:42 -06:00
commit 47c38ed04e
30 changed files with 161 additions and 3 deletions

View File

@ -30,6 +30,9 @@ module Metasploit
# @!attribute stop_on_success # @!attribute stop_on_success
# @return [Boolean] Whether the scanner should stop when it has found one working Credential # @return [Boolean] Whether the scanner should stop when it has found one working Credential
attr_accessor :stop_on_success attr_accessor :stop_on_success
# @!attribute bruteforce_speed
# @return [Fixnum] The desired speed, with 5 being 'fast' and 0 being 'slow.'
attr_accessor :bruteforce_speed
validates :connection_timeout, validates :connection_timeout,
presence: true, presence: true,
@ -53,6 +56,14 @@ module Metasploit
validates :stop_on_success, validates :stop_on_success,
inclusion: { in: [true, false] } inclusion: { in: [true, false] }
validates :bruteforce_speed,
presence: false,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0,
less_than_or_equal_to: 5
}
validate :host_address_must_be_valid validate :host_address_must_be_valid
validate :validate_cred_details validate :validate_cred_details
@ -86,6 +97,34 @@ module Metasploit
false false
end end
# @note Override this to set a timeout that makes more sense for
# your particular protocol. Telnet already usually takes a really
# long time, while MSSQL is often lickety-split quick. If
# overridden, the override should probably do something sensible
# with {#bruteforce_speed}
#
# @return [Fixnum] a number of seconds to sleep between attempts
def sleep_time
case bruteforce_speed
when 0; 60 * 5
when 1; 15
when 2; 1
when 3; 0.5
when 4; 0.1
else; 0
end
end
# A threadsafe sleep method
#
# @param time [Fixnum] number of seconds (can be a Float), defaults
# to {#sleep_time}
#
# @return [void]
def sleep_between_attempts(time=self.sleep_time)
::IO.select(nil,nil,nil,time) unless sleep_time.zero?
end
def each_credential def each_credential
cred_details.each do |raw_cred| cred_details.each do |raw_cred|
@ -148,6 +187,7 @@ module Metasploit
total_error_count = 0 total_error_count = 0
successful_users = Set.new successful_users = Set.new
first_attempt = true
each_credential do |credential| each_credential do |credential|
# Skip users for whom we've have already found a password # Skip users for whom we've have already found a password
@ -161,6 +201,12 @@ module Metasploit
next next
end end
if first_attempt
first_attempt = false
else
sleep_between_attempts
end
result = attempt_login(credential) result = attempt_login(credential)
result.freeze result.freeze

View File

@ -106,7 +106,7 @@ module Metasploit
self.max_send_size ||= 0 self.max_send_size ||= 0
self.send_delay ||= 0 self.send_delay ||= 0
self.ssl = false if self.ssl.nil? self.ssl = false if self.ssl.nil?
end end
# This method takes a response packet and checks to see # This method takes a response packet and checks to see

View File

@ -63,6 +63,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30, connection_timeout: 30,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -61,6 +61,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30, connection_timeout: 30,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -75,6 +75,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],
connection_timeout: 30 connection_timeout: 30

View File

@ -5,6 +5,7 @@
require 'msf/core' require 'msf/core'
require 'metasploit/framework/credential_collection' require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/http'
class Metasploit3 < Msf::Auxiliary class Metasploit3 < Msf::Auxiliary
@ -80,6 +81,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
) )

View File

@ -85,6 +85,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: proxies, proxies: proxies,
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -49,6 +49,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10, connection_timeout: 10,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -100,6 +100,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: @cred_collection, cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5 connection_timeout: 5
) )

View File

@ -82,6 +82,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: @cred_collection, cred_details: @cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5 connection_timeout: 5
) )

View File

@ -160,6 +160,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -44,6 +44,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -48,6 +48,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10, connection_timeout: 10,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -60,6 +60,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10, connection_timeout: 10,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -111,6 +111,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10, connection_timeout: 10,
user_agent: datastore['UserAgent'], user_agent: datastore['UserAgent'],
vhost: datastore['VHOST'] vhost: datastore['VHOST']

View File

@ -91,6 +91,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
) )

View File

@ -51,6 +51,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30, connection_timeout: 30,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -60,6 +60,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30, connection_timeout: 30,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -71,6 +71,7 @@ class Metasploit3 < Msf::Auxiliary
ssl: datastore['SSL'], ssl: datastore['SSL'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],
) )

View File

@ -69,6 +69,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30 connection_timeout: 30
) )

View File

@ -73,6 +73,7 @@ class Metasploit3 < Msf::Auxiliary
host: ip, host: ip,
port: rport, port: rport,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5, connection_timeout: 5,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -60,6 +60,7 @@ class Metasploit3 < Msf::Auxiliary
port: rport, port: rport,
cred_details: collection, cred_details: collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 2 connection_timeout: 2
) )

View File

@ -115,6 +115,7 @@ class Metasploit3 < Msf::Auxiliary
cred_details: cred_collection, cred_details: cred_collection,
proxies: datastore['Proxies'], proxies: datastore['Proxies'],
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: datastore['SSH_TIMEOUT'], connection_timeout: datastore['SSH_TIMEOUT'],
) )

View File

@ -207,6 +207,7 @@ class Metasploit3 < Msf::Auxiliary
port: rport, port: rport,
cred_details: keys, cred_details: keys,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
proxies: datastore['Proxies'], proxies: datastore['Proxies'],
connection_timeout: datastore['SSH_TIMEOUT'], connection_timeout: datastore['SSH_TIMEOUT'],
) )

View File

@ -64,6 +64,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: datastore['Timeout'], connection_timeout: datastore['Timeout'],
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -72,6 +72,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 30, connection_timeout: 30,
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -77,6 +77,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore['PROXIES'], proxies: datastore['PROXIES'],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: datastore['ConnectTimeout'], connection_timeout: datastore['ConnectTimeout'],
max_send_size: datastore['TCP::max_send_size'], max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'], send_delay: datastore['TCP::send_delay'],

View File

@ -59,6 +59,7 @@ class Metasploit3 < Msf::Auxiliary
proxies: datastore["PROXIES"], proxies: datastore["PROXIES"],
cred_details: cred_collection, cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'], stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 10, connection_timeout: 10,
) )

View File

@ -0,0 +1,85 @@
require 'spec_helper'
require 'metasploit/framework/login_scanner/base'
describe Metasploit::Framework::LoginScanner::Base do
let(:base_class) {
Class.new do
include Metasploit::Framework::LoginScanner::Base
def self.model_name
ActiveModel::Name.new(self, nil, 'base')
end
end
}
subject(:login_scanner) { base_class.new }
it { should respond_to :bruteforce_speed }
context 'validations' do
context 'bruteforce_speed' do
it 'is not valid for a non-number' do
login_scanner.bruteforce_speed = "a"
expect(login_scanner).to_not be_valid
expect(login_scanner.errors[:bruteforce_speed]).to include "is not a number"
end
it 'is not valid for a float' do
login_scanner.bruteforce_speed = "3.14"
expect(login_scanner).to_not be_valid
expect(login_scanner.errors[:bruteforce_speed]).to include "must be an integer"
end
it 'is not negative' do
login_scanner.bruteforce_speed = "-1"
expect(login_scanner).to_not be_valid
expect(login_scanner.errors[:bruteforce_speed]).to include "must be greater than or equal to 0"
end
it 'is not greater than five' do
login_scanner.bruteforce_speed = "6"
expect(login_scanner).to_not be_valid
expect(login_scanner.errors[:bruteforce_speed]).to include "must be less than or equal to 5"
end
end
it { should respond_to :sleep_time }
context '#sleep_time' do
context 'default' do
subject(:sleep_time) { base_class.new.sleep_time }
it 'defaults to zero' do
expect(sleep_time).to eq(0)
end
end
context 'set' do
subject(:sleep_time) {
klass = base_class.new
klass.bruteforce_speed = 0
klass.sleep_time
}
it 'is five minutes when bruteforce_speed is set to 0' do
expect(sleep_time).to eq(60 * 5)
end
end
end
it { should respond_to :sleep_between_attempts }
context '#sleep_between_attempts'
context 'default' do
subject(:sleep_between_attempts) { base_class.new.sleep_between_attempts }
it 'returns nothing' do
expect(sleep_between_attempts).to be_nil
end
end
context 'actually sleep a little' do
# I don't want to slow down the test, and I don't really know how
# to test a time interval anyway since rspec disables sleep. :(
end
end
end

View File

@ -38,7 +38,7 @@ describe Metasploit::Framework::LoginScanner::Telnet do
expect(login_scanner.errors[:banner_timeout]).to include "must be greater than or equal to 1" expect(login_scanner.errors[:banner_timeout]).to include "must be greater than or equal to 1"
end end
it 'is valid for a legitimate number' do it 'is valid for a legitimate number' do
login_scanner.port = rand(1000) + 1 login_scanner.port = rand(1000) + 1
expect(login_scanner.errors[:banner_timeout]).to be_empty expect(login_scanner.errors[:banner_timeout]).to be_empty
end end
@ -69,7 +69,7 @@ describe Metasploit::Framework::LoginScanner::Telnet do
expect(login_scanner.errors[:telnet_timeout]).to include "must be greater than or equal to 1" expect(login_scanner.errors[:telnet_timeout]).to include "must be greater than or equal to 1"
end end
it 'is valid for a legitimate number' do it 'is valid for a legitimate number' do
login_scanner.port = rand(1000) + 1 login_scanner.port = rand(1000) + 1
expect(login_scanner.errors[:telnet_timeout]).to be_empty expect(login_scanner.errors[:telnet_timeout]).to be_empty
end end