@@ -42,7 +42,7 @@ def winrm_poke(timeout = 20)
42
42
c = connect ( opts )
43
43
to = opts [ :timeout ] || timeout
44
44
ctype = "application/soap+xml;charset=UTF-8"
45
- resp , c = send_request_cgi ( opts . merge ( {
45
+ resp , c = send_winrm_request ( opts . merge ( {
46
46
'uri' => opts [ 'uri' ] ,
47
47
'method' => 'POST' ,
48
48
'ctype' => ctype ,
@@ -61,7 +61,7 @@ def parse_auth_methods(resp)
61
61
end
62
62
63
63
def winrm_run_cmd ( cmd , timeout = 20 )
64
- resp , c = send_request_ntlm ( winrm_open_shell_msg , timeout )
64
+ resp = send_winrm_request ( winrm_open_shell_msg , timeout )
65
65
if resp . nil?
66
66
print_error "Recieved no reply from server"
67
67
return nil
@@ -76,17 +76,17 @@ def winrm_run_cmd(cmd, timeout=20)
76
76
return retval
77
77
end
78
78
shell_id = winrm_get_shell_id ( resp )
79
- resp , c = send_request_ntlm ( winrm_cmd_msg ( cmd , shell_id ) , timeout )
79
+ resp = send_winrm_request ( winrm_cmd_msg ( cmd , shell_id ) , timeout )
80
80
cmd_id = winrm_get_cmd_id ( resp )
81
- resp , c = send_request_ntlm ( winrm_cmd_recv_msg ( shell_id , cmd_id ) , timeout )
81
+ resp = send_winrm_request ( winrm_cmd_recv_msg ( shell_id , cmd_id ) , timeout )
82
82
streams = winrm_get_cmd_streams ( resp )
83
- resp , c = send_request_ntlm ( winrm_terminate_cmd_msg ( shell_id , cmd_id ) , timeout )
84
- resp , c = send_request_ntlm ( winrm_delete_shell_msg ( shell_id ) )
83
+ resp = send_winrm_request ( winrm_terminate_cmd_msg ( shell_id , cmd_id ) , timeout )
84
+ resp = send_winrm_request ( winrm_delete_shell_msg ( shell_id ) )
85
85
return streams
86
86
end
87
87
88
88
def winrm_run_cmd_hanging ( cmd , timeout = 20 )
89
- resp , c = send_request_ntlm ( winrm_open_shell_msg , timeout )
89
+ resp = send_winrm_request ( winrm_open_shell_msg , timeout )
90
90
if resp . nil?
91
91
print_error "Recieved no reply from server"
92
92
return nil
@@ -101,9 +101,9 @@ def winrm_run_cmd_hanging(cmd, timeout=20)
101
101
return retval
102
102
end
103
103
shell_id = winrm_get_shell_id ( resp )
104
- resp , c = send_request_ntlm ( winrm_cmd_msg ( cmd , shell_id ) , timeout )
104
+ resp = send_winrm_request ( winrm_cmd_msg ( cmd , shell_id ) , timeout )
105
105
cmd_id = winrm_get_cmd_id ( resp )
106
- resp , c = send_request_ntlm ( winrm_cmd_recv_msg ( shell_id , cmd_id ) , timeout )
106
+ resp = send_winrm_request ( winrm_cmd_recv_msg ( shell_id , cmd_id ) , timeout )
107
107
streams = winrm_get_cmd_streams ( resp )
108
108
return streams
109
109
end
@@ -219,94 +219,6 @@ def generate_uuid
219
219
::Rex ::Proto ::DCERPC ::UUID . uuid_unpack ( Rex ::Text . rand_text ( 16 ) )
220
220
end
221
221
222
- def send_request_ntlm ( data , timeout = 20 )
223
- opts = {
224
- 'uri' => datastore [ 'URI' ] ,
225
- 'data' => data ,
226
- 'username' => datastore [ 'USERNAME' ] ,
227
- 'password' => datastore [ 'PASSWORD' ]
228
- }
229
- ntlm_options = {
230
- :signing => false ,
231
- :usentlm2_session => datastore [ 'NTLM::UseNTLM2_session' ] ,
232
- :use_ntlmv2 => datastore [ 'NTLM::UseNTLMv2' ] ,
233
- :send_lm => datastore [ 'NTLM::SendLM' ] ,
234
- :send_ntlm => datastore [ 'NTLM::SendNTLM' ]
235
- }
236
- ntlmssp_flags = NTLM_UTILS . make_ntlm_flags ( ntlm_options )
237
- workstation_name = Rex ::Text . rand_text_alpha ( rand ( 8 ) +1 )
238
- domain_name = datastore [ 'DOMAIN' ]
239
- ntlm_message_1 = "NEGOTIATE " + Rex ::Text ::encode_base64 ( NTLM_UTILS ::make_ntlmssp_blob_init ( domain_name ,
240
- workstation_name ,
241
- ntlmssp_flags ) )
242
- to = opts [ :timeout ] || timeout
243
- begin
244
- c = connect ( opts )
245
- ctype = "application/soap+xml;charset=UTF-8"
246
- # First request to get the challenge
247
- r = c . request_cgi ( opts . merge ( {
248
- 'uri' => opts [ 'uri' ] ,
249
- 'method' => 'POST' ,
250
- 'ctype' => ctype ,
251
- 'headers' => { 'Authorization' => ntlm_message_1 } ,
252
- 'data' => opts [ 'data' ]
253
- } ) )
254
- resp = c . send_recv ( r , to )
255
- unless resp . kind_of? Rex ::Proto ::Http ::Response
256
- return [ nil , nil ]
257
- end
258
- return [ nil , nil ] if resp . code == 404
259
- return [ nil , nil ] unless resp . code == 401 && resp . headers [ 'WWW-Authenticate' ]
260
- # Get the challenge and craft the response
261
- ntlm_challenge = resp . headers [ 'WWW-Authenticate' ] . match ( /NEGOTIATE ([A-Z0-9\x2b \x2f =]+)/i ) [ 1 ]
262
- return [ nil , nil ] unless ntlm_challenge
263
-
264
- #old and simplier method but not compatible with windows 7/2008r2
265
- #ntlm_message_2 = Rex::Proto::NTLM::Message.decode64(ntlm_challenge)
266
- #ntlm_message_3 = ntlm_message_2.response( {:user => opts['username'],:password => opts['password']}, {:ntlmv2 => true})
267
- ntlm_message_2 = Rex ::Text ::decode_base64 ( ntlm_challenge )
268
- blob_data = NTLM_UTILS . parse_ntlm_type_2_blob ( ntlm_message_2 )
269
- challenge_key = blob_data [ :challenge_key ]
270
- server_ntlmssp_flags = blob_data [ :server_ntlmssp_flags ] #else should raise an error
271
- #netbios name
272
- default_name = blob_data [ :default_name ] || ''
273
- #netbios domain
274
- default_domain = blob_data [ :default_domain ] || ''
275
- #dns name
276
- dns_host_name = blob_data [ :dns_host_name ] || ''
277
- #dns domain
278
- dns_domain_name = blob_data [ :dns_domain_name ] || ''
279
- #Client time
280
- chall_MsvAvTimestamp = blob_data [ :chall_MsvAvTimestamp ] || ''
281
- spnopt = { :use_spn => datastore [ 'NTLM::SendSPN' ] , :name => self . rhost }
282
- resp_lm ,
283
- resp_ntlm ,
284
- client_challenge ,
285
- ntlm_cli_challenge = NTLM_UTILS . create_lm_ntlm_responses ( opts [ 'username' ] , opts [ 'password' ] , challenge_key ,
286
- domain_name , default_name , default_domain ,
287
- dns_host_name , dns_domain_name , chall_MsvAvTimestamp ,
288
- spnopt , ntlm_options )
289
- ntlm_message_3 = NTLM_UTILS . make_ntlmssp_blob_auth ( domain_name , workstation_name , opts [ 'username' ] ,
290
- resp_lm , resp_ntlm , '' , ntlmssp_flags )
291
- ntlm_message_3 = Rex ::Text ::encode_base64 ( ntlm_message_3 )
292
- # Send the response
293
- r = c . request_cgi ( opts . merge ( {
294
- 'uri' => opts [ 'uri' ] ,
295
- 'method' => 'POST' ,
296
- 'ctype' => ctype ,
297
- 'headers' => { 'Authorization' => "NEGOTIATE #{ ntlm_message_3 } " } ,
298
- 'data' => opts [ 'data' ]
299
- } ) )
300
- resp = c . send_recv ( r , to , true )
301
- unless resp . kind_of? Rex ::Proto ::Http ::Response
302
- return [ nil , nil ]
303
- end
304
- return [ nil , nil ] if resp . code == 404
305
- return [ resp , c ]
306
- rescue ::Errno ::EPIPE , ::Timeout ::Error
307
- end
308
- end
309
-
310
222
def accepts_ntlm_auth
311
223
parse_auth_methods ( winrm_poke ) . include? "Negotiate"
312
224
end
@@ -329,6 +241,18 @@ def wmi_namespace
329
241
return "/root/cimv2/"
330
242
end
331
243
244
+ def send_winrm_request ( data , timeout = 20 )
245
+ opts = {
246
+ 'uri' => datastore [ 'URI' ] ,
247
+ 'method' => 'POST' ,
248
+ 'data' => data ,
249
+ 'username' => datastore [ 'USERNAME' ] ,
250
+ 'password' => datastore [ 'PASSWORD' ] ,
251
+ 'ctype' => "application/soap+xml;charset=UTF-8"
252
+ }
253
+ send_request_cgi ( opts , timeout )
254
+ end
255
+
332
256
333
257
private
334
258
0 commit comments