more meterp action
git-svn-id: file:///home/svn/incoming/trunk@2791 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
7f8db62b9c
commit
4679586c49
|
@ -28,7 +28,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||||
#
|
#
|
||||||
# Create the console instance
|
# Create the console instance
|
||||||
#
|
#
|
||||||
self.console = Rex::Post::Meterpreter::Ui::Console.new
|
self.console = Rex::Post::Meterpreter::Ui::Console.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -55,7 +55,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||||
# Initializes the console's I/O handles
|
# Initializes the console's I/O handles
|
||||||
#
|
#
|
||||||
def init_ui(input, output)
|
def init_ui(input, output)
|
||||||
console.init_ui(user_input, user_output)
|
console.init_ui(input, output)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -74,6 +74,10 @@ class Meterpreter < Rex::Post::Meterpreter::Client
|
||||||
# interacting. This will allow the shell to abort if interaction is
|
# interacting. This will allow the shell to abort if interaction is
|
||||||
# canceled.
|
# canceled.
|
||||||
console.interact { self.interacting }
|
console.interact { self.interacting }
|
||||||
|
|
||||||
|
# If the stop flag has been set, then that means the user exited. Raise
|
||||||
|
# the EOFError so we can drop this bitch like a bad habit.
|
||||||
|
raise EOFError if (console.stopped? == true)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -92,25 +92,11 @@ module Handler
|
||||||
# Handles an established connection supplied in the in and out
|
# Handles an established connection supplied in the in and out
|
||||||
# handles. The handles are passed as parameters in case this
|
# handles. The handles are passed as parameters in case this
|
||||||
# handler is capable of handling multiple simultaneous
|
# handler is capable of handling multiple simultaneous
|
||||||
# connections. The default implementation simply creates a
|
# connections. The default behavior is to attempt to create a session for
|
||||||
# session using the payload's session factory reference and
|
# the payload. This path will not be taken for mutli-staged payloads.
|
||||||
# the supplied stream.
|
|
||||||
#
|
#
|
||||||
def handle_connection(conn)
|
def handle_connection(conn)
|
||||||
# If the payload we merged in with has an associated session factory,
|
create_session(conn)
|
||||||
# allocate a new session.
|
|
||||||
if (self.session)
|
|
||||||
s = self.session.new(conn)
|
|
||||||
|
|
||||||
# Pass along the framework context
|
|
||||||
s.framework = framework
|
|
||||||
|
|
||||||
# If the session is valid, register it with the framework and
|
|
||||||
# notify any waiters we may have.
|
|
||||||
if (s)
|
|
||||||
register_session(s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -138,6 +124,28 @@ module Handler
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
#
|
||||||
|
# Creates a session, if necessary, for the connection that's been handled.
|
||||||
|
# Sessions are only created if the payload that's been mixed in has an
|
||||||
|
# associated session.
|
||||||
|
#
|
||||||
|
def create_session(conn)
|
||||||
|
# If the payload we merged in with has an associated session factory,
|
||||||
|
# allocate a new session.
|
||||||
|
if (self.session)
|
||||||
|
s = self.session.new(conn)
|
||||||
|
|
||||||
|
# Pass along the framework context
|
||||||
|
s.framework = framework
|
||||||
|
|
||||||
|
# If the session is valid, register it with the framework and
|
||||||
|
# notify any waiters we may have.
|
||||||
|
if (s)
|
||||||
|
register_session(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Registers a session with the framework and notifies any waiters of the
|
# Registers a session with the framework and notifies any waiters of the
|
||||||
# new session.
|
# new session.
|
||||||
|
|
|
@ -53,8 +53,18 @@ module Msf::Payload::Stager
|
||||||
print_status("Sending stage (#{p.length} bytes)")
|
print_status("Sending stage (#{p.length} bytes)")
|
||||||
|
|
||||||
conn.put(p)
|
conn.put(p)
|
||||||
|
|
||||||
super
|
# Give the stages a chance to handle the connection
|
||||||
|
handle_connection_stage(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Called by handle_connection to allow the stage to process
|
||||||
|
# whatever it is it needs to process. The default is to simply attempt to
|
||||||
|
# create a session.
|
||||||
|
#
|
||||||
|
def handle_connection_stage(conn)
|
||||||
|
create_session(conn)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Aliases
|
# Aliases
|
||||||
|
|
|
@ -4,29 +4,12 @@ module Console
|
||||||
|
|
||||||
module CommandDispatcher
|
module CommandDispatcher
|
||||||
|
|
||||||
def initialize(in_driver)
|
include Rex::Ui::Text::DispatcherShell::CommandDispatcher
|
||||||
self.driver = in_driver
|
|
||||||
self.tab_complete_items = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def print_error(msg = '')
|
def initialize(driver)
|
||||||
driver.print_error(msg)
|
super
|
||||||
end
|
|
||||||
|
|
||||||
def print_status(msg = '')
|
self.driver = driver
|
||||||
driver.print_status(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
def print_line(msg = '')
|
|
||||||
driver.print_line(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
def print(msg = '')
|
|
||||||
driver.print(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_prompt(prompt)
|
|
||||||
driver.update_prompt(prompt)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def framework
|
def framework
|
||||||
|
@ -48,13 +31,6 @@ module CommandDispatcher
|
||||||
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_1)
|
dlog("Call stack:\n#{$@.join("\n")}", 'core', LEV_1)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# No tab completion items by default
|
|
||||||
#
|
|
||||||
attr_accessor :tab_complete_items
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
attr_accessor :driver
|
attr_accessor :driver
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -271,7 +271,7 @@ class Core
|
||||||
print_status("Starting interaction with #{session.name}...\n") if (quiet == false)
|
print_status("Starting interaction with #{session.name}...\n") if (quiet == false)
|
||||||
|
|
||||||
# Set the session's input and output handles
|
# Set the session's input and output handles
|
||||||
session.init_ui(driver.input.dup, driver.output.dup)
|
session.init_ui(driver.input, driver.output)
|
||||||
|
|
||||||
# Interact
|
# Interact
|
||||||
session.interact()
|
session.interact()
|
||||||
|
|
|
@ -3,7 +3,6 @@ require 'msf/base'
|
||||||
require 'msf/ui'
|
require 'msf/ui'
|
||||||
require 'msf/ui/console/framework_event_manager'
|
require 'msf/ui/console/framework_event_manager'
|
||||||
require 'msf/ui/console/command_dispatcher'
|
require 'msf/ui/console/command_dispatcher'
|
||||||
require 'msf/ui/console/shell'
|
|
||||||
require 'msf/ui/console/table'
|
require 'msf/ui/console/table'
|
||||||
require 'find'
|
require 'find'
|
||||||
|
|
||||||
|
@ -32,12 +31,14 @@ class Driver < Msf::Ui::Driver
|
||||||
#
|
#
|
||||||
# The console driver is a command shell.
|
# The console driver is a command shell.
|
||||||
#
|
#
|
||||||
include Msf::Ui::Console::Shell
|
include Rex::Ui::Text::DispatcherShell
|
||||||
|
|
||||||
def initialize(prompt = "%umsf", prompt_char = ">%c")
|
def initialize(prompt = "%umsf", prompt_char = ">%c")
|
||||||
|
# Call the parent
|
||||||
|
super
|
||||||
|
|
||||||
# Initialize attributes
|
# Initialize attributes
|
||||||
self.framework = Msf::Simple::Framework.create
|
self.framework = Msf::Simple::Framework.create
|
||||||
self.dispatcher_stack = []
|
|
||||||
|
|
||||||
# Initialize config
|
# Initialize config
|
||||||
Msf::Config.init
|
Msf::Config.init
|
||||||
|
@ -46,9 +47,6 @@ class Driver < Msf::Ui::Driver
|
||||||
# stack
|
# stack
|
||||||
enstack_dispatcher(CommandDispatcher::Core)
|
enstack_dispatcher(CommandDispatcher::Core)
|
||||||
|
|
||||||
# Initialize the super
|
|
||||||
super
|
|
||||||
|
|
||||||
# Register event handlers
|
# Register event handlers
|
||||||
register_event_handlers
|
register_event_handlers
|
||||||
|
|
||||||
|
@ -130,80 +128,12 @@ class Driver < Msf::Ui::Driver
|
||||||
run_single("banner")
|
run_single("banner")
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
attr_reader :framework
|
||||||
# Performs tab completion on shell input if supported
|
|
||||||
#
|
|
||||||
def tab_complete(str)
|
|
||||||
items = []
|
|
||||||
|
|
||||||
# Next, try to match internal command or value completion
|
|
||||||
# Enumerate each entry in the dispatcher stack
|
|
||||||
dispatcher_stack.each { |dispatcher|
|
|
||||||
# If it supports commands, query them all
|
|
||||||
if (dispatcher.respond_to?('commands'))
|
|
||||||
items.concat(dispatcher.commands.to_a.map { |x| x[0] })
|
|
||||||
end
|
|
||||||
|
|
||||||
# If the dispatcher has custom tab completion items, use them
|
|
||||||
items.concat(dispatcher.tab_complete_items || [])
|
|
||||||
}
|
|
||||||
|
|
||||||
items.find_all { |e|
|
|
||||||
e =~ /^#{str}/
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run a single command line
|
|
||||||
def run_single(line)
|
|
||||||
arguments = parse_line(line)
|
|
||||||
method = arguments.shift
|
|
||||||
found = false
|
|
||||||
|
|
||||||
reset_color if (supports_color?)
|
|
||||||
|
|
||||||
if (method)
|
|
||||||
entries = dispatcher_stack.length
|
|
||||||
|
|
||||||
dispatcher_stack.each { |dispatcher|
|
|
||||||
begin
|
|
||||||
if (dispatcher.respond_to?('cmd_' + method))
|
|
||||||
eval("
|
|
||||||
dispatcher.#{'cmd_' + method}(*arguments)
|
|
||||||
found = true")
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
output.print_error("Error while running command #{method}: #{$!}\n#{$@.join("\n")}\n.")
|
|
||||||
end
|
|
||||||
|
|
||||||
# If the dispatcher stack changed as a result of this command,
|
|
||||||
# break out
|
|
||||||
break if (dispatcher_stack.length != entries)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
output.print_error("Unknown command: #{method}.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return found
|
|
||||||
end
|
|
||||||
|
|
||||||
# Push a dispatcher to the front of the stack
|
|
||||||
def enstack_dispatcher(dispatcher)
|
|
||||||
self.dispatcher_stack.unshift(dispatcher.new(self))
|
|
||||||
end
|
|
||||||
|
|
||||||
# Pop a dispatcher from the front of the stacker
|
|
||||||
def destack_dispatcher
|
|
||||||
self.dispatcher_stack.shift
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :dispatcher_stack, :framework
|
|
||||||
attr_accessor :active_module
|
attr_accessor :active_module
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_writer :dispatcher_stack, :framework
|
attr_writer :framework
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
require 'msf/ui'
|
|
||||||
|
|
||||||
module Msf
|
|
||||||
module Ui
|
|
||||||
module Console
|
|
||||||
|
|
||||||
###
|
|
||||||
#
|
|
||||||
# Shell
|
|
||||||
# -----
|
|
||||||
#
|
|
||||||
# The shell class provides a command-prompt style interface in a
|
|
||||||
# generic fashion. This wrapper is just here in case we want to do custom
|
|
||||||
# shell extensions that don't make sense to throw in the rex shell.
|
|
||||||
#
|
|
||||||
###
|
|
||||||
module Shell
|
|
||||||
|
|
||||||
include Rex::Ui::Text::Shell
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end end end
|
|
|
@ -1,3 +1,4 @@
|
||||||
#!/usr/bin/ruby
|
#!/usr/bin/ruby
|
||||||
|
|
||||||
require 'rex/post/meterpreter/client'
|
require 'rex/post/meterpreter/client'
|
||||||
|
require 'rex/post/meterpreter/ui/console'
|
||||||
|
|
|
@ -3,6 +3,8 @@ require 'rex/post/meterpreter'
|
||||||
|
|
||||||
module Rex
|
module Rex
|
||||||
module Post
|
module Post
|
||||||
|
module Meterpreter
|
||||||
|
module Ui
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
|
@ -12,28 +14,26 @@ module Post
|
||||||
# This class provides a shell driven interface to the meterpreter client API.
|
# This class provides a shell driven interface to the meterpreter client API.
|
||||||
#
|
#
|
||||||
###
|
###
|
||||||
class Meterpreter::Console
|
class Console
|
||||||
|
|
||||||
def initialize
|
include Rex::Ui::Text::DispatcherShell
|
||||||
# Initialize the pseudo-shell
|
|
||||||
shell = Rex::Ui::Text::Shell.new("%bmeterpreter%c ")
|
# Dispatchers
|
||||||
|
require 'rex/post/meterpreter/ui/console/core'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Initialize the meterpreter console
|
||||||
|
#
|
||||||
|
def initialize(client)
|
||||||
|
super("%bmeterpreter%c")
|
||||||
|
|
||||||
|
# The meterpreter client context
|
||||||
|
self.client = client
|
||||||
|
|
||||||
# Point the input/output handles elsewhere
|
# Point the input/output handles elsewhere
|
||||||
reset_ui
|
reset_ui
|
||||||
end
|
|
||||||
|
|
||||||
#
|
enstack_dispatcher(Console::Core)
|
||||||
# Initialize's the shells I/O handles
|
|
||||||
#
|
|
||||||
def init_ui(input, output)
|
|
||||||
shell.init_ui(input, output)
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Resets the shell's I/O handles
|
|
||||||
#
|
|
||||||
def reset_ui
|
|
||||||
shell.reset_ui
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -41,9 +41,9 @@ class Meterpreter::Console
|
||||||
# assumed that init_ui has been called prior.
|
# assumed that init_ui has been called prior.
|
||||||
#
|
#
|
||||||
def interact(&block)
|
def interact(&block)
|
||||||
shell.run { |line, args|
|
run { |line|
|
||||||
|
# Run the command
|
||||||
#
|
run_single(line)
|
||||||
|
|
||||||
# If a block was supplied, call it, otherwise return false
|
# If a block was supplied, call it, otherwise return false
|
||||||
if (block)
|
if (block)
|
||||||
|
@ -54,7 +54,15 @@ class Meterpreter::Console
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :client
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
attr_writer :client
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
require 'rex/parser/arguments'
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Post
|
||||||
|
module Meterpreter
|
||||||
|
module Ui
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Core
|
||||||
|
# ----
|
||||||
|
#
|
||||||
|
# Core meterpreter client commands.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
class Console::Core
|
||||||
|
|
||||||
|
include Rex::Ui::Text::DispatcherShell::CommandDispatcher
|
||||||
|
|
||||||
|
@@use_opts = Rex::Parser::Arguments.new(
|
||||||
|
"-m" => [ true, "The name of the module or modules to load (Ex: stdapi)." ],
|
||||||
|
"-h" => [ false, "Help banner." ])
|
||||||
|
|
||||||
|
#
|
||||||
|
# List of supported commands
|
||||||
|
#
|
||||||
|
def commands
|
||||||
|
{
|
||||||
|
"exit" => "Terminate the meterpreter session",
|
||||||
|
"use" => "Load a one or more meterpreter extensions",
|
||||||
|
"quit" => "Terminate the meterpreter session",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Terminates the meterpreter session
|
||||||
|
#
|
||||||
|
def cmd_exit(*args)
|
||||||
|
shell.stop
|
||||||
|
end
|
||||||
|
|
||||||
|
alias cmd_quit cmd_exit
|
||||||
|
|
||||||
|
#
|
||||||
|
# Loads one or more meterpreter extensions
|
||||||
|
#
|
||||||
|
def cmd_use(*args)
|
||||||
|
if (args.length == 0)
|
||||||
|
args.unshift("-h")
|
||||||
|
end
|
||||||
|
|
||||||
|
@@use_opts.parse(args) { |opt, idx, val|
|
||||||
|
case opt
|
||||||
|
when "-m"
|
||||||
|
mod = val
|
||||||
|
when "-h"
|
||||||
|
print(
|
||||||
|
"Usage: use [options]\n\n" +
|
||||||
|
"Loads a meterpreter extension module or modules.\n" +
|
||||||
|
@use_opts.usage)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,6 +10,7 @@ require 'rex/ui/progress_tracker'
|
||||||
# Text-based user interfaces
|
# Text-based user interfaces
|
||||||
require 'rex/ui/text/input'
|
require 'rex/ui/text/input'
|
||||||
require 'rex/ui/text/shell'
|
require 'rex/ui/text/shell'
|
||||||
|
require 'rex/ui/text/dispatcher_shell'
|
||||||
|
|
||||||
require 'rex/ui/text/color'
|
require 'rex/ui/text/color'
|
||||||
require 'rex/ui/text/table'
|
require 'rex/ui/text/table'
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
require 'rex/ui'
|
||||||
|
|
||||||
|
module Rex
|
||||||
|
module Ui
|
||||||
|
module Text
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# DispatcherShell
|
||||||
|
# ---------------
|
||||||
|
#
|
||||||
|
# The dispatcher shell class is designed to provide a generic means
|
||||||
|
# of processing various shell commands that may be located in
|
||||||
|
# different modules or chunks of codes. These chunks are referred
|
||||||
|
# to as command dispatchers. The only requirement for command dispatchers is
|
||||||
|
# that they prefix every method that they wish to be mirrored as a command
|
||||||
|
# with the cmd_ prefix.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
module DispatcherShell
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# CommandDispatcher
|
||||||
|
# -----------------
|
||||||
|
#
|
||||||
|
# Empty template base class for command dispatchers
|
||||||
|
#
|
||||||
|
###
|
||||||
|
module CommandDispatcher
|
||||||
|
|
||||||
|
def initialize(shell)
|
||||||
|
self.shell = shell
|
||||||
|
self.tab_complete_items = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def commands
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_error(msg = '')
|
||||||
|
shell.print_error(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_status(msg = '')
|
||||||
|
shell.print_status(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print_line(msg = '')
|
||||||
|
shell.print_line(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def print(msg = '')
|
||||||
|
shell.print(msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_prompt(prompt)
|
||||||
|
shell.update_prompt(prompt)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# No tab completion items by default
|
||||||
|
#
|
||||||
|
attr_accessor :shell, :tab_complete_items
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# DispatcherShell derives from shell
|
||||||
|
#
|
||||||
|
include Shell
|
||||||
|
|
||||||
|
#
|
||||||
|
# Initialize the dispatcher shell
|
||||||
|
#
|
||||||
|
def initialize(prompt, prompt_char = '>')
|
||||||
|
super
|
||||||
|
|
||||||
|
self.dispatcher_stack = []
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Performs tab completion on shell input if supported
|
||||||
|
#
|
||||||
|
def tab_complete(str)
|
||||||
|
items = []
|
||||||
|
|
||||||
|
# Next, try to match internal command or value completion
|
||||||
|
# Enumerate each entry in the dispatcher stack
|
||||||
|
dispatcher_stack.each { |dispatcher|
|
||||||
|
# If it supports commands, query them all
|
||||||
|
if (dispatcher.respond_to?('commands'))
|
||||||
|
items.concat(dispatcher.commands.to_a.map { |x| x[0] })
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the dispatcher has custom tab completion items, use them
|
||||||
|
items.concat(dispatcher.tab_complete_items || [])
|
||||||
|
}
|
||||||
|
|
||||||
|
items.find_all { |e|
|
||||||
|
e =~ /^#{str}/
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run a single command line
|
||||||
|
def run_single(line)
|
||||||
|
arguments = parse_line(line)
|
||||||
|
method = arguments.shift
|
||||||
|
found = false
|
||||||
|
|
||||||
|
reset_color if (supports_color?)
|
||||||
|
|
||||||
|
if (method)
|
||||||
|
entries = dispatcher_stack.length
|
||||||
|
|
||||||
|
dispatcher_stack.each { |dispatcher|
|
||||||
|
begin
|
||||||
|
if (dispatcher.respond_to?('cmd_' + method))
|
||||||
|
eval("
|
||||||
|
dispatcher.#{'cmd_' + method}(*arguments)
|
||||||
|
found = true")
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
output.print_error("Error while running command #{method}: #{$!}")
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the dispatcher stack changed as a result of this command,
|
||||||
|
# break out
|
||||||
|
break if (dispatcher_stack.length != entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == false)
|
||||||
|
unknown_command(method, line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return found
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# If the command is unknown...
|
||||||
|
#
|
||||||
|
def unknown_command(method, line)
|
||||||
|
output.print_error("Unknown command: #{method}.")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Push a dispatcher to the front of the stack
|
||||||
|
def enstack_dispatcher(dispatcher)
|
||||||
|
self.dispatcher_stack.unshift(dispatcher.new(self))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Pop a dispatcher from the front of the stacker
|
||||||
|
def destack_dispatcher
|
||||||
|
self.dispatcher_stack.shift
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
attr_accessor :dispatcher_stack
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -96,7 +96,7 @@ module Shell
|
||||||
# If a block was passed in, pass the line to it. If it returns true,
|
# If a block was passed in, pass the line to it. If it returns true,
|
||||||
# break out of the shell loop.
|
# break out of the shell loop.
|
||||||
if (block)
|
if (block)
|
||||||
break if (block.call(line, parse_line(line)))
|
break if (block.call(line))
|
||||||
# Otherwise, call what should be an overriden instance method to
|
# Otherwise, call what should be an overriden instance method to
|
||||||
# process the line.
|
# process the line.
|
||||||
else
|
else
|
||||||
|
@ -115,6 +115,13 @@ module Shell
|
||||||
self.stop_flag = true
|
self.stop_flag = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checks to see if the shell has stopped
|
||||||
|
#
|
||||||
|
def stopped?
|
||||||
|
self.stop_flag
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Change the input prompt
|
# Change the input prompt
|
||||||
#
|
#
|
||||||
|
|
|
@ -210,10 +210,7 @@ module DllInject
|
||||||
# Transmits the DLL injection payload and its associated DLL to the remote
|
# Transmits the DLL injection payload and its associated DLL to the remote
|
||||||
# computer so that it can be loaded into memory.
|
# computer so that it can be loaded into memory.
|
||||||
#
|
#
|
||||||
def handle_connection(conn)
|
def handle_connection_stage(conn)
|
||||||
# Call the parent so that the stage gets sent
|
|
||||||
super
|
|
||||||
|
|
||||||
data = library_name + "\x00"
|
data = library_name + "\x00"
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -226,6 +223,10 @@ module DllInject
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Give the stage a second or so, just so it doesn't try
|
||||||
|
# to read in the DLL as part of the stage...
|
||||||
|
Rex::ThreadSafe.sleep(1.5)
|
||||||
|
|
||||||
print_status("Uploading DLL (#{data.length} bytes)...")
|
print_status("Uploading DLL (#{data.length} bytes)...")
|
||||||
|
|
||||||
# Send the size of the thing we're transferring
|
# Send the size of the thing we're transferring
|
||||||
|
@ -234,6 +235,9 @@ module DllInject
|
||||||
conn.put(data)
|
conn.put(data)
|
||||||
|
|
||||||
print_status("Upload completed.")
|
print_status("Upload completed.")
|
||||||
|
|
||||||
|
# Call the parent so the session gets created.
|
||||||
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue