Files
metasploit-gs/lib/msf/core/session/interactive.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

197 lines
4.3 KiB
Ruby
Raw Normal View History

# -*- coding: binary -*-
2005-09-24 18:02:24 +00:00
module Msf
module Session
###
#
# This class implements the stubs that are needed to provide an interactive
# session.
#
###
module Interactive
2005-07-17 07:06:05 +00:00
#
# Interactive sessions by default may interact with the local user input
# and output.
#
include Rex::Ui::Interactive
2013-08-30 16:28:33 -05:00
2005-07-18 04:07:56 +00:00
#
2005-11-15 15:11:43 +00:00
# Initializes the session.
2005-07-18 04:07:56 +00:00
#
2010-04-03 05:21:15 +00:00
def initialize(rstream, opts={})
# A nil is passed in the case of non-stream interactive sessions (Meterpreter)
if rstream
self.rstream = rstream
2022-09-19 12:12:00 -04:00
begin
@peer_info = rstream.peerinfo
rescue ::Exception
end
end
super()
2005-07-18 04:07:56 +00:00
end
2013-08-30 16:28:33 -05:00
#
# Returns that, yes, indeed, this session supports going interactive with
# the user.
#
def interactive?
true
end
2013-08-30 16:28:33 -05:00
#
2005-11-15 15:11:43 +00:00
# Returns the local information.
2005-07-18 04:07:56 +00:00
#
def tunnel_local
return @local_info if @local_info
begin
@local_info = rstream.localinfo
2022-09-19 12:12:00 -04:00
rescue ::Exception => e
elog('Interactive#tunnel_local error', error: e)
@local_info = '127.0.0.1'
end
2005-07-18 04:07:56 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-18 04:07:56 +00:00
#
2005-11-15 15:11:43 +00:00
# Returns the remote peer information.
2005-07-18 04:07:56 +00:00
#
def tunnel_peer
return @peer_info if @peer_info
2005-11-03 00:18:12 +00:00
begin
2008-01-20 22:40:11 +00:00
@peer_info = rstream.peerinfo
2022-09-19 12:12:00 -04:00
rescue ::Exception => e
elog('Interactive#tunnel_peer error', error: e)
@peer_info = '127.0.0.1'
2005-11-03 00:18:12 +00:00
end
2005-07-18 04:07:56 +00:00
end
2013-08-30 16:28:33 -05:00
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
#
# Run an arbitrary command as if it came from user input.
#
def run_cmd(cmd)
end
2013-08-30 16:28:33 -05:00
#
# Terminate the session
#
def kill
self.reset_ui
self.cleanup
super()
end
2013-08-30 16:28:33 -05:00
2005-07-18 04:07:56 +00:00
#
# Closes rstream.
#
def cleanup
2005-12-12 07:07:19 +00:00
begin
self.interacting = false if self.interactive?
2005-12-12 07:07:19 +00:00
rstream.close if (rstream)
rescue ::Exception
2005-12-12 07:07:19 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-18 04:07:56 +00:00
rstream = nil
super
2005-07-18 04:07:56 +00:00
end
2013-08-30 16:28:33 -05:00
2005-07-18 04:07:56 +00:00
#
# The remote stream handle. Must inherit from Rex::IO::Stream.
#
attr_accessor :rstream
2013-08-30 16:28:33 -05:00
protected
2005-07-18 04:07:56 +00:00
#
2005-11-15 15:11:43 +00:00
# Stub method that is meant to handler interaction.
2005-07-18 04:07:56 +00:00
#
def _interact
framework.events.on_session_interact(self)
2005-07-18 04:07:56 +00:00
end
2013-08-30 16:28:33 -05:00
#
2005-11-15 15:11:43 +00:00
# Check to see if the user wants to abort.
#
def _interrupt
begin
2018-08-12 05:40:40 +08:00
intent = user_want_abort?
2020-03-24 18:08:34 +05:30
# 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
2024-01-06 15:54:49 -05:00
# 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
2018-08-12 05:40:40 +08:00
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")
2021-09-08 08:19:43 +10:00
abort_foreground
end
return
end
rescue Interrupt
# The user hit ctrl-c while we were handling a ctrl-c. Ignore
end
2020-06-29 12:35:02 +08:00
true
end
2013-08-30 16:28:33 -05:00
def abort_foreground_supported
true
end
2021-09-08 08:19:43 +10:00
def abort_foreground
self.rstream.write("\u0003")
end
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
#
2005-11-15 15:11:43 +00:00
# Check to see if we should suspend.
#
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
2013-08-30 16:28:33 -05:00
#
# If the session reaches EOF, deregister it.
#
def _interact_complete
framework.events.on_session_interact_completed()
framework.sessions.deregister(self, "User exit")
end
2013-08-30 16:28:33 -05:00
#
2005-11-15 15:11:43 +00:00
# Checks to see if the user wants to abort.
#
def user_want_abort?
prompt_yesno("Abort session #{name}?")
end
end
end
end