Fix winrm mixin from revert merge

bug/bundler_fix
David Maloney 2013-02-19 22:01:43 -06:00
parent b2563dd6c2
commit ac6fdf24a2
1 changed files with 20 additions and 97 deletions

View File

@ -42,7 +42,7 @@ module Exploit::Remote::WinRM
c = connect(opts) c = connect(opts)
to = opts[:timeout] || timeout to = opts[:timeout] || timeout
ctype = "application/soap+xml;charset=UTF-8" ctype = "application/soap+xml;charset=UTF-8"
resp, c = send_request_cgi(opts.merge({ resp = send_winrm_request(opts.merge({
'uri' => opts['uri'], 'uri' => opts['uri'],
'method' => 'POST', 'method' => 'POST',
'ctype' => ctype, 'ctype' => ctype,
@ -61,7 +61,7 @@ module Exploit::Remote::WinRM
end end
def winrm_run_cmd(cmd, timeout=20) def winrm_run_cmd(cmd, timeout=20)
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout) resp = send_winrm_request(winrm_open_shell_msg,timeout)
if resp.nil? if resp.nil?
print_error "Recieved no reply from server" print_error "Recieved no reply from server"
return nil return nil
@ -76,17 +76,17 @@ module Exploit::Remote::WinRM
return retval return retval
end end
shell_id = winrm_get_shell_id(resp) shell_id = winrm_get_shell_id(resp)
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout) resp = send_winrm_request(winrm_cmd_msg(cmd, shell_id),timeout)
cmd_id = winrm_get_cmd_id(resp) cmd_id = winrm_get_cmd_id(resp)
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id),timeout) resp = send_winrm_request(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
streams = winrm_get_cmd_streams(resp) streams = winrm_get_cmd_streams(resp)
resp,c = send_request_ntlm(winrm_terminate_cmd_msg(shell_id,cmd_id),timeout) resp = send_winrm_request(winrm_terminate_cmd_msg(shell_id,cmd_id),timeout)
resp,c = send_request_ntlm(winrm_delete_shell_msg(shell_id)) resp = send_winrm_request(winrm_delete_shell_msg(shell_id))
return streams return streams
end end
def winrm_run_cmd_hanging(cmd, timeout=20) def winrm_run_cmd_hanging(cmd, timeout=20)
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout) resp = send_winrm_request(winrm_open_shell_msg,timeout)
if resp.nil? if resp.nil?
print_error "Recieved no reply from server" print_error "Recieved no reply from server"
return nil return nil
@ -101,9 +101,9 @@ module Exploit::Remote::WinRM
return retval return retval
end end
shell_id = winrm_get_shell_id(resp) shell_id = winrm_get_shell_id(resp)
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout) resp = send_winrm_request(winrm_cmd_msg(cmd, shell_id),timeout)
cmd_id = winrm_get_cmd_id(resp) cmd_id = winrm_get_cmd_id(resp)
resp,c = send_request_ntlm(winrm_cmd_recv_msg(shell_id,cmd_id),timeout) resp = send_winrm_request(winrm_cmd_recv_msg(shell_id,cmd_id),timeout)
streams = winrm_get_cmd_streams(resp) streams = winrm_get_cmd_streams(resp)
return streams return streams
end end
@ -219,94 +219,6 @@ module Exploit::Remote::WinRM
::Rex::Proto::DCERPC::UUID.uuid_unpack(Rex::Text.rand_text(16)) ::Rex::Proto::DCERPC::UUID.uuid_unpack(Rex::Text.rand_text(16))
end end
def send_request_ntlm(data, timeout = 20)
opts = {
'uri' => datastore['URI'],
'data' => data,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
}
ntlm_options = {
:signing => false,
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
:send_lm => datastore['NTLM::SendLM'],
:send_ntlm => datastore['NTLM::SendNTLM']
}
ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
domain_name = datastore['DOMAIN']
ntlm_message_1 = "NEGOTIATE " + Rex::Text::encode_base64(NTLM_UTILS::make_ntlmssp_blob_init( domain_name,
workstation_name,
ntlmssp_flags))
to = opts[:timeout] || timeout
begin
c = connect(opts)
ctype = "application/soap+xml;charset=UTF-8"
# First request to get the challenge
r = c.request_cgi(opts.merge({
'uri' => opts['uri'],
'method' => 'POST',
'ctype' => ctype,
'headers' => { 'Authorization' => ntlm_message_1},
'data' => opts['data']
}))
resp = c.send_recv(r, to)
unless resp.kind_of? Rex::Proto::Http::Response
return [nil,nil]
end
return [nil,nil] if resp.code == 404
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
# Get the challenge and craft the response
ntlm_challenge = resp.headers['WWW-Authenticate'].match(/NEGOTIATE ([A-Z0-9\x2b\x2f=]+)/i)[1]
return [nil,nil] unless ntlm_challenge
#old and simplier method but not compatible with windows 7/2008r2
#ntlm_message_2 = Rex::Proto::NTLM::Message.decode64(ntlm_challenge)
#ntlm_message_3 = ntlm_message_2.response( {:user => opts['username'],:password => opts['password']}, {:ntlmv2 => true})
ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)
blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(ntlm_message_2)
challenge_key = blob_data[:challenge_key]
server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
#netbios name
default_name = blob_data[:default_name] || ''
#netbios domain
default_domain = blob_data[:default_domain] || ''
#dns name
dns_host_name = blob_data[:dns_host_name] || ''
#dns domain
dns_domain_name = blob_data[:dns_domain_name] || ''
#Client time
chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
spnopt = {:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
resp_lm,
resp_ntlm,
client_challenge,
ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(opts['username'], opts['password'], challenge_key,
domain_name, default_name, default_domain,
dns_host_name, dns_domain_name, chall_MsvAvTimestamp,
spnopt, ntlm_options)
ntlm_message_3 = NTLM_UTILS.make_ntlmssp_blob_auth(domain_name, workstation_name, opts['username'],
resp_lm, resp_ntlm, '', ntlmssp_flags)
ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
# Send the response
r = c.request_cgi(opts.merge({
'uri' => opts['uri'],
'method' => 'POST',
'ctype' => ctype,
'headers' => { 'Authorization' => "NEGOTIATE #{ntlm_message_3}"},
'data' => opts['data']
}))
resp = c.send_recv(r, to, true)
unless resp.kind_of? Rex::Proto::Http::Response
return [nil,nil]
end
return [nil,nil] if resp.code == 404
return [resp,c]
rescue ::Errno::EPIPE, ::Timeout::Error
end
end
def accepts_ntlm_auth def accepts_ntlm_auth
parse_auth_methods(winrm_poke).include? "Negotiate" parse_auth_methods(winrm_poke).include? "Negotiate"
end end
@ -329,6 +241,17 @@ module Exploit::Remote::WinRM
return "/root/cimv2/" return "/root/cimv2/"
end end
def send_winrm_request(data, timeout=20)
opts = {
'uri' => datastore['URI'],
'method' => 'POST',
'data' => data,
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD'],
'ctype' => "application/soap+xml;charset=UTF-8"
}
send_request_cgi(opts,timeout)
end
private private