From 0540e25db2f1bfe011e105d2fd62e4233119e390 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Wed, 25 Mar 2015 11:29:07 -0500 Subject: [PATCH] Calculate the java/rmi/registry/RegistryImpl_Stub hash dinamically --- lib/msf/java/rmi/client/registry.rb | 38 +++++++++++++++++++ lib/msf/java/rmi/client/registry/builder.rb | 4 +- lib/msf/java/rmi/util.rb | 4 +- .../auxiliary/scanner/misc/java_rmi_server.rb | 15 ++++++-- spec/lib/msf/java/rmi/client/registry_spec.rb | 6 +++ spec/lib/msf/java/rmi/util_spec.rb | 26 +++++-------- 6 files changed, 68 insertions(+), 25 deletions(-) diff --git a/lib/msf/java/rmi/client/registry.rb b/lib/msf/java/rmi/client/registry.rb index 997d49bab0..3a10d7b2ea 100644 --- a/lib/msf/java/rmi/client/registry.rb +++ b/lib/msf/java/rmi/client/registry.rb @@ -84,6 +84,44 @@ module Msf names end + + # Calculates the hash to make RMI calls for the + # java/rmi/registry/RegistryImpl_Stub interface + # + # @return [Fixnum] The interface's hash + def registry_interface_hash + hash = calculate_interface_hash( + [ + { + name: 'bind', + descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V', + exceptions: ['java.rmi.AccessException', 'java.rmi.AlreadyBoundException', 'java.rmi.RemoteException'] + }, + { + name: 'list', + descriptor: '()[Ljava/lang/String;', + exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException'] + }, + { + name: 'lookup', + descriptor: '(Ljava/lang/String;)Ljava/rmi/Remote;', + exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException'] + }, + { + name: 'rebind', + descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V', + exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException'] + }, + { + name: 'unbind', + descriptor: '(Ljava/lang/String;)V', + exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException'] + } + ] + ) + + hash + end end end end diff --git a/lib/msf/java/rmi/client/registry/builder.rb b/lib/msf/java/rmi/client/registry/builder.rb index 338f800ecb..acc9b11113 100644 --- a/lib/msf/java/rmi/client/registry/builder.rb +++ b/lib/msf/java/rmi/client/registry/builder.rb @@ -27,7 +27,7 @@ module Msf uid_time: uid_time, uid_count: uid_count, operation: 2, # java.rmi.Remote lookup(java.lang.String) - hash: 0x44154dc9d4e63bdf, # RegistryImpl_Stub + hash: registry_interface_hash, arguments: [Rex::Java::Serialization::Model::Utf.new(nil, name)] ) @@ -52,7 +52,7 @@ module Msf uid_time: uid_time, uid_count: uid_count, operation: 1, # java.lang.String list()[] - hash: 0x44154dc9d4e63bdf, # RegistryImpl_Stub + hash: registry_interface_hash, arguments: [] ) diff --git a/lib/msf/java/rmi/util.rb b/lib/msf/java/rmi/util.rb index 8f6515974b..61e70c8238 100644 --- a/lib/msf/java/rmi/util.rb +++ b/lib/msf/java/rmi/util.rb @@ -25,7 +25,7 @@ module Msf # @param exceptions [Array] set of declared exceptions # @return [Fixnum] The interface hash # @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how interface hashes are calculated - def calculate_interface_hash(methods, exceptions) + def calculate_interface_hash(methods) stream = '' stream << [1].pack('N') # stub version number @@ -34,7 +34,7 @@ module Msf utf_descriptor = Rex::Java::Serialization::Model::Utf.new(nil, m[:descriptor]) stream << utf_method.encode stream << utf_descriptor.encode - exceptions.each do |e| + m[:exceptions].each do |e| utf_exception = Rex::Java::Serialization::Model::Utf.new(nil, e) stream << utf_exception.encode end diff --git a/modules/auxiliary/scanner/misc/java_rmi_server.rb b/modules/auxiliary/scanner/misc/java_rmi_server.rb index 7a70976d6f..f78fd7017b 100644 --- a/modules/auxiliary/scanner/misc/java_rmi_server.rb +++ b/modules/auxiliary/scanner/misc/java_rmi_server.rb @@ -53,10 +53,17 @@ class Metasploit3 < Msf::Auxiliary dgc_interface_hash = calculate_interface_hash( [ - {name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V'}, - {name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;'} - ], - ['java.rmi.RemoteException'] + { + name: 'clean', + descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V', + exceptions: ['java.rmi.RemoteException'] + }, + { + name: 'dirty', + descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;', + exceptions: ['java.rmi.RemoteException'] + } + ] ) # JDK 1.1 stub protocol diff --git a/spec/lib/msf/java/rmi/client/registry_spec.rb b/spec/lib/msf/java/rmi/client/registry_spec.rb index 4c707b1ee5..ce7496e567 100644 --- a/spec/lib/msf/java/rmi/client/registry_spec.rb +++ b/spec/lib/msf/java/rmi/client/registry_spec.rb @@ -227,5 +227,11 @@ describe Msf::Java::Rmi::Client::Registry do end end end + + describe "#registry_interface_hash" do + it "calculates the hash for the java/rmi/registry/RegistryImpl_Stub correctly" do + expect(mod.registry_interface_hash).to eq(4905912898345647071) + end + end end diff --git a/spec/lib/msf/java/rmi/util_spec.rb b/spec/lib/msf/java/rmi/util_spec.rb index 11a15f8c20..b8cc6351fc 100644 --- a/spec/lib/msf/java/rmi/util_spec.rb +++ b/spec/lib/msf/java/rmi/util_spec.rb @@ -12,18 +12,14 @@ describe Msf::Java::Rmi::Util do mod end - let(:interface_methods) do + let(:example_interface) do [ - {name: 'sayHello', descriptor: '()Ljava/lang/String;'}, - {name: 'sayHelloTwo', descriptor: '(Ljava/lang/String;)Ljava/lang/String;'} + {name: 'sayHello', descriptor: '()Ljava/lang/String;', exceptions: ['java.rmi.RemoteException']}, + {name: 'sayHelloTwo', descriptor: '(Ljava/lang/String;)Ljava/lang/String;', exceptions: ['java.rmi.RemoteException']} ] end - let(:interface_exceptions) do - ['java.rmi.RemoteException'] - end - - let(:interface_hash) do + let(:example_hash) do 0x3e664fcbd9e953bb end @@ -35,17 +31,13 @@ describe Msf::Java::Rmi::Util do 0x53e0822d3e3724df end - let(:dgc_methods) do + let(:dgc_interface) do [ - {name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V'}, - {name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;'} + {name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V', exceptions: ['java.rmi.RemoteException']}, + {name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;', exceptions: ['java.rmi.RemoteException']} ] end - let(:dgc_exceptions) do - ['java.rmi.RemoteException'] - end - let(:dgc_hash) do 0xf6b6898d8bf28643 end @@ -83,13 +75,13 @@ describe Msf::Java::Rmi::Util do describe "#calculate_interface_hash" do context "when an example interface is provided" do it "generates a correct interface hash" do - expect(mod.calculate_interface_hash(interface_methods, interface_exceptions)).to eq(interface_hash) + expect(mod.calculate_interface_hash(example_interface)).to eq(example_hash) end end context "when a DGC interface is provided" do it "generates a correct interface hash" do - expect(mod.calculate_interface_hash(dgc_methods, dgc_exceptions)).to eq(dgc_hash) + expect(mod.calculate_interface_hash(dgc_interface)).to eq(dgc_hash) end end end