From 3aa7b513d5b25e8c30dcf17a02094628034fb868 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 9 Oct 2015 13:34:38 -0500 Subject: [PATCH 1/2] Delete safe_get_once --- lib/msf/java/rmi/client.rb | 48 +------------------ .../java/rmi/client/jmx/connection_spec.rb | 24 ---------- .../msf/java/rmi/client/jmx/server_spec.rb | 8 ---- spec/lib/msf/java/rmi/client_spec.rb | 8 ---- 4 files changed, 2 insertions(+), 86 deletions(-) diff --git a/lib/msf/java/rmi/client.rb b/lib/msf/java/rmi/client.rb index 9cb6987357..f14ff153da 100644 --- a/lib/msf/java/rmi/client.rb +++ b/lib/msf/java/rmi/client.rb @@ -19,23 +19,6 @@ module Msf include Msf::Java::Rmi::Client::Jmx include Exploit::Remote::Tcp - def initialize(info = {}) - super - - register_advanced_options( - [ - OptInt.new('RmiReadLoopTimeout', [ true, 'Maximum number of seconds to wait for data between read iterations', 1]) - ], Msf::Java::Rmi::Client - ) - end - - # Returns the timeout to wait for data between read iterations - # - # @return [Fixnum] - def read_loop_timeout - datastore['RmiReadLoopTimeout'] || 1 - end - # Returns the target host # # @return [String] @@ -103,9 +86,8 @@ module Msf # @see Rex::Proto::Rmi::Model::ProtocolAck.decode def recv_protocol_ack(opts = {}) nsock = opts[:sock] || sock - data = safe_get_once(nsock) begin - ack = Rex::Proto::Rmi::Model::ProtocolAck.decode(StringIO.new(data)) + ack = Rex::Proto::Rmi::Model::ProtocolAck.decode(nsock) rescue Rex::Proto::Rmi::DecodeError return nil end @@ -123,41 +105,15 @@ module Msf # @see Rex::Proto::Rmi::Model::ReturnData.decode def recv_return(opts = {}) nsock = opts[:sock] || sock - data = safe_get_once(nsock) begin - return_data = Rex::Proto::Rmi::Model::ReturnData.decode(StringIO.new(data)) + return_data = Rex::Proto::Rmi::Model::ReturnData.decode(nsock) rescue Rex::Proto::Rmi::DecodeError return nil end return_data.return_value end - - # Helper method to read fragmented data from a ```Rex::Socket::Tcp``` - # - # @param nsock [Rex::Socket::Tcp] - # @return [String] - def safe_get_once(nsock = sock, loop_timeout = read_loop_timeout) - data = '' - begin - res = nsock.get_once - rescue ::EOFError - res = nil - end - - while res && nsock.has_read_data?(loop_timeout) - data << res - begin - res = nsock.get_once - rescue ::EOFError - res = nil - end - end - - data << res if res - data - end end end end diff --git a/spec/lib/msf/java/rmi/client/jmx/connection_spec.rb b/spec/lib/msf/java/rmi/client/jmx/connection_spec.rb index 068988f14a..58200f856e 100644 --- a/spec/lib/msf/java/rmi/client/jmx/connection_spec.rb +++ b/spec/lib/msf/java/rmi/client/jmx/connection_spec.rb @@ -101,14 +101,6 @@ describe Msf::Java::Rmi::Client::Jmx::Connection do io.write(get_object_instance_response) io.seek(0) end - - allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout| - io.read - end - - allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io| - false - end end it "returns true" do @@ -125,14 +117,6 @@ describe Msf::Java::Rmi::Client::Jmx::Connection do io.write(create_mbean_response) io.seek(0) end - - allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout| - io.read - end - - allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io| - false - end end it "returns true" do @@ -149,14 +133,6 @@ describe Msf::Java::Rmi::Client::Jmx::Connection do io.write(invoke_response) io.seek(0) end - - allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout| - io.read - end - - allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io| - false - end end it "returns true" do diff --git a/spec/lib/msf/java/rmi/client/jmx/server_spec.rb b/spec/lib/msf/java/rmi/client/jmx/server_spec.rb index fbc2bf81ed..c8528f2031 100644 --- a/spec/lib/msf/java/rmi/client/jmx/server_spec.rb +++ b/spec/lib/msf/java/rmi/client/jmx/server_spec.rb @@ -47,14 +47,6 @@ describe Msf::Java::Rmi::Client::Jmx::Server do io.write(new_client_response) io.seek(0) end - - allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout| - io.read - end - - allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io| - false - end end it "returns the reference information" do diff --git a/spec/lib/msf/java/rmi/client_spec.rb b/spec/lib/msf/java/rmi/client_spec.rb index 008b543ae1..5ae74bfacc 100644 --- a/spec/lib/msf/java/rmi/client_spec.rb +++ b/spec/lib/msf/java/rmi/client_spec.rb @@ -44,14 +44,6 @@ describe Msf::Java::Rmi::Client do allow_any_instance_of(::StringIO).to receive(:put) do |io, data| io.write(data) end - - allow_any_instance_of(::StringIO).to receive(:get_once) do |io, length, timeout| - io.read - end - - allow_any_instance_of(::StringIO).to receive(:has_read_data?) do |io| - false - end end describe "#send_header" do From 347495e2f57175709d7c5ef41b50409f8eebd4ad Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 9 Oct 2015 13:41:41 -0500 Subject: [PATCH 2/2] Rescue Rex::StreamClosedError when there is a session --- modules/exploits/multi/misc/java_rmi_server.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/exploits/multi/misc/java_rmi_server.rb b/modules/exploits/multi/misc/java_rmi_server.rb index b557a3bf4b..dde9a19bad 100644 --- a/modules/exploits/multi/misc/java_rmi_server.rb +++ b/modules/exploits/multi/misc/java_rmi_server.rb @@ -154,7 +154,13 @@ class Metasploit3 < Msf::Exploit::Remote arguments: build_dgc_clean_args(new_url) ) - return_value = recv_return + begin + return_value = recv_return + rescue Rex::StreamClosedError + # There should be a session... + disconnect + return + end if return_value.nil? && !session_created? fail_with(Failure::Unknown, 'RMI Call failed')