Class: Rex::Post::Meterpreter::Ui::Console

Inherits:
Object
  • Object
show all
Includes:
Ui::Text::DispatcherShell
Defined in:
lib/rex/post/meterpreter/ui/console.rb

Overview

This class provides a shell driven interface to the meterpreter client API.

Defined Under Namespace

Modules: CommandDispatcher, InteractiveChannel

Instance Attribute Summary collapse

Attributes included from Ui::Text::DispatcherShell

#blocked, #busy, #dispatcher_stack, #tab_words

Attributes included from Ui::Text::Shell

#disable_output, #framework, #input, #on_command_proc, #on_print_proc, #output

Instance Method Summary collapse

Methods included from Ui::Text::DispatcherShell

#append_dispatcher, #block_command, #blocked_command?, #current_dispatcher, #destack_dispatcher, #enstack_dispatcher, #help_to_s, #remove_dispatcher, #run_single, #tab_complete, #tab_complete_helper, #tab_complete_stub, #unblock_command, #unknown_command

Methods included from Ui::Text::Shell

#init_tab_complete, #init_ui, #print, #print_error, #print_good, #print_line, #print_status, #reset_ui, #run, #set_log_source, #stop, #stopped?, #tab_complete, #unset_log_source, #update_prompt

Constructor Details

#initialize(client) ⇒ Console

Initialize the meterpreter console.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rex/post/meterpreter/ui/console.rb', line 28

def initialize(client)
	if (Rex::Compat.is_windows())
		super("meterpreter")
	else
		super("%undmeterpreter%clr")
	end

	# The meterpreter client context
	self.client = client

	# Queued commands array
	self.commands = []

	# Point the input/output handles elsewhere
	reset_ui

	enstack_dispatcher(Console::CommandDispatcher::Core)

	# Set up logging to whatever logsink 'core' is using
	if ! $dispatcher['meterpreter']
		$dispatcher['meterpreter'] = $dispatcher['core']
	end
end

Instance Attribute Details

#clientObject

:nodoc:



127
128
129
# File 'lib/rex/post/meterpreter/ui/console.rb', line 127

def client
  @client
end

Instance Method Details

#interact(&block) ⇒ Object

Called when someone wants to interact with the meterpreter client. It’s assumed that init_ui has been called prior.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rex/post/meterpreter/ui/console.rb', line 56

def interact(&block)
	init_tab_complete

	# Run queued commands
	commands.delete_if { |ent|
		run_single(ent)
		true
	}

	# Run the interactive loop
	run { |line|
		# Run the command
		run_single(line)

		# If a block was supplied, call it, otherwise return false
		if (block)
			block.call
		else
			false
		end
	}
end

#interact_with_channel(channel) ⇒ Object

Interacts with the supplied channel.



82
83
84
85
86
87
88
89
# File 'lib/rex/post/meterpreter/ui/console.rb', line 82

def interact_with_channel(channel)
	channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
	channel.on_command_proc = self.on_command_proc if self.on_command_proc
	channel.on_print_proc   = self.on_print_proc if self.on_print_proc

	channel.interact(input, output)
	channel.reset_ui
end

#log_error(msg) ⇒ Object

Logs that an error occurred and persists the callstack.



119
120
121
122
123
124
125
# File 'lib/rex/post/meterpreter/ui/console.rb', line 119

def log_error(msg)
	print_error(msg)

	elog(msg, 'meterpreter')

	dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')
end

#queue_cmd(cmd) ⇒ Object

Queues a command to be run when the interactive loop is entered.



94
95
96
# File 'lib/rex/post/meterpreter/ui/console.rb', line 94

def queue_cmd(cmd)
	self.commands << cmd
end

#run_command(dispatcher, method, arguments) ⇒ Object

Runs the specified command wrapper in something to catch meterpreter exceptions.



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rex/post/meterpreter/ui/console.rb', line 102

def run_command(dispatcher, method, arguments)
	begin
		super
	rescue Timeout::Error
		log_error("Operation timed out.")
	rescue RequestError => info
		log_error(info.to_s)
	rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
		self.client.kill
	rescue  ::Exception => e
		log_error("Error running command #{method}: #{e.class} #{e}")
	end
end