CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/post/meterpreter/extension_mapper.rb
Views: 11784
1
# -*- coding: binary -*-
2
3
module Rex
4
module Post
5
module Meterpreter
6
7
class ExtensionMapper
8
9
@@klasses = {}
10
11
# Get the names of all of the extensions.
12
#
13
# @return [Array<String>] An array of all of the extension names.
14
def self.get_extension_names
15
base = ::File.join(File.dirname(__dir__), 'meterpreter/extensions')
16
::Dir.entries(base).select do |e|
17
::File.directory?(::File.join(base, e)) && !['.', '..'].include?(e)
18
end
19
end
20
21
# Get the numeric ID for the specified extension name.
22
#
23
# @param [String] name The name of the extension to retrieve the ID for. This
24
# parameter is case insensitive.
25
# @return [Integer, nil] The extension ID or nil if the name does not exist.
26
def self.get_extension_id(name)
27
begin
28
k = self.get_extension_klass(name)
29
rescue RuntimeError
30
return nil
31
end
32
33
k.extension_id
34
end
35
36
# Get the string extension name for the specified extension ID.
37
#
38
# @param [Integer] id The ID of the extension to retrieve the name for.
39
# @return [String, nil] The extension name or nil if the ID does not exist.
40
def self.get_extension_name(id)
41
id = id - (id % COMMAND_ID_RANGE)
42
43
self.get_extension_names.find do |name|
44
begin
45
klass = self.get_extension_klass(name)
46
rescue RuntimeError
47
next
48
end
49
50
klass.extension_id == id
51
end
52
end
53
54
# Get the module for the specified extension name.
55
#
56
# @param [String] name The name of the extension to retrieve the module for.
57
# This parameter is case insensitive.
58
# @raise [RuntimeError] A RuntimeError is raised if the specified module can
59
# not be loaded.
60
# @return [Module] The extension module.
61
def self.get_extension_module(name)
62
name.downcase!
63
64
begin
65
require("rex/post/meterpreter/extensions/#{name}/#{name}")
66
rescue LoadError
67
# the extension doesn't exist on disk
68
raise RuntimeError, "Unable to load extension '#{name}' - module does not exist."
69
end
70
s = Rex::Post::Meterpreter::Extensions.constants.find { |c| name == c.to_s.downcase }
71
Rex::Post::Meterpreter::Extensions.const_get(s)
72
end
73
74
# Get the class for the specified extension name.
75
#
76
# @param [String] name The name of the extension to retrieve the class for.
77
# This parameter is case insensitive.
78
# @raise [RuntimeError] A RuntimeError is raised if the specified module can
79
# not be loaded.
80
# @return [Class] The extension class.
81
def self.get_extension_klass(name)
82
name.downcase!
83
84
unless @@klasses[name]
85
mod = self.get_extension_module(name)
86
@@klasses[name] = mod.const_get(mod.name.split('::').last)
87
end
88
89
@@klasses[name]
90
end
91
92
def self.get_extension_klasses
93
self.get_extension_names.map { |name| self.get_extension_module(name) }
94
end
95
96
def self.dump_extensions
97
self.get_extension_names.each { |n|
98
STDERR.puts("EXTENSION_ID_#{n.upcase} = #{self.get_extension_id(n)}\n")
99
}
100
end
101
102
end
103
104
end
105
end
106
end
107
108