Skip to content

Commit 48975a4

Browse files
committed
Support multiple suffixes on meterpreter extensions.
1 parent daf2acc commit 48975a4

File tree

5 files changed

+75
-21
lines changed

5 files changed

+75
-21
lines changed

lib/msf/base/sessions/meterpreter.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -635,24 +635,24 @@ def binary_suffix
635635
# Platform-agnostic archs go first
636636
case self.arch
637637
when 'java'
638-
'jar'
638+
['jar']
639639
when 'php'
640-
'php'
640+
['php']
641641
when 'python'
642-
'py'
642+
['py']
643643
else
644644
# otherwise we fall back to the platform
645645
case self.platform
646646
when 'windows'
647-
"#{self.arch}.dll"
647+
["#{self.arch}.dll"]
648648
when 'linux' , 'aix' , 'hpux' , 'irix' , 'unix'
649-
'bin'
649+
['bin', 'elf']
650650
when 'android', 'java'
651-
'jar'
651+
['jar']
652652
when 'php'
653-
'php'
653+
['php']
654654
when 'python'
655-
'py'
655+
['py']
656656
else
657657
nil
658658
end

lib/rex/post/meterpreter/client_core.rb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,14 @@ def load_library(opts)
249249
# path of the local and target so that it gets loaded with a random
250250
# name
251251
if opts['Extension']
252-
library_path = "ext#{rand(1000000)}.#{client.binary_suffix}"
252+
if client.binary_suffix.size > 1
253+
m = /(.*)\.(.*)/.match(library_path)
254+
suffix = $2
255+
else
256+
suffix = client.binary_suffix
257+
end
258+
259+
library_path = "ext#{rand(1000000)}.#{suffix}"
253260
target_path = library_path
254261
end
255262
end
@@ -296,6 +303,20 @@ def use(mod, opts = { })
296303
raise RuntimeError, "No modules were specified", caller
297304
end
298305

306+
modnameprovided = mod
307+
suffix = nil
308+
if client.binary_suffix.size > 1
309+
client.binary_suffix.each { |s|
310+
if (mod =~ /(.*)\.#{s}/ )
311+
mod = $1
312+
suffix = s
313+
break
314+
end
315+
}
316+
else
317+
suffix = client.binary_suffix.first
318+
end
319+
299320
# Query the remote instance to see if commands for the extension are
300321
# already loaded
301322
commands = get_loaded_extension_commands(mod.downcase)
@@ -306,14 +327,14 @@ def use(mod, opts = { })
306327
# Get us to the installation root and then into data/meterpreter, where
307328
# the file is expected to be
308329
modname = "ext_server_#{mod.downcase}"
309-
path = MetasploitPayloads.meterpreter_path(modname, client.binary_suffix)
330+
path = MetasploitPayloads.meterpreter_path(modname, suffix)
310331

311332
if opts['ExtensionPath']
312333
path = ::File.expand_path(opts['ExtensionPath'])
313334
end
314335

315336
if path.nil?
316-
raise RuntimeError, "No module of the name #{modname}.#{client.binary_suffix} found", caller
337+
raise RuntimeError, "No module of the name #{modnameprovided} found", caller
317338
end
318339

319340
# Load the extension DLL

lib/rex/post/meterpreter/extensions/priv/priv.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,19 @@ def getsystem( technique=0 )
4545

4646
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
4747

48-
elevator_path = MetasploitPayloads.meterpreter_path('elevator', client.binary_suffix)
48+
elevator_path = nil
49+
client.binary_suffix.each { |s|
50+
elevator_path = MetasploitPayloads.meterpreter_path('elevator', s)
51+
if !elevator_path.nil?
52+
break
53+
end
54+
}
4955
if elevator_path.nil?
50-
raise RuntimeError, "elevator.#{binary_suffix} not found", caller
56+
elevators = ""
57+
client.binary_suffix.each { |s|
58+
elevators << "elevator.#{s}, "
59+
}
60+
raise RuntimeError, "#{elevators.chomp(', ')} not found", caller
5161
end
5262

5363
elevator_data = ""

lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,8 +1151,16 @@ def cmd_load(*args)
11511151
gem_path = MetasploitPayloads.local_meterpreter_dir
11521152
[msf_path, gem_path].each do |path|
11531153
::Dir.entries(path).each { |f|
1154-
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
1155-
exts.add($1)
1154+
if (::File.file?(::File.join(path, f)))
1155+
client.binary_suffix.each { |s|
1156+
if (f =~ /ext_server_(.*)\.#{s}/ )
1157+
if (client.binary_suffix.size > 1)
1158+
exts.add($1 + ".#{s}")
1159+
else
1160+
exts.add($1)
1161+
end
1162+
end
1163+
}
11561164
end
11571165
}
11581166
end
@@ -1168,7 +1176,16 @@ def cmd_load(*args)
11681176
# Load each of the modules
11691177
args.each { |m|
11701178
md = m.downcase
1179+
modulenameprovided = md
11711180

1181+
if client.binary_suffix.size > 1
1182+
client.binary_suffix.each { |s|
1183+
if (md =~ /(.*)\.#{s}/ )
1184+
md = $1
1185+
break
1186+
end
1187+
}
1188+
end
11721189
if (extensions.include?(md))
11731190
print_error("The '#{md}' extension has already been loaded.")
11741191
next
@@ -1178,7 +1195,7 @@ def cmd_load(*args)
11781195

11791196
begin
11801197
# Use the remote side, then load the client-side
1181-
if (client.core.use(md) == true)
1198+
if (client.core.use(modulenameprovided) == true)
11821199
add_extension_client(md)
11831200
end
11841201
rescue
@@ -1199,10 +1216,16 @@ def cmd_load_tabs(str, words)
11991216
gem_path = MetasploitPayloads.local_meterpreter_dir
12001217
[msf_path, gem_path].each do |path|
12011218
::Dir.entries(path).each { |f|
1202-
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
1203-
if (not extensions.include?($1))
1204-
tabs.add($1)
1205-
end
1219+
if (::File.file?(::File.join(path, f)))
1220+
client.binary_suffix.each { |s|
1221+
if (f =~ /ext_server_(.*)\.#{s}/ )
1222+
if (client.binary_suffix.size > 1 && !extensions.include?($1 + ".#{s}"))
1223+
tabs.add($1 + ".#{s}")
1224+
elsif (!extensions.include?($1))
1225+
tabs.add($1)
1226+
end
1227+
end
1228+
}
12061229
end
12071230
}
12081231
end

spec/lib/rex/post/meterpreter/client_core_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
allow(@response).to receive(:result) { 0 }
1515
allow(@response).to receive(:each) { [:help] }
1616
@client = double("client")
17-
allow(@client).to receive(:binary_suffix) { "x64.dll" }
17+
allow(@client).to receive(:binary_suffix) { ["x64.dll"] }
1818
allow(@client).to receive(:capabilities) { {:ssl => false, :zlib => false } }
1919
allow(@client).to receive(:response_timeout) { 1 }
2020
allow(@client).to receive(:send_packet_wait_response) { @response }

0 commit comments

Comments
 (0)