Map Meterpreter command IDs to their names when raising a RequestError

This commit is contained in:
Spencer McIntyre
2020-12-28 15:11:07 -05:00
parent 2af64c43e9
commit a0b26429a6
2 changed files with 49 additions and 17 deletions
+34 -15
View File
@@ -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 LoadError
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
+15 -2
View File
@@ -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