Make verbose status printing standardized across login modules

git-svn-id: file:///home/svn/framework3/trunk@8866 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2010-03-21 18:42:47 +00:00
parent bb0db3cdf6
commit 480380003c
7 changed files with 80 additions and 50 deletions

View File

@ -17,7 +17,8 @@ def initialize(info = {})
OptPath.new('USER_FILE', [ false, "File containing usernames, one per line" ]), OptPath.new('USER_FILE', [ false, "File containing usernames, one per line" ]),
OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line" ]), OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line" ]),
OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line" ]), OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line" ]),
OptInt.new('BRUTEFORCE_SPEED', [ true, "How fast to bruteforce, from 0 to 5", 5]) OptInt.new('BRUTEFORCE_SPEED', [ true, "How fast to bruteforce, from 0 to 5", 5]),
OptBool.new('VERBOSE', [ true, "Whether to print output for all attempts", true]),
], Auxiliary::AuthBrute) ], Auxiliary::AuthBrute)
@user = nil @user = nil
@ -114,6 +115,21 @@ def userpass_sleep_interval
select(nil,nil,nil,sleep_time) unless sleep_time == 0 select(nil,nil,nil,sleep_time) unless sleep_time == 0
end end
def vprint_status(msg='')
return if not datastore['VERBOSE']
print_status(msg)
end
def vprint_error(msg='')
return if not datastore['VERBOSE']
print_error(msg)
end
def vprint_good(msg='')
return if not datastore['VERBOSE']
print_good(msg)
end
protected protected
# #
# These methods all close their files after reaching EOF so that modifications # These methods all close their files after reaching EOF so that modifications

View File

@ -29,11 +29,6 @@ class Metasploit3 < Msf::Auxiliary
'Author' => 'MC', 'Author' => 'MC',
'License' => MSF_LICENSE 'License' => MSF_LICENSE
) )
register_options(
[
OptBool.new('VERBOSE', [ true, 'Verbose output', false])
], self.class)
end end
def run_host(ip) def run_host(ip)
@ -56,7 +51,7 @@ class Metasploit3 < Msf::Auxiliary
end end
def do_login(user='sa', pass='', this_cred='', verbose=false) def do_login(user='sa', pass='', this_cred='', verbose=false)
print_status("#{rhost}:#{rport} - MSSQL - Trying username:'#{user}' with password:'#{pass}' against #{rhost}:#{rport}") if verbose vprint_status("#{rhost}:#{rport} - MSSQL - Trying username:'#{user}' with password:'#{pass}'")
begin begin
success = mssql_login(user, pass) success = mssql_login(user, pass)
@ -74,7 +69,7 @@ class Metasploit3 < Msf::Auxiliary
self.credentials_good[this_cred] = pass self.credentials_good[this_cred] = pass
return :next_user return :next_user
else else
print_error("#{rhost}:#{rport} failed to login as '#{user}'") if verbose vprint_error("#{rhost}:#{rport} failed to login as '#{user}'")
return return
end end
rescue ::Rex::ConnectionError rescue ::Rex::ConnectionError
@ -82,3 +77,4 @@ class Metasploit3 < Msf::Auxiliary
end end
end end
end end

View File

