Module: Msf::Session::Interactive

Includes:
Rex::Ui::Interactive
Included in:
Basic, Msf::Sessions::HWBridge, Msf::Sessions::Meterpreter
Defined in:
lib/msf/core/session/interactive.rb

Overview

This class implements the stubs that are needed to provide an interactive session.

Instance Attribute Summary collapse

Attributes included from Rex::Ui::Interactive

#completed, #interacting, #next_session, #on_command_proc, #on_print_proc, #on_run_command_error_proc, #orig_suspend, #orig_usr1, #orig_winch

Attributes included from Rex::Ui::Subscriber::Input

#user_input

Attributes included from Rex::Ui::Subscriber::Output

#user_output

Instance Method Summary collapse

Methods included from Rex::Ui::Interactive

#_local_fd, #_remote_fd, #_stream_read_local_write_remote, #_stream_read_remote_write_local, #_winch, #detach, #handle_suspend, #handle_usr1, #handle_winch, #interact, #interact_stream, #prompt, #prompt_yesno, #restore_suspend, #restore_usr1, #restore_winch

Methods included from Rex::Ui::Subscriber

#copy_ui, #init_ui, #reset_ui

Methods included from Rex::Ui::Subscriber::Input

#gets

Methods included from Rex::Ui::Subscriber::Output

#flush, #print, #print_blank_line, #print_error, #print_good, #print_line, #print_status, #print_warning

Instance Attribute Details

#rstreamObject

The remote stream handle. Must inherit from Rex::IO::Stream.



108
109
110
# File 'lib/msf/core/session/interactive.rb', line 108

def rstream
  @rstream
end

Instance Method Details

#_interactObject (protected)

Stub method that is meant to handler interaction.



115
116
117
# File 'lib/msf/core/session/interactive.rb', line 115

def _interact
  framework.events.on_session_interact(self)
end

#_interact_completeObject (protected)

If the session reaches EOF, deregister it.



181
182
183
184
# File 'lib/msf/core/session/interactive.rb', line 181

def _interact_complete
  framework.events.on_session_interact_completed()
  framework.sessions.deregister(self, "User exit")
end

#_interruptObject (protected)

Check to see if the user wants to abort.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/msf/core/session/interactive.rb', line 122

def _interrupt
  begin
    intent = user_want_abort?
    # Judge the user wants to abort the reverse shell session
    # Or just want to abort the process running on the target machine
    # If the latter, just send ASCII Control Character \u0003 (End of Text) to the socket fd
    # The character will be handled by the line discipline program of the pseudo-terminal on target machine
    # It will send the SEGINT signal to the foreground process
    if !intent
      # TODO: Check the shell is interactive or not
      # If the current shell is not interactive, the ASCII Control Character will not work
      if abort_foreground_supported
        print_status("Aborting foreground process in the shell session")
        abort_foreground
      end
      return
    end
  rescue Interrupt
    # The user hit ctrl-c while we were handling a ctrl-c. Ignore
  end
  true
end

#_suspendObject (protected)

Check to see if we should suspend.



163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/msf/core/session/interactive.rb', line 163

def _suspend
  # Ask the user if they would like to background the session
  intent = prompt_yesno("Background session #{name}?")
  if !intent
    # User does not want to background the current session
    # Assuming the target is *nix, we'll forward CTRL-Z to the foreground process on the target
    if !(self.platform=="windows" && self.type =="shell")
      print_status("Backgrounding foreground process in the shell session")
      self.rstream.write("\u001A")
    end
    return
  end
  self.interacting = false
end

#_usr1Object (protected)



153
154
155
156
157
158
# File 'lib/msf/core/session/interactive.rb', line 153

def _usr1
  # A simple signal to exit vim in reverse shell
  # Just for fun
  # Make sure you have already executed `shell` meta-shell command to pop up an interactive shell
  self.rstream.write("\x1B\x1B\x1B:q!\r")
end

#abort_foregroundObject (protected)



149
150
151
# File 'lib/msf/core/session/interactive.rb', line 149

def abort_foreground
  self.rstream.write("\u0003")
end

#abort_foreground_supportedObject (protected)



145
146
147
# File 'lib/msf/core/session/interactive.rb', line 145

def abort_foreground_supported
  true
end

#cleanupObject

Closes rstream.



94
95
96
97
98
99
100
101
102
103
# File 'lib/msf/core/session/interactive.rb', line 94

def cleanup
  begin
    self.interacting = false if self.interactive?
    rstream.close if (rstream)
  rescue ::Exception
  end

  rstream = nil
  super
end

#comm_channelObject



69
70
71
72
73
74
# File 'lib/msf/core/session/interactive.rb', line 69

def comm_channel
  return @comm_info if @comm_info
  if rstream.respond_to?(:channel) && rstream.channel.respond_to?(:client)
    @comm_info = "via session #{rstream.channel.client.sid}" if rstream.channel.client.respond_to?(:sid)
  end
end

#initialize(rstream, opts = {}) ⇒ Object

Initializes the session.



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/msf/core/session/interactive.rb', line 23

def initialize(rstream, opts={})
  # A nil is passed in the case of non-stream interactive sessions (Meterpreter)
  if rstream
    self.rstream = rstream
    begin
      @peer_info = rstream.peerinfo
    rescue ::Exception
    end
  end
  super()
end

#interactive?Boolean

Returns that, yes, indeed, this session supports going interactive with the user.

Returns:

  • (Boolean)


39
40
41
# File 'lib/msf/core/session/interactive.rb', line 39

def interactive?
  true
end

#killObject

Terminate the session



85
86
87
88
89
# File 'lib/msf/core/session/interactive.rb', line 85

def kill
  self.reset_ui
  self.cleanup
  super()
end

#run_cmd(cmd) ⇒ Object

Run an arbitrary command as if it came from user input.



79
80
# File 'lib/msf/core/session/interactive.rb', line 79

def run_cmd(cmd)
end

#tunnel_localObject

Returns the local information.



46
47
48
49
50
51
52
53
54
# File 'lib/msf/core/session/interactive.rb', line 46

def tunnel_local
  return @local_info if @local_info
  begin
    @local_info = rstream.localinfo
  rescue ::Exception => e
    elog('Interactive#tunnel_local error', error: e)
    @local_info = '127.0.0.1'
  end
end

#tunnel_peerObject

Returns the remote peer information.



59
60
61
62
63
64
65
66
67
# File 'lib/msf/core/session/interactive.rb', line 59

def tunnel_peer
  return @peer_info if @peer_info
  begin
    @peer_info = rstream.peerinfo
  rescue ::Exception => e
    elog('Interactive#tunnel_peer error', error: e)
    @peer_info = '127.0.0.1'
  end
end

#user_want_abort?Boolean (protected)

Checks to see if the user wants to abort.

Returns:

  • (Boolean)


189
190
191
# File 'lib/msf/core/session/interactive.rb', line 189

def user_want_abort?
  prompt_yesno("Abort session #{name}?")
end