Mirror of metasploit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

module.rb 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. # -*- coding: binary -*-
  2. require 'msf/core'
  3. module Msf
  4. autoload :OptionContainer, 'msf/core/option_container'
  5. ###
  6. #
  7. # The module base class is responsible for providing the common interface
  8. # that is used to interact with modules at the most basic levels, such as
  9. # by inspecting a given module's attributes (name, description, version,
  10. # authors, etc) and by managing the module's data store.
  11. #
  12. ###
  13. class Module
  14. autoload :Arch, 'msf/core/module/arch'
  15. autoload :Author, 'msf/core/module/author'
  16. autoload :AuxiliaryAction, 'msf/core/module/auxiliary_action'
  17. autoload :Compatibility, 'msf/core/module/compatibility'
  18. autoload :DataStore, 'msf/core/module/data_store'
  19. autoload :Deprecated, 'msf/core/module/deprecated'
  20. autoload :Failure, 'msf/core/module/failure'
  21. autoload :FullName, 'msf/core/module/full_name'
  22. autoload :HasActions, 'msf/core/module/has_actions'
  23. autoload :ModuleInfo, 'msf/core/module/module_info'
  24. autoload :ModuleStore, 'msf/core/module/module_store'
  25. autoload :Network, 'msf/core/module/network'
  26. autoload :Options, 'msf/core/module/options'
  27. autoload :Platform, 'msf/core/module/platform'
  28. autoload :PlatformList, 'msf/core/module/platform_list'
  29. autoload :Privileged, 'msf/core/module/privileged'
  30. autoload :Ranking, 'msf/core/module/ranking'
  31. autoload :Reference, 'msf/core/module/reference'
  32. autoload :Search, 'msf/core/module/search'
  33. autoload :SiteReference, 'msf/core/module/reference'
  34. autoload :Target, 'msf/core/module/target'
  35. autoload :Type, 'msf/core/module/type'
  36. autoload :UI, 'msf/core/module/ui'
  37. autoload :UUID, 'msf/core/module/uuid'
  38. include Msf::Module::Arch
  39. include Msf::Module::Author
  40. include Msf::Module::Compatibility
  41. include Msf::Module::DataStore
  42. include Msf::Module::FullName
  43. include Msf::Module::ModuleInfo
  44. include Msf::Module::ModuleStore
  45. include Msf::Module::Network
  46. include Msf::Module::Options
  47. include Msf::Module::Privileged
  48. include Msf::Module::Ranking
  49. include Msf::Module::Search
  50. include Msf::Module::Type
  51. include Msf::Module::UI
  52. include Msf::Module::UUID
  53. # The key where a comma-separated list of Ruby module names will live in the
  54. # datastore, consumed by #replicant to allow clean override of MSF module methods.
  55. REPLICANT_EXTENSION_DS_KEY = 'ReplicantExtensions'
  56. # Make include public so we can runtime extend
  57. public_class_method :include
  58. class << self
  59. include Framework::Offspring
  60. #
  61. # This attribute holds the non-duplicated copy of the module
  62. # implementation. This attribute is used for reloading purposes so that
  63. # it can be re-duplicated.
  64. #
  65. attr_accessor :orig_cls
  66. #
  67. # The path from which the module was loaded.
  68. #
  69. attr_accessor :file_path
  70. end
  71. #
  72. # Returns the class reference to the framework
  73. #
  74. def framework
  75. self.class.framework
  76. end
  77. #
  78. # This method allows modules to tell the framework if they are usable
  79. # on the system that they are being loaded on in a generic fashion.
  80. # By default, all modules are indicated as being usable. An example of
  81. # where this is useful is if the module depends on something external to
  82. # ruby, such as a binary.
  83. #
  84. def self.is_usable
  85. true
  86. end
  87. #
  88. # Creates an instance of an abstract module using the supplied information
  89. # hash.
  90. #
  91. def initialize(info = {})
  92. @module_info_copy = info.dup
  93. self.module_info = info
  94. generate_uuid
  95. set_defaults
  96. # Initialize module compatibility hashes
  97. init_compat
  98. # Fixup module fields as needed
  99. info_fixups
  100. # Transform some of the fields to arrays as necessary
  101. self.author = Msf::Author.transform(module_info['Author'])
  102. self.arch = Rex::Transformer.transform(module_info['Arch'], Array, [ String ], 'Arch')
  103. self.platform = PlatformList.transform(module_info['Platform'])
  104. self.references = Rex::Transformer.transform(module_info['References'], Array, [ SiteReference, Reference ], 'Ref')
  105. # Create and initialize the option container for this module
  106. self.options = Msf::OptionContainer.new
  107. self.options.add_options(info['Options'], self.class)
  108. self.options.add_advanced_options(info['AdvancedOptions'], self.class)
  109. self.options.add_evasion_options(info['EvasionOptions'], self.class)
  110. # Create and initialize the data store for this module
  111. self.datastore = ModuleDataStore.new(self)
  112. # Import default options into the datastore
  113. import_defaults
  114. self.privileged = module_info['Privileged'] || false
  115. self.license = module_info['License'] || MSF_LICENSE
  116. # Allow all modules to track their current workspace
  117. register_advanced_options(
  118. [
  119. OptString.new('WORKSPACE', [ false, "Specify the workspace for this module" ]),
  120. OptBool.new('VERBOSE', [ false, 'Enable detailed status messages', false ])
  121. ], Msf::Module)
  122. end
  123. #
  124. # Creates a fresh copy of an instantiated module
  125. #
  126. def replicant
  127. obj = self.class.new
  128. self.instance_variables.each { |k|
  129. v = instance_variable_get(k)
  130. v = v.dup rescue v
  131. obj.instance_variable_set(k, v)
  132. }
  133. obj.datastore = self.datastore.copy
  134. obj.user_input = self.user_input
  135. obj.user_output = self.user_output
  136. obj.module_store = self.module_store.clone
  137. obj.perform_extensions
  138. obj
  139. end
  140. # Extends self with the constant list in the datastore
  141. # @return [void]
  142. def perform_extensions
  143. if datastore[REPLICANT_EXTENSION_DS_KEY].present?
  144. if datastore[REPLICANT_EXTENSION_DS_KEY].respond_to?(:each)
  145. datastore[REPLICANT_EXTENSION_DS_KEY].each do |const|
  146. self.extend(const)
  147. end
  148. else
  149. fail "Invalid settings in datastore at key #{REPLICANT_EXTENSION_DS_KEY}"
  150. end
  151. end
  152. end
  153. # @param[Constant] One or more Ruby constants
  154. # @return [void]
  155. def register_extensions(*rb_modules)
  156. datastore[REPLICANT_EXTENSION_DS_KEY] = [] unless datastore[REPLICANT_EXTENSION_DS_KEY].present?
  157. rb_modules.each do |rb_mod|
  158. datastore[REPLICANT_EXTENSION_DS_KEY] << rb_mod unless datastore[REPLICANT_EXTENSION_DS_KEY].include? rb_mod
  159. end
  160. end
  161. #
  162. # Returns the unduplicated class associated with this module.
  163. #
  164. def orig_cls
  165. self.class.orig_cls
  166. end
  167. #
  168. # The path to the file in which the module can be loaded from.
  169. #
  170. def file_path
  171. self.class.file_path
  172. end
  173. #
  174. # Checks to see if the target is vulnerable, returning unsupported if it's
  175. # not supported.
  176. #
  177. # This method is designed to be overriden by exploit modules.
  178. #
  179. def check
  180. Msf::Exploit::CheckCode::Unsupported
  181. end
  182. #
  183. # Returns the current workspace
  184. #
  185. def workspace
  186. self.datastore['WORKSPACE'] ||
  187. (framework.db and framework.db.active and framework.db.workspace and framework.db.workspace.name)
  188. end
  189. #
  190. # Returns the username that instantiated this module, this tries a handful of methods
  191. # to determine what actual user ran this module.
  192. #
  193. def owner
  194. # Generic method to configure a module owner
  195. username = self.datastore['MODULE_OWNER'].to_s.strip
  196. # Specific method used by the commercial products
  197. if username.empty?
  198. username = self.datastore['PROUSER'].to_s.strip
  199. end
  200. # Fallback when neither prior method is available, common for msfconsole
  201. if username.empty?
  202. username = (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip
  203. end
  204. username
  205. end
  206. #
  207. # Scans the parent module reference to populate additional information. This
  208. # is used to inherit common settings (owner, workspace, parent uuid, etc).
  209. #
  210. def register_parent(ref)
  211. self.datastore['WORKSPACE'] = (ref.datastore['WORKSPACE'] ? ref.datastore['WORKSPACE'].dup : nil)
  212. self.datastore['PROUSER'] = (ref.datastore['PROUSER'] ? ref.datastore['PROUSER'].dup : nil)
  213. self.datastore['MODULE_OWNER'] = ref.owner.dup
  214. self.datastore['ParentUUID'] = ref.uuid.dup
  215. end
  216. #
  217. # Return a comma separated list of supported platforms, if any.
  218. #
  219. def platform_to_s
  220. platform.all? ? "All" : platform.names.join(", ")
  221. end
  222. #
  223. # Checks to see if this module is compatible with the supplied platform
  224. #
  225. def platform?(what)
  226. (platform & what).empty? == false
  227. end
  228. #
  229. # Returns true if this module is being debugged.
  230. #
  231. def debugging?
  232. datastore['DEBUG']
  233. end
  234. #
  235. # Raises a RuntimeError failure message. This is meant to be used for all non-exploits,
  236. # and allows specific classes to override.
  237. #
  238. # @param reason [String] A reason about the failure.
  239. # @param msg [String] (Optional) A message about the failure.
  240. # @raise [RuntimeError]
  241. # @return [void]
  242. # @note If you are writing an exploit, you don't use this API. Instead, please refer to the
  243. # API documentation from lib/msf/core/exploit.rb.
  244. # @see Msf::Exploit#fail_with
  245. # @example
  246. # fail_with('No Access', 'Unable to login')
  247. #
  248. def fail_with(reason, msg=nil)
  249. raise RuntimeError, "#{reason.to_s}: #{msg}"
  250. end
  251. ##
  252. #
  253. # Just some handy quick checks
  254. #
  255. ##
  256. #
  257. # Returns false since this is the real module
  258. #
  259. def self.cached?
  260. false
  261. end
  262. #
  263. # The array of zero or more platforms.
  264. #
  265. attr_reader :platform
  266. #
  267. # The reference count for the module.
  268. #
  269. attr_reader :references
  270. #
  271. # The license under which this module is provided.
  272. #
  273. attr_reader :license
  274. #
  275. # The job identifier that this module is running as, if any.
  276. #
  277. attr_accessor :job_id
  278. #
  279. # The last exception to occur using this module
  280. #
  281. attr_accessor :error
  282. # An opaque bag of data to attach to a module. This is useful for attaching
  283. # some piece of identifying info on to a module before calling
  284. # {Msf::Simple::Exploit#exploit_simple} or
  285. # {Msf::Simple::Auxiliary#run_simple} for correlating where modules came
  286. # from.
  287. #
  288. attr_accessor :user_data
  289. protected
  290. #
  291. # Sets the modules unsupplied info fields to their default values.
  292. #
  293. def set_defaults
  294. self.module_info = {
  295. 'Name' => 'No module name',
  296. 'Description' => 'No module description',
  297. 'Version' => '0',
  298. 'Author' => nil,
  299. 'Arch' => nil, # No architectures by default.
  300. 'Platform' => [], # No platforms by default.
  301. 'Ref' => nil,
  302. 'Privileged' => false,
  303. 'License' => MSF_LICENSE,
  304. }.update(self.module_info)
  305. self.module_store = {}
  306. end
  307. #
  308. # Checks to see if a derived instance of a given module implements a method
  309. # beyond the one that is provided by a base class. This is a pretty lame
  310. # way of doing it, but I couldn't find a better one, so meh.
  311. #
  312. def derived_implementor?(parent, method_name)
  313. (self.method(method_name).to_s.match(/#{parent}[^:]/)) ? false : true
  314. end
  315. attr_writer :platform, :references # :nodoc:
  316. attr_writer :privileged # :nodoc:
  317. attr_writer :license # :nodoc:
  318. end
  319. end