@@ -204,24 +204,31 @@ def try_user_pass(opts)
204
204
end
205
205
206
206
#No password change required moving on.
207
- reason = res . headers [ 'location' ] . split ( 'reason=' ) [ 1 ]
207
+ unless location = res . headers [ 'location' ]
208
+ print_error ( "#{ msg } No HTTP redirect. This is not OWA 2013, aborting." )
209
+ return :abort
210
+ end
211
+ reason = location . split ( 'reason=' ) [ 1 ]
208
212
if reason == nil
209
213
headers [ 'Cookie' ] = 'PBack=0;' << res . get_cookies
210
214
else
211
215
#Login didn't work. no point on going on.
212
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } '" )
216
+ vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (HTTP redirect with reason #{ reason } ) " )
213
217
return :Skip_pass
214
218
end
215
219
else
216
220
# The authentication info is in the cookies on this response
217
221
cookies = res . get_cookies
218
- sessionid_value = cookies . split ( 'sessionid=' ) [ 1 ]
219
- sessionid_value = sessionid_value . to_s . split ( '; ' ) [ 0 ]
220
- sessionid_header = "sessionid=#{ sessionid_value } "
221
- cadata_value = cookies . split ( 'cadata=' ) [ 1 ]
222
- cadata_value = cadata_value . to_s . split ( '; ' ) [ 0 ]
223
- cadata_header = "cadata=#{ cadata_value } "
224
- headers [ 'Cookie' ] = 'PBack=0; ' << sessionid_header << '; ' << cadata_header
222
+ cookie_header = 'PBack=0'
223
+ %w( sessionid cadata ) . each do |necessary_cookie |
224
+ if cookies =~ /#{ necessary_cookie } =([^;]+)/
225
+ cookie_header << "; #{ Regexp . last_match ( 1 ) } "
226
+ else
227
+ print_error ( "#{ msg } Missing #{ necessary_cookie } cookie. This is not OWA 2010, aborting" )
228
+ return :abort
229
+ end
230
+ end
231
+ headers [ 'Cookie' ] = cookie_header
225
232
end
226
233
227
234
begin
@@ -240,8 +247,8 @@ def try_user_pass(opts)
240
247
return :abort
241
248
end
242
249
243
- if res . code == 302
244
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } '" )
250
+ if res . redirect?
251
+ vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (response was a #{ res . code } redirect) " )
245
252
return :skip_pass
246
253
end
247
254
@@ -260,7 +267,7 @@ def try_user_pass(opts)
260
267
report_auth_info ( report_hash )
261
268
return :next_user
262
269
else
263
- vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } '" )
270
+ vprint_error ( "#{ msg } FAILED LOGIN. '#{ user } ' : '#{ pass } ' (response body did not match) " )
264
271
return :skip_pass
265
272
end
266
273
end
@@ -295,7 +302,7 @@ def get_ad_domain
295
302
next
296
303
end
297
304
298
- if res and res . code == 401 and res [ 'WWW-Authenticate' ] . match ( /^NTLM/i )
305
+ if res && res . code == 401 && res . headers . has_key? ( 'WWW-Authenticate' ) && res . headers [ 'WWW-Authenticate' ] . match ( /^NTLM/i )
299
306
hash = res [ 'WWW-Authenticate' ] . split ( 'NTLM ' ) [ 1 ]
300
307
domain = Rex ::Proto ::NTLM ::Message . parse ( Rex ::Text . decode_base64 ( hash ) ) [ :target_name ] . value ( ) . gsub ( /\0 / , '' )
301
308
print_good ( "Found target domain: " + domain )
0 commit comments