CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/base/simple/auxiliary.rb
Views: 1904
1
# -*- coding: binary -*-
2
module Msf
3
module Simple
4
5
###
6
#
7
# A simplified auxiliary wrapper.
8
#
9
###
10
module Auxiliary
11
12
include Module
13
14
#
15
# Wraps the auxiliary process in a simple single method. The options
16
# hash can have the following values passed in it:
17
#
18
# Action
19
#
20
# The selected action name.
21
#
22
# OptionStr
23
#
24
# A string of comma separated option values that should be imported into
25
# the datastore.
26
#
27
# Options
28
#
29
# A hash of values to be imported directly into the datastore.
30
#
31
# LocalInput
32
#
33
# The local input handle that data can be read in from.
34
#
35
# LocalOutput
36
#
37
# The local output through which data can be displayed.
38
#
39
# RunAsJob
40
#
41
# Whether or not the exploit should be run in the context of a background
42
# job.
43
#
44
def self.run_simple(omod, opts = {}, job_listener: Msf::Simple::NoopJobListener.instance, &block)
45
46
# Clone the module to prevent changes to the original instance
47
mod = omod.replicant
48
Msf::Simple::Framework.simplify_module(mod)
49
yield(mod) if block_given?
50
51
# Import options from the OptionStr or Option hash.
52
mod._import_extra_options(opts)
53
54
mod.datastore['ACTION'] = opts['Action'] if opts['Action']
55
56
# Verify the ACTION
57
if (mod.actions.length > 0 and not mod.action)
58
raise MissingActionError, "Please use: #{mod.actions.collect {|e| e.name} * ", "}"
59
end
60
61
# Verify the options
62
mod.options.validate(mod.datastore)
63
64
# Initialize user interaction
65
if ! opts['Quiet']
66
mod.init_ui(opts['LocalInput'] || mod.user_input, opts['LocalOutput'] || mod.user_output)
67
else
68
mod.init_ui(nil, nil)
69
end
70
71
run_uuid = Rex::Text.rand_text_alphanumeric(24)
72
job_listener.waiting run_uuid
73
ctx = [mod, run_uuid, job_listener]
74
run_as_job = opts['RunAsJob'].nil? ? mod.passive? : opts['RunAsJob']
75
if run_as_job
76
mod.job_id = mod.framework.jobs.start_bg_job(
77
"Auxiliary: #{mod.refname}",
78
ctx,
79
Proc.new { |ctx_| self.job_run_proc(ctx_, &:run) },
80
Proc.new { |ctx_| self.job_cleanup_proc(ctx_) }
81
)
82
# Propagate this back to the caller for console mgmt
83
omod.job_id = mod.job_id
84
return [run_uuid, mod.job_id]
85
else
86
result = self.job_run_proc(ctx, &:run)
87
self.job_cleanup_proc(ctx)
88
89
return result
90
end
91
end
92
93
#
94
# Calls the class method.
95
#
96
def run_simple(opts = {}, &block)
97
Msf::Simple::Auxiliary.run_simple(self, opts, &block)
98
end
99
100
#
101
# Initiates a check, setting up the exploit to be used. The following
102
# options can be specified:
103
#
104
# LocalInput
105
#
106
# The local input handle that data can be read in from.
107
#
108
# LocalOutput
109
#
110
# The local output through which data can be displayed.
111
#
112
def self.check_simple(mod, opts, job_listener: Msf::Simple::NoopJobListener.instance)
113
Msf::Simple::Framework.simplify_module(mod)
114
115
mod._import_extra_options(opts)
116
if opts['LocalInput']
117
mod.init_ui(opts['LocalInput'], opts['LocalOutput'])
118
end
119
120
unless mod.has_check?
121
# Bail out early if the module doesn't have check
122
raise ::NotImplementedError.new(Msf::Exploit::CheckCode::Unsupported.message)
123
end
124
125
# Validate the option container state so that options will
126
# be normalized
127
mod.validate
128
129
run_uuid = Rex::Text.rand_text_alphanumeric(24)
130
job_listener.waiting run_uuid
131
ctx = [mod, run_uuid, job_listener]
132
133
if opts['RunAsJob']
134
mod.job_id = mod.framework.jobs.start_bg_job(
135
"Auxiliary: #{mod.refname} check",
136
ctx,
137
Proc.new do |ctx_|
138
self.job_run_proc(ctx_) do |m|
139
m.check
140
end
141
end,
142
Proc.new { |ctx_| self.job_cleanup_proc(ctx_) }
143
)
144
145
[run_uuid, mod.job_id]
146
else
147
# Run check if it exists
148
result = self.job_run_proc(ctx) do |m|
149
m.check
150
end
151
self.job_cleanup_proc(ctx)
152
153
result
154
end
155
end
156
157
#
158
# Calls the class method.
159
#
160
def check_simple(opts)
161
Msf::Simple::Auxiliary.check_simple(self, opts)
162
end
163
164
165
protected
166
167
#
168
# Job run proc, sets up the module and kicks it off.
169
#
170
def self.job_run_proc(ctx, &block)
171
mod = ctx[0]
172
run_uuid = ctx[1]
173
job_listener = ctx[2]
174
begin
175
begin
176
job_listener.start run_uuid
177
mod.setup
178
mod.framework.events.on_module_run(mod)
179
result = block.call(mod)
180
job_listener.completed(run_uuid, result, mod)
181
rescue ::Exception => e
182
job_listener.failed(run_uuid, e, mod)
183
raise
184
end
185
rescue Msf::Auxiliary::Complete
186
mod.cleanup
187
return
188
rescue Msf::Auxiliary::Failed => e
189
mod.error = e
190
mod.print_error("Auxiliary aborted due to failure: #{e.message}")
191
mod.cleanup
192
return
193
rescue ::Timeout::Error => e
194
mod.error = e
195
mod.print_error("Auxiliary triggered a timeout exception")
196
mod.cleanup
197
return
198
rescue ::Interrupt => e
199
mod.error = e
200
mod.print_error("Stopping running against current target...")
201
mod.cleanup
202
mod.print_status("Control-C again to force quit all targets.")
203
begin
204
Rex.sleep(0.5)
205
rescue ::Interrupt
206
raise $!
207
end
208
return
209
rescue ::Msf::OptionValidateError => e
210
mod.error = e
211
::Msf::Ui::Formatter::OptionValidateError.print_error(mod, e)
212
rescue ::Exception => e
213
mod.error = e
214
mod.print_error("Auxiliary failed: #{e.class} #{e}")
215
if(e.class.to_s != 'Msf::OptionValidateError')
216
mod.print_error("Call stack:")
217
e.backtrace.each do |line|
218
break if line =~ /lib.msf.base.simple.auxiliary.rb/
219
mod.print_error(" #{line}")
220
end
221
end
222
223
elog('Auxiliary failed', error: e)
224
mod.cleanup
225
226
end
227
return result
228
end
229
230
#
231
# Clean up the module after the job completes.
232
#
233
def self.job_cleanup_proc(ctx)
234
mod = ctx[0]
235
mod.framework.events.on_module_complete(mod)
236
# Allow the exploit to cleanup after itself, that messy bugger.
237
mod.cleanup
238
end
239
240
end
241
242
end
243
end
244
245