Skip to content

Commit 67c25c2

Browse files
committed
Land rapid7#3357, Run Local Exploits in AutoRunScript
2 parents 64dbc39 + 3fc5710 commit 67c25c2

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

lib/msf/base/sessions/scriptable.rb

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,29 +52,65 @@ def execute_file
5252
end
5353

5454
#
55-
# Executes the supplied script or Post module with arguments +args+
55+
# Executes the supplied script, Post module, or local Exploit module with
56+
# arguments +args+
5657
#
5758
# Will search the script path.
5859
#
5960
def execute_script(script_name, *args)
6061
mod = framework.modules.create(script_name)
61-
if (mod and mod.type == "post")
62+
if mod
6263
# Don't report module run events here as it will be taken care of
6364
# in +Post.run_simple+
6465
opts = { 'SESSION' => self.sid }
6566
args.each do |arg|
6667
k,v = arg.split("=", 2)
67-
opts[k] = v
68+
# case doesn't matter in datastore, but it does in hashes, let's normalize
69+
opts[k.downcase] = v
6870
end
69-
mod.run_simple(
70-
# Run with whatever the default stance is for now. At some
71-
# point in the future, we'll probably want a way to force a
72-
# module to run in the background
73-
#'RunAsJob' => true,
74-
'LocalInput' => self.user_input,
75-
'LocalOutput' => self.user_output,
76-
'Options' => opts
77-
)
71+
if mod.type == "post"
72+
mod.run_simple(
73+
# Run with whatever the default stance is for now. At some
74+
# point in the future, we'll probably want a way to force a
75+
# module to run in the background
76+
#'RunAsJob' => true,
77+
'LocalInput' => self.user_input,
78+
'LocalOutput' => self.user_output,
79+
'Options' => opts
80+
)
81+
elsif mod.type == "exploit"
82+
# well it must be a local, we're not currently supporting anything else
83+
if mod.exploit_type == "local"
84+
# get a copy of the session exploit's datastore if we can
85+
original_exploit_datastore = self.exploit.datastore || {}
86+
copy_of_orig_exploit_datastore = original_exploit_datastore.clone
87+
# convert datastore opts to a hash to normalize casing issues
88+
local_exploit_opts = {}
89+
copy_of_orig_exploit_datastore.each do |k,v|
90+
local_exploit_opts[k.downcase] = v
91+
end
92+
# we don't want to inherit a couple things, like AutoRunScript's
93+
to_neuter = %w{AutoRunScript InitialAutoRunScript LPORT TARGET}
94+
to_neuter.each do |setting|
95+
local_exploit_opts.delete(setting.downcase)
96+
end
97+
98+
# merge in any opts that were passed in, defaulting all other settings
99+
# to the values from the datastore (of the exploit) that spawned the
100+
# session
101+
local_exploit_opts = local_exploit_opts.merge(opts)
102+
103+
new_session = mod.exploit_simple(
104+
'Payload' => local_exploit_opts.delete('payload'),
105+
'Target' => local_exploit_opts.delete('target'),
106+
'LocalInput' => self.user_input,
107+
'LocalOutput' => self.user_output,
108+
'Options' => local_exploit_opts
109+
)
110+
111+
end # end if local
112+
end # end if exploit
113+
78114
else
79115
full_path = self.class.find_script_path(script_name)
80116

@@ -91,4 +127,3 @@ def execute_script(script_name, *args)
91127
end
92128

93129
end
94-

0 commit comments

Comments
 (0)