@ -29,11 +29,6 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Version' => '$Revision$' 'Version' => '$Revision$'
)) ))
register_options(
[
OptBool.new('VERBOSE', [ true, 'Verbose output', false])
], self.class)
end end
@ -44,13 +39,13 @@ class Metasploit3 < Msf::Auxiliary
this_cred = [user,ip,rport].join(":") this_cred = [user,ip,rport].join(":")
next if self.credentials_tried[this_cred] == pass || self.credentials_good[this_cred] next if self.credentials_tried[this_cred] == pass || self.credentials_good[this_cred]
self.credentials_tried[this_cred] = pass self.credentials_tried[this_cred] = pass
do_login(user, pass, this_cred, datastore['VERBOSE']) do_login(user, pass, this_cred)
} }
end end
end end
# Tmtm's rbmysql is only good for recent versions of mysql, according # Tmtm's rbmysql is only good for recent versions of mysql, according
# to http://www.tmtm.org/en/mysql/ruby/. We'll need to write our own # to http://www.tmtm.org/en/mysql/ruby/. We'll need to write our own
# auth checker for earlier versions. Shouldn't be too hard. # auth checker for earlier versions. Shouldn't be too hard.
# This code is essentially the same as the mysql_version module, just less # This code is essentially the same as the mysql_version module, just less
# whitespace and returns false on errors. # whitespace and returns false on errors.
@ -61,8 +56,8 @@ class Metasploit3 < Msf::Auxiliary
disconnect(s) disconnect(s)
rescue ::Rex::ConnectionError, ::EOFError rescue ::Rex::ConnectionError, ::EOFError
return false return false
rescue ::Exception rescue ::Exception => e
print_error("Error: #{$!}") vprint_error("#{rhost}:#{rport} error checking version #{e.class} #{e}")
return false return false
end end
offset = 0 offset = 0
@ -78,7 +73,7 @@ class Metasploit3 < Msf::Auxiliary
version = data[offset..-1].unpack('Z*')[0] version = data[offset..-1].unpack('Z*')[0]
report_service(:host => rhost, :port => rport, :name => "mysql", :info => version) report_service(:host => rhost, :port => rport, :name => "mysql", :info => version)
short_version = version.split('-')[0] short_version = version.split('-')[0]
print_status "#{rhost}:#{rport} - Found remote MySQL version #{short_version}." if datastore['VERBOSE'] vprint_status "#{rhost}:#{rport} - Found remote MySQL version #{short_version}"
int_version(short_version) >= int_version(target) int_version(short_version) >= int_version(target)
end end
@ -100,9 +95,9 @@ class Metasploit3 < Msf::Auxiliary
end end
def do_login(user='root', pass='', this_cred = '', verbose=false) def do_login(user='root', pass='', this_cred = '')
print_status("Trying username:'#{user}' with password:'#{pass}' against #{rhost}:#{rport}") if verbose vprint_status("#{rhost}:#{rport} Trying username:'#{user}' with password:'#{pass}'")
begin begin
mysql_login(user, pass) mysql_login(user, pass)
print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN '#{user}' : '#{pass}'") print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN '#{user}' : '#{pass}'")
@ -116,10 +111,10 @@ class Metasploit3 < Msf::Auxiliary
) )
self.credentials_good[this_cred] = pass self.credentials_good[this_cred] = pass
rescue ::RbMysql::AccessDeniedError rescue ::RbMysql::AccessDeniedError
print_status("#{rhost}:#{rport} failed to login as '#{user}' with password '#{pass}'") if verbose vprint_status("#{rhost}:#{rport} failed to login as '#{user}' with password '#{pass}'")
return :fail return :fail
rescue ::RbMysql::Error => e rescue ::RbMysql::Error => e
print_error("#{rhost}:#{rport} failed to login: #{e}") vprint_error("#{rhost}:#{rport} failed to login: #{e.class} #{e}")
return :error return :error
rescue ::Interrupt rescue ::Interrupt
raise $! raise $!

View File

