From 25dcfc796afdae103dd28c91b9bab56a4fba54c9 Mon Sep 17 00:00:00 2001 From: OJ Date: Tue, 24 Mar 2015 10:14:44 +1000 Subject: [PATCH] Better support old binaries in rev http(s) * Patch 256char URL if the 512char one doesn't work. * Return an empty list in the case where the ext enum fails. --- .../core/payload/windows/stageless_meterpreter.rb | 7 ++++++- lib/rex/payloads/meterpreter/patch.rb | 13 ++++++++++++- lib/rex/post/meterpreter/client_core.rb | 9 ++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/payload/windows/stageless_meterpreter.rb b/lib/msf/core/payload/windows/stageless_meterpreter.rb index 1c79d9ecd1..af21900d2d 100644 --- a/lib/msf/core/payload/windows/stageless_meterpreter.rb +++ b/lib/msf/core/payload/windows/stageless_meterpreter.rb @@ -77,7 +77,12 @@ module Payload::Windows::StagelessMeterpreter # the URL might not be given, as it might be patched in some other way if url # Patch the URL using the patcher as this upports both ASCII and WCHAR. - Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00") + unless Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00") + # If the patching failed this could mean that we are somehow + # working with outdated binaries, so try to patch with the + # old stuff. + Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 256}", "s#{url}\x00") + end end # if a block is given then call that with the meterpreter dll diff --git a/lib/rex/payloads/meterpreter/patch.rb b/lib/rex/payloads/meterpreter/patch.rb index 166eb7f7cf..c04b67ffc0 100644 --- a/lib/rex/payloads/meterpreter/patch.rb +++ b/lib/rex/payloads/meterpreter/patch.rb @@ -18,7 +18,12 @@ module Rex # Replace the URL def self.patch_url!(blob, url) - patch_string!(blob, "https://#{'X' * 512}", url) + unless patch_string!(blob, "https://#{'X' * 512}", url) + # If the patching failed this could mean that we are somehow + # working with outdated binaries, so try to patch with the + # old stuff. + patch_string!(blob, "https://#{'X' * 256}", url) + end end # Replace the session expiration timeout @@ -122,16 +127,22 @@ module Rex # Patch an ASCII value in the given payload. If not found, try WCHAR instead. # def self.patch_string!(blob, search, replacement) + result = false + i = blob.index(search) if i blob[i, replacement.length] = replacement + result = true else i = blob.index(wchar(search)) if i r = wchar(replacement) blob[i, r.length] = r + result = true end end + + result end private diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index d2cf08bb88..df0befed5c 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -48,7 +48,14 @@ class ClientCore < Extension request = Packet.create_request('core_enumextcmd') request.add_tlv(TLV_TYPE_STRING, extension_name) - response = self.client.send_packet_wait_response(request, self.client.response_timeout) + begin + response = self.client.send_packet_wait_response(request, self.client.response_timeout) + rescue + # In the case where orphaned shells call back with OLD copies of the meterpreter + # binaries, we end up with a case where this fails. So here we just return the + # empty list of supported commands. + return [] + end # No response? if response.nil?