Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/post/meterpreter/ui/console.rb
Views: 11789
# -*- coding: binary -*-1require 'rex/post/meterpreter'23module Rex4module Post5module Meterpreter6module Ui78###9#10# This class provides a shell driven interface to the meterpreter client API.11#12###13class Console1415include Rex::Ui::Text::DispatcherShell1617# Dispatchers18require 'rex/post/meterpreter/ui/console/interactive_channel'19require 'rex/post/meterpreter/ui/console/command_dispatcher'20require 'rex/post/meterpreter/ui/console/command_dispatcher/core'2122#23# Initialize the meterpreter console.24#25def initialize(client)26if (Rex::Compat.is_windows())27super("meterpreter")28else29super("%undmeterpreter%clr", '>', Msf::Config.meterpreter_history, nil, :meterpreter)30end3132# The meterpreter client context33self.client = client3435# Queued commands array36self.commands = []3738# Point the input/output handles elsewhere39reset_ui4041enstack_dispatcher(Console::CommandDispatcher::Core)4243# Set up logging to whatever logsink 'core' is using44if ! $dispatcher['meterpreter']45$dispatcher['meterpreter'] = $dispatcher['core']46end47end4849#50# Called when someone wants to interact with the meterpreter client. It's51# assumed that init_ui has been called prior.52#53def interact(&block)54# Run queued commands55commands.delete_if { |ent|56run_single(ent)57true58}5960# Run the interactive loop61run { |line|62# Run the command63run_single(line)6465# If a block was supplied, call it, otherwise return false66if (block)67block.call68else69false70end71}72end7374#75# Interacts with the supplied channel.76#77def interact_with_channel(channel, raw: false)78channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)79channel.on_command_proc = self.on_command_proc if self.on_command_proc80channel.on_print_proc = self.on_print_proc if self.on_print_proc81channel.on_log_proc = method(:log_output) if self.respond_to?(:log_output, true)82channel.raw = raw8384channel.interact(input, output)85channel.reset_ui86end8788#89# Queues a command to be run when the interactive loop is entered.90#91def queue_cmd(cmd)92self.commands << cmd93end9495#96# Runs the specified command wrapper in something to catch meterpreter97# exceptions.98#99def run_command(dispatcher, method, arguments)100begin101super102rescue Exception => e103is_error_handled = self.client.on_run_command_error_proc && self.client.on_run_command_error_proc.call(e) == :handled104return if is_error_handled105case e106when Rex::TimeoutError, Rex::InvalidDestination107log_error(e.message)108when Timeout::Error109log_error('Operation timed out.')110when RequestError111log_error(e.to_s)112when ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError113self.client.kill114when ::Exception115log_error("Error running command #{method}: #{e.class} #{e}")116elog(e)117end118end119end120121#122# Logs that an error occurred and persists the callstack.123#124def log_error(msg)125print_error(msg)126127elog(msg, 'meterpreter')128129dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')130end131132attr_reader :client # :nodoc:133134protected135136attr_writer :client # :nodoc:137attr_accessor :commands # :nodoc:138139end140141end142end143end144end145146147148