Support multiple suffixes on meterpreter extensions.

MS-2855/keylogger-mettle-extension
Pearce Barry 2017-10-12 11:00:24 -05:00
parent daf2acc2b1
commit 48975a4327
No known key found for this signature in database
GPG Key ID: 0916F4DEA5C5DE0A
5 changed files with 75 additions and 21 deletions

View File

@ -635,24 +635,24 @@ class Meterpreter < Rex::Post::Meterpreter::Client
# Platform-agnostic archs go first
case self.arch
when 'java'
'jar'
['jar']
when 'php'
'php'
['php']
when 'python'
'py'
['py']
else
# otherwise we fall back to the platform
case self.platform
when 'windows'
"#{self.arch}.dll"
["#{self.arch}.dll"]
when 'linux' , 'aix' , 'hpux' , 'irix' , 'unix'
'bin'
['bin', 'elf']
when 'android', 'java'
'jar'
['jar']
when 'php'
'php'
['php']
when 'python'
'py'
['py']
else
nil
end

View File

@ -249,7 +249,14 @@ class ClientCore < Extension
# path of the local and target so that it gets loaded with a random
# name
if opts['Extension']
library_path = "ext#{rand(1000000)}.#{client.binary_suffix}"
if client.binary_suffix.size > 1
m = /(.*)\.(.*)/.match(library_path)
suffix = $2
else
suffix = client.binary_suffix
end
library_path = "ext#{rand(1000000)}.#{suffix}"
target_path = library_path
end
end
@ -296,6 +303,20 @@ class ClientCore < Extension
raise RuntimeError, "No modules were specified", caller
end
modnameprovided = mod
suffix = nil
if client.binary_suffix.size > 1
client.binary_suffix.each { |s|
if (mod =~ /(.*)\.#{s}/ )
mod = $1
suffix = s
break
end
}
else
suffix = client.binary_suffix.first
end
# Query the remote instance to see if commands for the extension are
# already loaded
commands = get_loaded_extension_commands(mod.downcase)
@ -306,14 +327,14 @@ class ClientCore < Extension
# Get us to the installation root and then into data/meterpreter, where
# the file is expected to be
modname = "ext_server_#{mod.downcase}"
path = MetasploitPayloads.meterpreter_path(modname, client.binary_suffix)
path = MetasploitPayloads.meterpreter_path(modname, suffix)
if opts['ExtensionPath']
path = ::File.expand_path(opts['ExtensionPath'])
end
if path.nil?
raise RuntimeError, "No module of the name #{modname}.#{client.binary_suffix} found", caller
raise RuntimeError, "No module of the name #{modnameprovided} found", caller
end
# Load the extension DLL

View File

@ -45,9 +45,19 @@ class Priv < Extension
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
elevator_path = MetasploitPayloads.meterpreter_path('elevator', client.binary_suffix)
elevator_path = nil
client.binary_suffix.each { |s|
elevator_path = MetasploitPayloads.meterpreter_path('elevator', s)
if !elevator_path.nil?
break
end
}
if elevator_path.nil?
raise RuntimeError, "elevator.#{binary_suffix} not found", caller
elevators = ""
client.binary_suffix.each { |s|
elevators << "elevator.#{s}, "
}
raise RuntimeError, "#{elevators.chomp(', ')} not found", caller
end
elevator_data = ""

View File

@ -1151,8 +1151,16 @@ class Console::CommandDispatcher::Core
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
exts.add($1)
if (::File.file?(::File.join(path, f)))
client.binary_suffix.each { |s|
if (f =~ /ext_server_(.*)\.#{s}/ )
if (client.binary_suffix.size > 1)
exts.add($1 + ".#{s}")
else
exts.add($1)
end
end
}
end
}
end
@ -1168,7 +1176,16 @@ class Console::CommandDispatcher::Core
# Load each of the modules
args.each { |m|
md = m.downcase
modulenameprovided = md
if client.binary_suffix.size > 1
client.binary_suffix.each { |s|
if (md =~ /(.*)\.#{s}/ )
md = $1
break
end
}
end
if (extensions.include?(md))
print_error("The '#{md}' extension has already been loaded.")
next
@ -1178,7 +1195,7 @@ class Console::CommandDispatcher::Core
begin
# Use the remote side, then load the client-side
if (client.core.use(md) == true)
if (client.core.use(modulenameprovided) == true)
add_extension_client(md)
end
rescue
@ -1199,10 +1216,16 @@ class Console::CommandDispatcher::Core
gem_path = MetasploitPayloads.local_meterpreter_dir
[msf_path, gem_path].each do |path|
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
if (not extensions.include?($1))
tabs.add($1)
end
if (::File.file?(::File.join(path, f)))
client.binary_suffix.each { |s|
if (f =~ /ext_server_(.*)\.#{s}/ )
if (client.binary_suffix.size > 1 && !extensions.include?($1 + ".#{s}"))
tabs.add($1 + ".#{s}")
elsif (!extensions.include?($1))
tabs.add($1)
end
end
}
end
}
end

View File

@ -14,7 +14,7 @@ RSpec.describe Rex::Post::Meterpreter::ClientCore do
allow(@response).to receive(:result) { 0 }
allow(@response).to receive(:each) { [:help] }
@client = double("client")
allow(@client).to receive(:binary_suffix) { "x64.dll" }
allow(@client).to receive(:binary_suffix) { ["x64.dll"] }
allow(@client).to receive(:capabilities) { {:ssl => false, :zlib => false } }
allow(@client).to receive(:response_timeout) { 1 }
allow(@client).to receive(:send_packet_wait_response) { @response }