post modules working for shell sessions, fixes #3541

git-svn-id: file:///home/svn/framework3/trunk@11599 4d416f70-5f16-0410-b530-b9f4589650da
unstable
James Lee 2011-01-19 02:24:21 +00:00
parent 41e43b557c
commit d120892e7c
5 changed files with 45 additions and 129 deletions

View File

@ -1,4 +1,5 @@
require 'msf/base'
require 'msf/base/sessions/scriptable'
module Msf
module Sessions
@ -22,6 +23,19 @@ class CommandShell
#
include Msf::Session::Provider::SingleCommandShell
include Msf::Session::Scriptable
#
# Executes the supplied script, must be specified as full path.
#
# Msf::Session::Scriptable implementor
#
def execute_file(full_path, args)
o = Rex::Script::Shell.new(self, full_path)
o.run(args)
end
#
# Returns the type of session.
#
@ -29,36 +43,6 @@ class CommandShell
"shell"
end
#
# Find out of the script exists (and if so, which path)
#
ScriptBase = Msf::Config.script_directory + Msf::Config::FileSep + "shell"
UserScriptBase = Msf::Config.user_script_directory + Msf::Config::FileSep + "shell"
def self.find_script_path(script)
# Find the full file path of the specified argument
check_paths =
[
script,
ScriptBase + Msf::Config::FileSep + "#{script}",
ScriptBase + Msf::Config::FileSep + "#{script}.rb",
UserScriptBase + Msf::Config::FileSep + "#{script}",
UserScriptBase + Msf::Config::FileSep + "#{script}.rb"
]
full_path = nil
# Scan all of the path combinations
check_paths.each { |path|
if ::File.exists?(path)
full_path = path
break
end
}
full_path
end
def initialize(*args)
self.platform ||= ""
self.arch ||= ""
@ -93,29 +77,6 @@ class CommandShell
return true
end
#
# Executes the supplied script, will search the script path.
#
def execute_script(script, args)
full_path = self.class.find_script_path(script)
# No path found? Weak.
if full_path.nil?
print_error("The specified script could not be found: #{script}")
return true
end
execute_file(full_path, args)
end
#
# Executes the supplied script, must be specified as full path.
#
def execute_file(full_path, args)
o = Rex::Script::Shell.new(self, full_path)
o.run(args)
end
#
# Explicitly run a single command, return the output.
#
@ -263,13 +224,13 @@ class CommandShell
if (datastore['InitialAutoRunScript'] && datastore['InitialAutoRunScript'].empty? == false)
args = datastore['InitialAutoRunScript'].split
print_status("Session ID #{sid} (#{tunnel_to_s}) processing InitialAutoRunScript '#{datastore['InitialAutoRunScript']}'")
execute_script(args.shift, args)
execute_script(args.shift, *args)
end
if (datastore['AutoRunScript'] && datastore['AutoRunScript'].empty? == false)
args = datastore['AutoRunScript'].split
print_status("Session ID #{sid} (#{tunnel_to_s}) processing AutoRunScript '#{datastore['AutoRunScript']}'")
execute_script(args.shift, args)
execute_script(args.shift, *args)
end
end

View File

@ -3,6 +3,7 @@
##
require 'msf/base'
require 'msf/base/sessions/scriptable'
require 'rex/post/meterpreter'
module Msf
@ -24,35 +25,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
include Msf::Session::Interactive
include Msf::Session::Comm
#
# Find out of the script exists (and if so, which path)
#
ScriptBase = Msf::Config.script_directory + Msf::Config::FileSep + "meterpreter"
UserScriptBase = Msf::Config.user_script_directory + Msf::Config::FileSep + "meterpreter"
def self.find_script_path(script)
# Find the full file path of the specified argument
check_paths =
[
script,
ScriptBase + Msf::Config::FileSep + "#{script}",
ScriptBase + Msf::Config::FileSep + "#{script}.rb",
UserScriptBase + Msf::Config::FileSep + "#{script}",
UserScriptBase + Msf::Config::FileSep + "#{script}.rb"
]
full_path = nil
# Scan all of the path combinations
check_paths.each { |path|
if ::File.exists?(path)
full_path = path
break
end
}
full_path
end
include Msf::Session::Scriptable
# Override for server implementations that can't do ssl
def supports_ssl?
@ -92,10 +65,17 @@ class Meterpreter < Rex::Post::Meterpreter::Client
#
# Returns the session type as being 'meterpreter'.
#
def type
def self.type
"meterpreter"
end
#
# Calls the class method
#
def type
self.class.type
end
#
# Called by PacketDispatcher to resolve error codes to names.
# This is the default version (return the number itself)
@ -126,6 +106,22 @@ class Meterpreter < Rex::Post::Meterpreter::Client
"Meterpreter"
end
##
#
# Msf::Session::Scriptable implementors
#
##
#
# Runs the meterpreter script in the context of a script container
#
def execute_file(full_path, args)
o = Rex::Script::Meterpreter.new(self, full_path)
o.run(args)
end
##
#
# Msf::Session::Interactive implementors
@ -178,22 +174,6 @@ class Meterpreter < Rex::Post::Meterpreter::Client
console.run_single(cmd)
end
#
# Executes the supplied script.
#
def execute_script(script, args)
full_path = self.class.find_script_path(script)
# No path found? Weak.
if full_path.nil?
print_error("The specified script could not be found: #{script}")
return true
end
execute_file(full_path, args)
end
#
# Load the stdapi extension.
#

View File

@ -57,29 +57,12 @@ module MeterpreterOptions
if (datastore[key].empty? == false)
args = datastore[key].split
print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'")
run_script(session, args.shift, *args)
session.execute_script(args.shift, *args)
end
end
end
def run_script(session, script_name, *args)
mod = session.framework.modules.create(script_name)
if (mod and mod.type == "post")
opts = (args + [ "SESSION=#{session.sid}" ]).join(',')
mod.run_simple(
# Run with whatever the default stance is for now. At some
# point in the future, we'll probably want a way to force a
# module to run in the background
#'RunAsJob' => true,
'LocalInput' => session.user_input,
'LocalOutput' => session.user_output,
'OptionStr' => opts
)
else
session.execute_script(script_name, args)
end
end
end
end
end

View File

@ -207,14 +207,6 @@ class Client
@@ssl_ctx
end
#
# Runs the meterpreter script in the context of a script container
#
def execute_file(file, args)
o = Rex::Script::Meterpreter.new(self, file)
o.run(args)
end
##
#
# Accessors

View File

@ -395,8 +395,8 @@ class Console::CommandDispatcher::Core
tabs += tab_complete_postmods
end
[
::Msf::Sessions::Meterpreter::ScriptBase,
::Msf::Sessions::Meterpreter::UserScriptBase
::Msf::Sessions::Meterpreter.script_base,
::Msf::Sessions::Meterpreter.user_script_base
].each do |dir|
next if not ::File.exist? dir
tabs += ::Dir.new(dir).find_all { |e|