Fixes up various usability bugs with AuthBrute, many of which revolved around smb_login tests.

git-svn-id: file:///home/svn/framework3/trunk@9086 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Tod Beardsley 2010-04-15 17:29:47 +00:00
parent 8e5f0a37d8
commit 888e80f92c
4 changed files with 64 additions and 32 deletions

View File

@ -40,24 +40,25 @@ def each_user_pass(&block)
users = extract_words(datastore['USER_FILE'])
passwords = extract_words(datastore['PASS_FILE'])
translate_smb_datastores()
if datastore['USERNAME']
users << datastore['USERNAME']
users.unshift datastore['USERNAME']
credentials = prepend_chosen_username(datastore['USERNAME'],credentials)
end
if datastore['PASSWORD']
passwords << datastore['PASSWORD']
passwords.unshift datastore['PASSWORD']
credentials = prepend_chosen_password(datastore['PASSWORD'],credentials)
end
if datastore['BLANK_PASSWORDS']
credentials = gen_blank_passwords(users,credentials) + credentials
credentials = gen_blank_passwords(users,credentials)
end
credentials.concat(combine_users_and_passwords(users,passwords))
credentials = just_uniq_passwords(credentials) if @strip_usernames
if datastore['USERNAME']
credentials.unshift( [datastore['USERNAME'], datastore['PASSWORD'].to_s] )
end
credentials.each do |u,p|
fq_user = "%s:%s:%s" % [datastore['RHOST'], datastore['RPORT'], u]
userpass_sleep_interval unless @@credentials_tried.empty?
@ -75,9 +76,27 @@ def each_user_pass(&block)
return
end
# Takes SMBUser and SMBPass, and, if present, prefers those
# over any given USERNAME or PASSWORD.
def translate_smb_datastores
if datastore['SMBUser'] and !datastore['SMBUser'].empty?
datastore['USERNAME'] = datastore['SMBUser']
end
if datastore['SMBPass'] and !datastore['SMBPass'].empty?
datastore['PASSWORD'] = datastore['SMBPass']
end
end
def just_uniq_passwords(credentials)
new_creds = credentials.map{|x| x[0] = ""; x}
credentials.uniq
credentials.map{|x| ["",x[1]]}.uniq
end
def prepend_chosen_username(user,cred_array)
cred_array.map {|pair| [user,pair[1]]} + cred_array
end
def prepend_chosen_password(pass,cred_array)
cred_array.map {|pair| [pair[0],pass]} + cred_array
end
def gen_blank_passwords(user_array,cred_array)
@ -88,7 +107,7 @@ def gen_blank_passwords(user_array,cred_array)
unless cred_array.empty?
cred_array.each {|u,p| blank_passwords << [u,""]}
end
return blank_passwords
return(blank_passwords + cred_array)
end
def combine_users_and_passwords(user_array,pass_array)
@ -107,7 +126,21 @@ def combine_users_and_passwords(user_array,pass_array)
end
end
end
return combined_array
# Move datastore['USERNAME'] and datastore['PASSWORD'] to the front of the list.
creds = [ [], [], [], [] ] # userpass, pass, user, rest
combined_array.each do |pair|
if pair == [datastore['USERNAME'],datastore['PASSWORD']]
creds[0] << pair
elsif pair[1] == datastore['PASSWORD']
creds[1] << pair
elsif pair[0] == datastore['USERNAME']
creds[2] << pair
else
creds[3] << pair
end
end
return creds[0] + creds[1] + creds[2] + creds[3]
end
def extract_words(wordfile)

View File

@ -41,8 +41,6 @@ class Metasploit3 < Msf::Auxiliary
File.join(Msf::Config.install_root, "data", "wordlists", "db2_default_pass.txt") ]),
], self.class)
# Users must use user/pass/userpass files.
deregister_options('USERNAME' , 'PASSWORD')
end
def run_host(ip)

View File

@ -44,8 +44,8 @@ class Metasploit3 < Msf::Auxiliary
OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line", File.join(Msf::Config.install_root, "data", "wordlists", "postgres_default_pass.txt") ]),
], self.class)
# Users should use user/pass/userpass files.
deregister_options('USERNAME', 'PASSWORD', 'SQL')
deregister_options('SQL')
end
# Loops through each host in turn. Note the current IP address is both

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary
'Author' => 'tebo <tebo [at] attackresearch [dot] com>',
'License' => MSF_LICENSE
)
deregister_options('RHOST')
deregister_options('RHOST','USERNAME','PASSWORD')
# These are normally advanced options, but for this module they have a
# more active role, so make them regular options.
@ -54,26 +54,24 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
vprint_status("Starting SMB login attempt on #{ip}")
if (datastore["SMBUser"] and not datastore["SMBUser"].empty?)
# then just do this user/pass
try_user_pass(datastore["SMBUser"], datastore["SMBPass"])
else
if accepts_bogus_logins?
print_error("This system accepts authentication with any credentials, brute force is ineffective.")
return
end
begin
each_user_pass do |user, pass|
try_user_pass(user, pass)
end
rescue ::Rex::ConnectionError
nil
end
if accepts_bogus_logins?
print_error("This system accepts authentication with any credentials, brute force is ineffective.")
return
end
begin
each_user_pass do |user, pass|
try_user_pass(user, pass)
end
rescue ::Rex::ConnectionError
nil
end
end
def accepts_bogus_logins?
orig_user,orig_pass = datastore['SMBUser'],datastore['SMBPass']
datastore["SMBUser"] = Rex::Text.rand_text_alpha(8)
datastore["SMBPass"] = Rex::Text.rand_text_alpha(8)
@ -86,11 +84,14 @@ class Metasploit3 < Msf::Auxiliary
end
disconnect
datastore['SMBUser'],datastore['SMBPass'] = orig_user,orig_pass
simple.client.auth_user ? true : false
end
def try_user_pass(user, pass)
# The SMB mixins require the datastores "SMBUser" and
# "SMBPass" to be populated.
datastore["SMBUser"] = user
datastore["SMBPass"] = pass
@ -143,7 +144,7 @@ class Metasploit3 < Msf::Auxiliary
disconnect()
return
end
if(simple.client.auth_user)
print_good("#{rhost} - SUCCESSFUL LOGIN (#{smb_peer_os}) '#{user}' : '#{pass}'")
report_auth_info(