diff --git a/lib/rex/post/meterpreter/extension_mapper.rb b/lib/rex/post/meterpreter/extension_mapper.rb index 057ff9c9853a..d3ee0a693263 100644 --- a/lib/rex/post/meterpreter/extension_mapper.rb +++ b/lib/rex/post/meterpreter/extension_mapper.rb @@ -8,36 +8,55 @@ class ExtensionMapper @@klasses = {} + def self.get_extension_names + base = ::File.join(File.dirname(__dir__), 'meterpreter/extensions') + ::Dir.entries(base).select do |e| + ::File.directory?(::File.join(base, e)) && !['.', '..'].include?(e) + end + end + def self.get_extension_id(name) k = self.get_extension_klass(name) k.extension_id end + def self.get_extension_name(id) + self.get_extension_names.each do |name| + begin + klass = self.get_extension_klass(name) + rescue RuntimeError + next + end + return name if klass.extension_id == id + end + end + + def self.get_extension_module(name) + name.downcase! + + begin + require("rex/post/meterpreter/extensions/#{name}/#{name}") + rescue LoadError + # the extension doesn't exist on disk + raise RuntimeError, "Unable to load extension '#{name}' - module does not exist." + end + s = Rex::Post::Meterpreter::Extensions.constants.find { |c| name == c.to_s.downcase } + Rex::Post::Meterpreter::Extensions.const_get(s) + end + def self.get_extension_klass(name) name.downcase! unless @@klasses[name] - begin - require("rex/post/meterpreter/extensions/#{name}/#{name}") - rescue LoadError - # the extension doesn't exist on disk - raise RuntimeError, "Unable to load extension '#{name}' - module does not exist." - end - s = Rex::Post::Meterpreter::Extensions.constants.select { |c| - name == c.to_s.downcase - }[0] - @@klasses[name] = Rex::Post::Meterpreter::Extensions.const_get(s).const_get(s) + mod = self.get_extension_module(name) + @@klasses[name] = mod.const_get(mod.name.split('::').last) end @@klasses[name] end def self.dump_extensions - base = ::File.join(File.dirname(__dir__), 'meterpreter/extensions') - names = ::Dir.entries(base).select { |e| - ::File.directory?(::File.join(base, e)) && !['.', '..'].include?(e) - } - names.each { |n| + self.get_extension_names.each { |n| STDERR.puts("EXTENSION_ID_#{n.upcase} = #{self.get_extension_id(n)}\n") } end diff --git a/lib/rex/post/meterpreter/packet_dispatcher.rb b/lib/rex/post/meterpreter/packet_dispatcher.rb index d58e68fd0073..eb141a795101 100644 --- a/lib/rex/post/meterpreter/packet_dispatcher.rb +++ b/lib/rex/post/meterpreter/packet_dispatcher.rb @@ -14,8 +14,21 @@ module Meterpreter # ### class RequestError < ArgumentError - def initialize(method, einfo, ecode=nil) - @method = method + def initialize(command_id, einfo, ecode=nil) + extension_id = command_id - (command_id % 1000) + if extension_id == 0 # this is the meterpreter core + mod = Rex::Post::Meterpreter + else + mod_name = Rex::Post::Meterpreter::ExtensionMapper.get_extension_name(extension_id) + mod = Rex::Post::Meterpreter::ExtensionMapper.get_extension_module(mod_name) + end + + if mod + command_name = mod.constants.select { |c| c.start_with?('COMMAND_ID_') }.find { |c| command_id == mod.const_get(c) } + command_name = command_name.to_s.delete_prefix('COMMAND_ID_').downcase if command_name + end + + @method = command_name || "##{command_id}" @result = einfo @code = ecode || einfo end