Module: Msf::PostMixin

Includes:
Auxiliary::Report, Module::HasActions, Msf::Post::Common
Included in:
Exploit::Local, Exploit::Local::WindowsKernel, Post
Defined in:
lib/msf/core/post_mixin.rb

Overview

A mixin used for providing Modules with post-exploitation options and helper methods

Instance Attribute Summary collapse

Attributes included from Module::HasActions

#actions, #default_action, #passive_actions

Instance Method Summary collapse

Methods included from Msf::Post::Common

#clear_screen, #cmd_exec, #cmd_exec_get_pid, #command_exists?, #get_env, #get_envs, #has_pid?, #peer, #report_virtualization, #rhost, #rport

Methods included from Module::HasActions

#action, #find_action, #passive_action?

Methods included from Auxiliary::Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Attribute Details

#passiveBoolean

True when this module is passive, false when active

Returns:

  • (Boolean)

See Also:


199
200
201
# File 'lib/msf/core/post_mixin.rb', line 199

def passive
  @passive
end

#session_typesArray

A list of compatible session types

Returns:

  • (Array)

205
206
207
# File 'lib/msf/core/post_mixin.rb', line 205

def session_types
  @session_types
end

Instance Method Details

#check_for_session_readiness(tries = 6) ⇒ Object

Meterpreter sometimes needs a little bit of extra time to actually be responsive for post modules. Default tries and retries for 5 seconds.


56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/msf/core/post_mixin.rb', line 56

def check_for_session_readiness(tries=6)
  session_ready_count = 0
  session_ready = false
  until session.sys or session_ready_count > tries
    session_ready_count += 1
    back_off_period = (session_ready_count**2)/10.0
    select(nil,nil,nil,back_off_period)
  end
  session_ready = !!session.sys
  raise "Could not get a hold of the session." unless session_ready
  return session_ready
end

#cleanupObject

Default cleanup handler does nothing


72
73
# File 'lib/msf/core/post_mixin.rb', line 72

def cleanup
end

#compatible_sessionsArray

Return a (possibly empty) list of all compatible sessions

Returns:

  • (Array)

129
130
131
132
133
134
135
# File 'lib/msf/core/post_mixin.rb', line 129

def compatible_sessions
  sessions = []
  framework.sessions.each do |sid, s|
    sessions << sid if session_compatible?(s)
  end
  sessions
end

#initialize(info = {}) ⇒ Object


15
16
17
18
19
20
21
22
23
24
25
# File 'lib/msf/core/post_mixin.rb', line 15

def initialize(info={})
  super

  register_options( [
    Msf::OptInt.new('SESSION', [ true, "The session to run this module on." ])
  ] , Msf::Post)

  # Default stance is active
  self.passive = info['Passive'] || false
  self.session_types = info['SessionTypes'] || []
end

#passive?Boolean

Whether this module's Exploit::Stance is passive

Returns:

  • (Boolean)

121
122
123
# File 'lib/msf/core/post_mixin.rb', line 121

def passive?
  self.passive
end

#post_commandsObject

Can be overridden by individual modules to add new commands


116
117
118
# File 'lib/msf/core/post_mixin.rb', line 116

def post_commands
  {}
end

#sessionMsf::Session? Also known as: client

Return the associated session or nil if there isn't one

Returns:

  • (Msf::Session)
  • (nil)

    if the id provided in the datastore does not correspond to a session


81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/msf/core/post_mixin.rb', line 81

def session
  # Try the cached one
  return @session if @session and not session_changed?

  if datastore["SESSION"]
    @session = framework.sessions.get(datastore["SESSION"].to_i)
  else
    @session = nil
  end

  @session
end

#session_changed?Boolean (protected)

Returns:

  • (Boolean)

212
213
214
215
216
217
218
219
220
221
# File 'lib/msf/core/post_mixin.rb', line 212

def session_changed?
  @ds_session ||= datastore["SESSION"]

  if (@ds_session != datastore["SESSION"])
    @ds_session = nil
    return true
  else
    return false
  end
end

#session_compatible?(sess_or_sid) ⇒ Boolean

Note:

Because it errs on the side of compatibility, a true return value from this method does not guarantee the module will work with the session. For example, ARCH_CMD modules can work on a variety of platforms and archs and thus return true in this check.

Return false if the given session is not compatible with this module

Checks the session's type against this module's module_info["SessionTypes"] as well as examining platform and arch compatibility.

sess_or_sid can be a Session object, Integer, or String. In the latter cases it should be a key in framework.sessions.

Parameters:

  • sess_or_sid (Msf::Session, Integer, String)

    A session or session ID to compare against this module for compatibility.

Returns:

  • (Boolean)

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/msf/core/post_mixin.rb', line 158

def session_compatible?(sess_or_sid)
  # Normalize the argument to an actual Session
  case sess_or_sid
  when ::Integer, ::String
    s = framework.sessions[sess_or_sid.to_i]
  when ::Msf::Session
    s = sess_or_sid
  end

  # Can't do anything without a session
  return false unless s

  # Can't be compatible if it's the wrong type
  if session_types
    return false unless session_types.include?(s.type)
  end

  # Check to make sure architectures match
  mod_arch = self.module_info['Arch']
  if mod_arch
    mod_arch = [mod_arch] unless mod_arch.kind_of?(Array)
    # Assume ARCH_CMD modules can work on supported SessionTypes
    return true if mod_arch.include?(ARCH_CMD)
    return false unless mod_arch.include?(s.arch)
  end

  # Arch is okay, now check the platform.
  if self.platform && self.platform.kind_of?(Msf::Module::PlatformList)
    return false unless self.platform.supports?(Msf::Module::PlatformList.transform(s.platform))
  end

  # If we got here, we haven't found anything that definitely
  # disqualifies this session.  Assume that means we can use it.
  true
end

#session_display_infoObject


94
95
96
# File 'lib/msf/core/post_mixin.rb', line 94

def session_display_info
  "Session: #{session.sid} (#{session.session_host})"
end

#setupObject

Grabs a session object from the framework or raises OptionValidateError if one doesn't exist. Initializes user input and output on the session.

Raises:


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/msf/core/post_mixin.rb', line 32

def setup
  alert_user

  unless session
    # Always fail if the session doesn't exist.
    raise Msf::OptionValidateError.new(['SESSION'])
  end

  unless session_compatible?(session)
    print_warning('SESSION may not be compatible with this module.')
  end

  # Msf::Exploit#setup for exploits, NoMethodError for post modules
  super rescue NoMethodError

  check_for_session_readiness() if session.type == "meterpreter"

  @session.init_ui(self.user_input, self.user_output)
  @sysinfo = nil
end

#sysinfoHash?

Cached sysinfo, returns nil for non-meterpreter sessions

Returns:

  • (Hash, nil)

104
105
106
107
108
109
110
111
# File 'lib/msf/core/post_mixin.rb', line 104

def sysinfo
  begin
    @sysinfo ||= session.sys.config.sysinfo
  rescue NoMethodError
    @sysinfo = nil
  end
  @sysinfo
end