@ -18,7 +18,7 @@ class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::AuthBrute include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Scanner include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
# Creates an instance of this module. # Creates an instance of this module.
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(info,
@ -32,7 +32,7 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'References' => 'References' =>
[ [
[ 'URL', 'www.postgresql.org' ] [ 'URL', 'http://www.postgresql.org' ]
], ],
'Version' => '$Revision$' 'Version' => '$Revision$'
)) ))
@ -60,7 +60,7 @@ class Metasploit3 < Msf::Auxiliary
self.credentials_tried[this_cred] = pass self.credentials_tried[this_cred] = pass
datastore['USERNAME'] = user datastore['USERNAME'] = user
datastore['PASSWORD'] = pass datastore['PASSWORD'] = pass
do_login(user,pass,this_cred,datastore['DATABASE'],datastore['VERBOSE']) do_login(user,pass,this_cred)
} }
end end
@ -69,7 +69,7 @@ class Metasploit3 < Msf::Auxiliary
datastore['RHOST'] datastore['RHOST']
end end
# Alias for RPORT # Alias for RPORT
def rport def rport
datastore['RPORT'] datastore['RPORT']
end end
@ -77,10 +77,11 @@ class Metasploit3 < Msf::Auxiliary
# Actually do all the login stuff. Note that "verbose" is really pretty # Actually do all the login stuff. Note that "verbose" is really pretty
# verbose, since postgres_login also makes use of the verbose value # verbose, since postgres_login also makes use of the verbose value
# to print diagnostics for other modules. # to print diagnostics for other modules.
def do_login(user=nil,pass=nil,this_cred='',database=nil,verbose=false) def do_login(user=nil,pass=nil,this_cred='')
database = datastore['DATABASE']
begin begin
msg = "#{rhost}:#{rport} Postgres -" msg = "#{rhost}:#{rport} Postgres -"
print_status("#{msg} Trying username:'#{user}' with password:'#{pass}' against #{rhost}:#{rport} on database '#{database}'") if verbose vprint_status("#{msg} Trying username:'#{user}' with password:'#{pass}' on database '#{database}'")
# Here's where the actual connection happens. # Here's where the actual connection happens.
result = postgres_login( result = postgres_login(
:db => database, :db => database,
@ -94,7 +95,7 @@ class Metasploit3 < Msf::Auxiliary
self.credentials_good[this_cred] = pass self.credentials_good[this_cred] = pass
return :next_user # This is a success for user:pass! return :next_user # This is a success for user:pass!
when :error_credentials when :error_credentials
print_error("#{msg} Username/Password failed.") if verbose vprint_error("#{msg} Username/Password failed.")
return return
when :connected when :connected
print_good("#{msg} Success: #{user}:#{pass} (Database '#{database}' succeeded.)") print_good("#{msg} Success: #{user}:#{pass} (Database '#{database}' succeeded.)")
@ -103,11 +104,11 @@ class Metasploit3 < Msf::Auxiliary
postgres_logout postgres_logout
return :next_user return :next_user
when :error when :error
print_error("#{msg} Unknown error encountered, quitting.") if verbose vprint_error("#{msg} Unknown error encountered, giving up on host")
return :done return :done
end end
rescue Rex::ConnectionError rescue Rex::ConnectionError
print_error "#{rhost}:#{rport} Connection Error: #{$!}" if datastore['VERBOSE'] vprint_error "#{rhost}:#{rport} Connection Error: #{$!}"
return :done return :done
end end
end end
@ -137,3 +138,4 @@ class Metasploit3 < Msf::Auxiliary
end end
end end

View File

@ -53,11 +53,16 @@ class Metasploit3 < Msf::Auxiliary
end end
def run_host(ip) def run_host(ip)
print_status("Starting host #{ip}") vprint_status("Starting SMB login attempt on #{ip}")
if (datastore["SMBUser"] and not datastore["SMBUser"].empty?) if (datastore["SMBUser"] and not datastore["SMBUser"].empty?)
# then just do this user/pass # then just do this user/pass
try_user_pass(datastore["SMBUser"], datastore["SMBPass"], [datastore["SMBUser"],ip,rport].join(":")) try_user_pass(datastore["SMBUser"], datastore["SMBPass"], [datastore["SMBUser"],ip,rport].join(":"))
else else
if accepts_bogus_logins?
print_error("This system accepts authentication with any credentials, brute force is ineffective.")
return
end
begin begin
each_user_pass do |user, pass| each_user_pass do |user, pass|
userpass_sleep_interval unless self.credentials_tried.empty? userpass_sleep_interval unless self.credentials_tried.empty?
@ -71,6 +76,23 @@ class Metasploit3 < Msf::Auxiliary
end end
end end
def accepts_bogus_logins?
datastore["SMBUser"] = Rex::Text.rand_text_alpha(8)
datastore["SMBPass"] = Rex::Text.rand_text_alpha(8)
# Connection problems are dealt with at a higher level
connect()
begin
smb_login()
rescue ::Rex::Proto::SMB::Exceptions::LoginError => e
end
disconnect
simple.client.auth_user ? true : false
end
def try_user_pass(user, pass, this_cred) def try_user_pass(user, pass, this_cred)
datastore["SMBUser"] = user datastore["SMBUser"] = user
datastore["SMBPass"] = pass datastore["SMBPass"] = pass
@ -85,6 +107,7 @@ class Metasploit3 < Msf::Auxiliary
case e.error_reason case e.error_reason
when 'STATUS_LOGON_FAILURE' when 'STATUS_LOGON_FAILURE'
# Nothing interesting # Nothing interesting
vprint_status("#{rhost} - FAILED LOGIN (#{smb_peer_os}) #{user} : #{pass} (#{e.error_reason})")
disconnect() disconnect()
return return

View File

@ -41,14 +41,13 @@ class Metasploit3 < Msf::Auxiliary
[ [
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]), OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]), OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),
OptBool.new('VERBOSE', [ true, 'Verbose output', false]),
Opt::RPORT(22) Opt::RPORT(22)
], self.class ], self.class
) )
register_advanced_options( register_advanced_options(
[ [
OptBool.new('SSH_Debug', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]) OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false])
] ]
) )
@ -71,7 +70,7 @@ class Metasploit3 < Msf::Auxiliary
:password => pass :password => pass
} }
opt_hash.merge!(:verbose => :debug) if datastore['SSH_Debug'] opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG']
begin begin
self.ssh_socket = Net::SSH.start( self.ssh_socket = Net::SSH.start(
@ -137,6 +136,8 @@ class Metasploit3 < Msf::Auxiliary
this_cred = [user,ip,rport].join(":") this_cred = [user,ip,rport].join(":")
next if self.credentials_tried[this_cred] == pass || self.credentials_good[this_cred] next if self.credentials_tried[this_cred] == pass || self.credentials_good[this_cred]
self.credentials_tried[this_cred] = pass self.credentials_tried[this_cred] = pass
vprint_status("#{ip}:#{rport} - SSH - Trying: username: '#{user}' with password: '#{pass}'")
ret,proof = do_login(ip,user,pass,rport) ret,proof = do_login(ip,user,pass,rport)
case ret case ret
when :success when :success
@ -144,15 +145,16 @@ class Metasploit3 < Msf::Auxiliary
self.credentials_good[this_cred] = pass self.credentials_good[this_cred] = pass
do_report(ip,user,pass,rport,proof) do_report(ip,user,pass,rport,proof)
when :connection_error when :connection_error
print_error "#{ip}:#{rport} - Could not connect" if datastore['VERBOSE'] vprint_error "#{ip}:#{rport} - SSH - Could not connect"
return return
when :connection_disconnect when :connection_disconnect
print_error "#{ip}:#{rport} - Connection timed out" if datastore['VERBOSE'] vprint_error "#{ip}:#{rport} - SSH - Connection timed out"
return return
when :fail when :fail
print_error "#{ip}:#{rport} - SSH - Failed: '#{user}':'#{pass}'" if datastore['VERBOSE'] vprint_error "#{ip}:#{rport} - SSH - Failed: '#{user}':'#{pass}'"
end end
end end
end end
end end

View File

@ -46,11 +46,6 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE 'License' => MSF_LICENSE
) )
deregister_options('RHOST') deregister_options('RHOST')
register_options(
[
OptBool.new('VERBOSE', [ true, 'Verbose output', false])
], Msf::Exploit::Remote::Telnet
)
register_advanced_options( register_advanced_options(
[ [
OptInt.new('TIMEOUT', [ true, 'Default timeout for telnet connections. The greatest value of TelnetTimeout, TelnetBannerTimeout, or this option will be used as an overall timeout.', 0]) OptInt.new('TIMEOUT', [ true, 'Default timeout for telnet connections. The greatest value of TelnetTimeout, TelnetBannerTimeout, or this option will be used as an overall timeout.', 0])
@ -91,16 +86,16 @@ class Metasploit3 < Msf::Auxiliary
else else
self.credentials_tried[this_cred] = pass self.credentials_tried[this_cred] = pass
end end
print_status "#{rhost}:#{rport} Telnet - Attempting: '#{user}':'#{pass}'" if datastore['VERBOSE'] vprint_status "#{rhost}:#{rport} Telnet - Attempting: '#{user}':'#{pass}'"
ret = do_login(user,pass) ret = do_login(user,pass)
if ret == :no_pass_prompt if ret == :no_pass_prompt
print_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to missing password prompt" if datastore['VERBOSE'] vprint_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to missing password prompt"
self.no_pass_prompt << this_cred self.no_pass_prompt << this_cred
elsif ret == :timeout elsif ret == :timeout
print_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to timeout" if datastore['VERBOSE'] vprint_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to timeout"
elsif ret == :busy elsif ret == :busy
print_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to busy state" if datastore['VERBOSE'] vprint_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to busy state"
else else
start_telnet_session(rhost,rport,user,pass) if login_succeeded? start_telnet_session(rhost,rport,user,pass) if login_succeeded?
end end
@ -114,7 +109,7 @@ class Metasploit3 < Msf::Auxiliary
begin begin
print_status("#{rhost}:#{rport} Banner: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") if datastore['VERBOSE'] vprint_status("#{rhost}:#{rport} Banner: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
if busy_message? if busy_message?
self.sock.close unless self.sock.closed? self.sock.close unless self.sock.closed?
@ -146,7 +141,7 @@ class Metasploit3 < Msf::Auxiliary
recv_telnet(self.sock, 0.10) recv_telnet(self.sock, 0.10)
end end
print_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") if datastore['VERBOSE'] vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
if password_prompt? if password_prompt?
send_pass(pass) send_pass(pass)
@ -157,7 +152,7 @@ class Metasploit3 < Msf::Auxiliary
end end
print_status("#{rhost}:#{rport} Result: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") if datastore['VERBOSE'] vprint_status("#{rhost}:#{rport} Result: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
if login_succeeded? if login_succeeded?
report_telnet(user,pass,@trace) report_telnet(user,pass,@trace)
@ -218,3 +213,4 @@ class Metasploit3 < Msf::Auxiliary
end end
end end