Method: Msf::Sessions::Meterpreter#bootstrap

Defined in:
lib/msf/base/sessions/meterpreter.rb

#bootstrap(datastore = {}, handler = nil) ⇒ Object


140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/msf/base/sessions/meterpreter.rb', line 140

def bootstrap(datastore = {}, handler = nil)
  session = self

  # Configure unicode encoding before loading stdapi
  session.encode_unicode = datastore['EnableUnicodeEncoding']

  session.init_ui(self.user_input, self.user_output)

  initialize_tlv_logging(datastore['SessionTlvLogging']) unless datastore['SessionTlvLogging'].nil?

  verification_timeout = datastore['AutoVerifySessionTimeout']&.to_i || session.comm_timeout
  begin
    session.tlv_enc_key = session.core.negotiate_tlv_encryption(timeout: verification_timeout)
  rescue Rex::TimeoutError
  end

  if session.tlv_enc_key.nil?
    # Fail-closed if TLV encryption can't be negotiated (close the session as invalid)
    dlog("Session #{session.sid} failed to negotiate TLV encryption")
    print_error("Meterpreter session #{session.sid} is not valid and will be closed")
    # Terminate the session without cleanup if it did not validate
    session.skip_cleanup = true
    session.kill
    return nil
  end

  # always make sure that the new session has a new guid if it's not already known
  guid = session.session_guid
  if guid == "\x00" * 16
    guid = [SecureRandom.uuid.gsub(/-/, '')].pack('H*')
    session.core.set_session_guid(guid)
    session.session_guid = guid
    # TODO: New stageless session, do some account in the DB so we can track it later.
  else
    # TODO: This session was either staged or previously known, and so we should do some accounting here!
  end

  session.commands.concat(session.core.get_loaded_extension_commands('core'))
  if session.tlv_enc_key[:weak_key?]
    print_warning("Meterpreter session #{session.sid} is using a weak encryption key.")
    print_warning('Meterpreter start up operations have been aborted. Use the session at your own risk.')
    return nil
  end
  # Unhook the process prior to loading stdapi to reduce logging/inspection by any AV/PSP
  if datastore['AutoUnhookProcess'] == true
    console.run_single('load unhook')
    console.run_single('unhook_pe')
  end

  unless datastore['AutoLoadStdapi'] == false

    session.load_stdapi

    unless datastore['AutoSystemInfo'] == false
      session.load_session_info
    end

    # only load priv on native windows
    # TODO: abstract this too, to remove windows stuff
    if session.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(session.arch)
      session.load_priv rescue nil
    end
  end

  # TODO: abstract this a little, perhaps a "post load" function that removes
  # platform-specific stuff?
  if session.platform == 'android'
    session.load_android
  end

  ['InitialAutoRunScript', 'AutoRunScript'].each do |key|
    unless datastore[key].nil? || datastore[key].empty?
      args = Shellwords.shellwords(datastore[key])
      print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
      session.execute_script(args.shift, *args)
    end
  end
end