CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/base/simple/post.rb
Views: 11784
1
# -*- coding: binary -*-
2
module Msf
3
module Simple
4
5
###
6
#
7
# A simplified post-exploitation module wrapper.
8
#
9
###
10
module Post
11
12
include Module
13
14
#
15
# Wraps the post-exploitation module running process in a simple single
16
# method. The options hash can have the following values passed in it:
17
#
18
# OptionStr
19
#
20
# A string of comma separated option values that should be imported into
21
# the datastore.
22
#
23
# Options
24
#
25
# A hash of values to be imported directly into the datastore.
26
#
27
# LocalInput
28
#
29
# The local input handle that data can be read in from.
30
#
31
# LocalOutput
32
#
33
# The local output through which data can be displayed.
34
#
35
# RunAsJob
36
#
37
# Whether or not the module should be run in the context of a background
38
# job.
39
#
40
def self.run_simple(omod, opts = {}, &block)
41
42
# Clone the module to prevent changes to the original instance
43
mod = omod.replicant
44
Msf::Simple::Framework.simplify_module(mod)
45
yield(mod) if block_given?
46
47
# Import options from the OptionStr or Option hash.
48
mod._import_extra_options(opts)
49
50
mod.datastore['ACTION'] = opts['Action'] if opts['Action']
51
52
# Verify the ACTION
53
if (mod.actions.length > 0 and not mod.action)
54
raise MissingActionError, "Please use: #{mod.actions.collect {|e| e.name} * ", "}"
55
end
56
57
# Verify the options
58
mod.options.validate(mod.datastore)
59
60
# Initialize user interaction
61
if ! opts['Quiet']
62
mod.init_ui(opts['LocalInput'] || mod.user_input, opts['LocalOutput'] || mod.user_output)
63
else
64
mod.init_ui(nil, nil)
65
end
66
67
#
68
# Disable this until we can test background stuff a little better
69
#
70
if(mod.passive? or opts['RunAsJob'])
71
ctx = [ mod.replicant ]
72
mod.job_id = mod.framework.jobs.start_bg_job(
73
"Post: #{mod.refname}",
74
ctx,
75
Proc.new { |ctx_| self.job_run_proc(ctx_) },
76
Proc.new { |ctx_| self.job_cleanup_proc(ctx_) }
77
)
78
# Propagate this back to the caller for console mgmt
79
omod.job_id = mod.job_id
80
else
81
ctx = [ mod ]
82
self.job_run_proc(ctx)
83
self.job_cleanup_proc(ctx)
84
end
85
end
86
87
#
88
# Calls the class method.
89
#
90
def run_simple(opts = {}, &block)
91
Msf::Simple::Post.run_simple(self, opts, &block)
92
end
93
94
protected
95
96
#
97
# Job run proc, sets up the module and kicks it off.
98
#
99
# XXX: Mostly Copy/pasted from simple/auxiliary.rb
100
#
101
def self.job_run_proc(ctx)
102
mod = ctx[0]
103
begin
104
mod.setup
105
mod.framework.events.on_module_run(mod)
106
# Grab the session object since we need to fire an event for not
107
# only the normal module_run event that all module types have to
108
# report, but a specific event for sessions as well.
109
s = mod.framework.sessions.get(mod.datastore["SESSION"])
110
if s
111
mod.framework.events.on_session_module_run(s, mod)
112
mod.run
113
else
114
mod.print_error("Session not found")
115
mod.cleanup
116
return
117
end
118
rescue Msf::Post::Complete
119
mod.cleanup
120
return
121
rescue Msf::Post::Failed => e
122
mod.error = e
123
mod.print_error("Post aborted due to failure: #{e.message}")
124
mod.cleanup
125
return
126
rescue ::Timeout::Error => e
127
mod.error = e
128
mod.print_error("Post triggered a timeout exception")
129
mod.cleanup
130
return
131
rescue ::Interrupt => e
132
mod.error = e
133
mod.print_error("Post interrupted by the console user")
134
mod.cleanup
135
return
136
rescue ::Msf::OptionValidateError => e
137
mod.error = e
138
::Msf::Ui::Formatter::OptionValidateError.print_error(mod, e)
139
rescue ::Exception => e
140
mod.error = e
141
mod.print_error("Post failed: #{e.class} #{e}")
142
if(e.class.to_s != 'Msf::OptionValidateError')
143
mod.print_error("Call stack:")
144
e.backtrace.each do |line|
145
break if line =~ /lib.msf.base.simple.post.rb/
146
mod.print_error(" #{line}")
147
end
148
end
149
150
elog('Post failed', error: e)
151
mod.cleanup
152
153
return
154
end
155
end
156
157
#
158
# Clean up the module after the job completes.
159
#
160
# Copy/pasted from simple/auxiliary.rb
161
#
162
def self.job_cleanup_proc(ctx)
163
mod = ctx[0]
164
mod.framework.events.on_module_complete(mod)
165
# Allow the exploit to cleanup after itself, that messy bugger.
166
mod.cleanup
167
end
168
169
end
170
171
end
172
end
173
174