@@ -27,7 +27,8 @@ def initialize
27
27
'SecureState R&D Team' ,
28
28
'sinn3r' ,
29
29
'Brandon Knight' ,
30
- 'Pete (Bokojan) Arzamendi, #Outlook 2013 updates'
30
+ 'Pete (Bokojan) Arzamendi - Outlook 2013 updates' ,
31
+ 'Nate Power - HTTP timing option'
31
32
] ,
32
33
'License' => MSF_LICENSE ,
33
34
'Actions' =>
@@ -81,6 +82,7 @@ def initialize
81
82
OptInt . new ( 'RPORT' , [ true , "The target port" , 443 ] ) ,
82
83
OptAddress . new ( 'RHOST' , [ true , "The target address" , true ] ) ,
83
84
OptBool . new ( 'ENUM_DOMAIN' , [ true , "Automatically enumerate AD domain using NTLM authentication" , true ] ) ,
85
+ OptBool . new ( 'AUTH_TIME' , [ false , "Time HTTP authentication response(in seconds)" , true ] ) ,
84
86
] , self . class )
85
87
86
88
@@ -163,6 +165,7 @@ def try_user_pass(opts)
163
165
end
164
166
165
167
begin
168
+ start_time = Time . now
166
169
res = send_request_cgi ( {
167
170
'encode' => true ,
168
171
'uri' => auth_path ,
@@ -171,6 +174,10 @@ def try_user_pass(opts)
171
174
'data' => data
172
175
} )
173
176
177
+ if ( datastore [ 'AUTH_TIME' ] . to_s . match ( /^(t|y|1)/i ) )
178
+ elapsed_time = Time . now - start_time
179
+ end
180
+
174
181
rescue ::Rex ::ConnectionError , Errno ::ECONNREFUSED , Errno ::ETIMEDOUT
175
182
print_error ( "#{ msg } HTTP Connection Failed, Aborting" )
176
183
return :abort
@@ -186,10 +193,10 @@ def try_user_pass(opts)
186
193
return :abort
187
194
end
188
195
if action . name == "OWA_2013"
189
- # Check for a response code to make sure login was valid. Changes from 2010 to 2013.
190
- # Check if the password needs to be changed.
196
+ #Check for a response code to make sure login was valid. Changes from 2010 to 2013.
197
+ #Check if the password needs to be changed.
191
198
if res . headers [ 'location' ] =~ /expiredpassword/
192
- print_good ( "#{ msg } SUCCESSFUL LOGIN. '#{ user } ' : '#{ pass } ': NOTE password change required" )
199
+ print_good ( "#{ msg } SUCCESSFUL LOGIN. #{ elapsed_time } '#{ user } ' : '#{ pass } ': NOTE password change required" )
193
200
report_hash = {
194
201
:host => datastore [ 'RHOST' ] ,
195
202
:port => datastore [ 'RPORT' ] ,
@@ -203,7 +210,7 @@ def try_user_pass(opts)
203
210
return :next_user
204
211
end
205
212
206
- # No password change required moving on.
213
+ #No password change required moving on.
207
214
unless location = res . headers [ 'location' ]
208
215
print_error ( "#{ msg } No HTTP redirect. This is not OWA 2013, aborting." )
209
216
return :abort
@@ -212,8 +219,8 @@ def try_user_pass(opts)
212
219
if reason == nil
213
220
headers [ 'Cookie' ] = 'PBack=0;' << res . get_cookies
214
221
else
215
- # Login didn't work. no point on going on.
216
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (HTTP redirect with reason #{ reason } )" )
222
+ #Login didn't work. no point on going on.
223
+ vprint_error ( "#{ msg } FAILED LOGIN. #{ elapsed_time } '#{ user } ' : '#{ pass } ' (HTTP redirect with reason #{ reason } )" )
217
224
return :Skip_pass
218
225
end
219
226
else
@@ -248,12 +255,12 @@ def try_user_pass(opts)
248
255
end
249
256
250
257
if res . redirect?
251
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (response was a #{ res . code } redirect)" )
258
+ vprint_error ( "#{ msg } FAILED LOGIN. #{ elapsed_time } '#{ user } ' : '#{ pass } ' (response was a #{ res . code } redirect)" )
252
259
return :skip_pass
253
260
end
254
261
255
262
if res . body =~ login_check
256
- print_good ( "#{ msg } SUCCESSFUL LOGIN. '#{ user } ' : '#{ pass } '" )
263
+ print_good ( "#{ msg } SUCCESSFUL LOGIN. #{ elapsed_time } '#{ user } ' : '#{ pass } '" )
257
264
258
265
report_hash = {
259
266
:host => datastore [ 'RHOST' ] ,
@@ -267,7 +274,7 @@ def try_user_pass(opts)
267
274
report_auth_info ( report_hash )
268
275
return :next_user
269
276
else
270
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (response body did not match)" )
277
+ vprint_error ( "#{ msg } FAILED LOGIN. #{ elapsed_time } '#{ user } ' : '#{ pass } ' (response body did not match)" )
271
278
return :skip_pass
272
279
end
273
280
end
0 commit comments