diff --git a/lib/msf/base/sessions/scriptable.rb b/lib/msf/base/sessions/scriptable.rb index 4780aae3cf..662b28091e 100644 --- a/lib/msf/base/sessions/scriptable.rb +++ b/lib/msf/base/sessions/scriptable.rb @@ -52,29 +52,65 @@ module Scriptable end # - # Executes the supplied script or Post module with arguments +args+ + # Executes the supplied script, Post module, or local Exploit module with + # arguments +args+ # # Will search the script path. # def execute_script(script_name, *args) mod = framework.modules.create(script_name) - if (mod and mod.type == "post") + if mod # Don't report module run events here as it will be taken care of # in +Post.run_simple+ opts = { 'SESSION' => self.sid } args.each do |arg| k,v = arg.split("=", 2) - opts[k] = v + # case doesn't matter in datastore, but it does in hashes, let's normalize + opts[k.downcase] = v end - 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' => self.user_input, - 'LocalOutput' => self.user_output, - 'Options' => opts - ) + if mod.type == "post" + 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' => self.user_input, + 'LocalOutput' => self.user_output, + 'Options' => opts + ) + elsif mod.type == "exploit" + # well it must be a local, we're not currently supporting anything else + if mod.exploit_type == "local" + # get a copy of the session exploit's datastore if we can + original_exploit_datastore = self.exploit.datastore || {} + copy_of_orig_exploit_datastore = original_exploit_datastore.clone + # convert datastore opts to a hash to normalize casing issues + local_exploit_opts = {} + copy_of_orig_exploit_datastore.each do |k,v| + local_exploit_opts[k.downcase] = v + end + # we don't want to inherit a couple things, like AutoRunScript's + to_neuter = %w{AutoRunScript InitialAutoRunScript LPORT TARGET} + to_neuter.each do |setting| + local_exploit_opts.delete(setting.downcase) + end + + # merge in any opts that were passed in, defaulting all other settings + # to the values from the datastore (of the exploit) that spawned the + # session + local_exploit_opts = local_exploit_opts.merge(opts) + + new_session = mod.exploit_simple( + 'Payload' => local_exploit_opts.delete('payload'), + 'Target' => local_exploit_opts.delete('target'), + 'LocalInput' => self.user_input, + 'LocalOutput' => self.user_output, + 'Options' => local_exploit_opts + ) + + end # end if local + end # end if exploit + else full_path = self.class.find_script_path(script_name) @@ -91,4 +127,3 @@ module Scriptable end end -