2005-07-18 04:07:56 +00:00
|
|
|
require 'rex/ui'
|
|
|
|
require 'rex/post/meterpreter'
|
2006-08-21 21:35:03 +00:00
|
|
|
require 'rex/logging'
|
2005-07-18 04:07:56 +00:00
|
|
|
|
|
|
|
module Rex
|
|
|
|
module Post
|
2005-07-18 05:13:21 +00:00
|
|
|
module Meterpreter
|
|
|
|
module Ui
|
2005-07-18 04:07:56 +00:00
|
|
|
|
|
|
|
###
|
|
|
|
#
|
|
|
|
# This class provides a shell driven interface to the meterpreter client API.
|
|
|
|
#
|
|
|
|
###
|
2005-07-18 05:13:21 +00:00
|
|
|
class Console
|
2005-07-18 04:07:56 +00:00
|
|
|
|
2005-07-18 05:13:21 +00:00
|
|
|
include Rex::Ui::Text::DispatcherShell
|
2005-07-18 04:07:56 +00:00
|
|
|
|
2005-07-18 05:13:21 +00:00
|
|
|
# Dispatchers
|
2005-07-19 04:21:15 +00:00
|
|
|
require 'rex/post/meterpreter/ui/console/interactive_channel'
|
2005-07-18 05:59:27 +00:00
|
|
|
require 'rex/post/meterpreter/ui/console/command_dispatcher'
|
2005-07-18 07:46:54 +00:00
|
|
|
require 'rex/post/meterpreter/ui/console/command_dispatcher/core'
|
2005-07-18 04:07:56 +00:00
|
|
|
|
|
|
|
#
|
2005-11-15 05:22:13 +00:00
|
|
|
# Initialize the meterpreter console.
|
2005-07-18 04:07:56 +00:00
|
|
|
#
|
2005-07-18 05:13:21 +00:00
|
|
|
def initialize(client)
|
2006-07-27 22:28:19 +00:00
|
|
|
if (Rex::Compat.is_windows())
|
2006-06-08 20:53:15 +00:00
|
|
|
super("meterpreter")
|
|
|
|
else
|
2009-11-10 07:12:56 +00:00
|
|
|
super("%undmeterpreter%clr")
|
2006-06-08 20:53:15 +00:00
|
|
|
end
|
2005-07-18 04:07:56 +00:00
|
|
|
|
2005-07-18 05:13:21 +00:00
|
|
|
# The meterpreter client context
|
|
|
|
self.client = client
|
|
|
|
|
2005-11-19 15:09:41 +00:00
|
|
|
# Queued commands array
|
|
|
|
self.commands = []
|
|
|
|
|
2005-07-18 05:13:21 +00:00
|
|
|
# Point the input/output handles elsewhere
|
|
|
|
reset_ui
|
|
|
|
|
2005-07-18 07:46:54 +00:00
|
|
|
enstack_dispatcher(Console::CommandDispatcher::Core)
|
2009-11-26 02:46:04 +00:00
|
|
|
|
|
|
|
# Set up logging to whatever logsink 'core' is using
|
2009-11-28 16:34:46 +00:00
|
|
|
if ! $dispatcher['meterpreter']
|
|
|
|
$dispatcher['meterpreter'] = $dispatcher['core']
|
|
|
|
end
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Called when someone wants to interact with the meterpreter client. It's
|
|
|
|
# assumed that init_ui has been called prior.
|
|
|
|
#
|
|
|
|
def interact(&block)
|
2005-11-19 15:09:41 +00:00
|
|
|
# Run queued commands
|
|
|
|
commands.delete_if { |ent|
|
|
|
|
run_single(ent)
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
# Run the interactive loop
|
2005-07-18 05:13:21 +00:00
|
|
|
run { |line|
|
|
|
|
# Run the command
|
|
|
|
run_single(line)
|
2005-07-18 04:07:56 +00:00
|
|
|
|
|
|
|
# If a block was supplied, call it, otherwise return false
|
|
|
|
if (block)
|
|
|
|
block.call
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2005-07-19 04:21:15 +00:00
|
|
|
#
|
2005-11-15 05:22:13 +00:00
|
|
|
# Interacts with the supplied channel.
|
2005-07-19 04:21:15 +00:00
|
|
|
#
|
|
|
|
def interact_with_channel(channel)
|
|
|
|
channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
|
|
|
|
|
2007-02-20 05:41:51 +00:00
|
|
|
channel.interact(input, output)
|
2005-07-19 04:21:15 +00:00
|
|
|
channel.reset_ui
|
|
|
|
end
|
|
|
|
|
2005-11-19 15:09:41 +00:00
|
|
|
#
|
|
|
|
# Queues a command to be run when the interactive loop is entered.
|
|
|
|
#
|
|
|
|
def queue_cmd(cmd)
|
|
|
|
self.commands << cmd
|
|
|
|
end
|
|
|
|
|
2005-07-19 04:21:15 +00:00
|
|
|
#
|
|
|
|
# Runs the specified command wrapper in something to catch meterpreter
|
|
|
|
# exceptions.
|
|
|
|
#
|
|
|
|
def run_command(dispatcher, method, arguments)
|
|
|
|
begin
|
|
|
|
super
|
2009-11-02 18:20:02 +00:00
|
|
|
rescue Timeout::Error
|
2005-07-23 17:52:29 +00:00
|
|
|
log_error("Operation timed out.")
|
2005-07-19 04:21:15 +00:00
|
|
|
rescue RequestError => info
|
2005-07-23 17:52:29 +00:00
|
|
|
log_error(info.to_s)
|
2005-07-23 05:13:27 +00:00
|
|
|
rescue
|
2009-11-25 23:24:01 +00:00
|
|
|
log_error("Error running command #{method}: #{$!}")
|
2005-07-19 04:21:15 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
#
|
|
|
|
# Logs that an error occurred and persists the callstack.
|
|
|
|
#
|
2005-07-23 17:52:29 +00:00
|
|
|
def log_error(msg)
|
|
|
|
print_error(msg)
|
|
|
|
|
2009-11-26 02:46:04 +00:00
|
|
|
elog(msg, 'meterpreter')
|
2005-07-23 17:52:29 +00:00
|
|
|
|
2009-11-26 02:46:04 +00:00
|
|
|
dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')
|
2005-07-23 17:52:29 +00:00
|
|
|
end
|
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
attr_reader :client # :nodoc:
|
2005-07-18 05:13:21 +00:00
|
|
|
|
|
|
|
protected
|
2009-11-02 18:20:02 +00:00
|
|
|
|
2005-11-15 05:22:13 +00:00
|
|
|
attr_writer :client # :nodoc:
|
2005-11-19 15:09:41 +00:00
|
|
|
attr_accessor :commands # :nodoc:
|
2005-07-18 05:13:21 +00:00
|
|
|
|
2005-07-18 04:07:56 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
2005-07-18 05:13:21 +00:00
|
|
|
end
|
2008-11-20 05:54:55 +00:00
|
|
|
end
|
2009-11-02 18:20:02 +00:00
|
|
|
|