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/ui/console/command_dispatcher/session.rb
Views: 11786
1
# frozen_string_literal: true
2
3
module Msf
4
module Ui
5
module Console
6
module CommandDispatcher
7
module Session
8
include Rex::Ui::Text::DispatcherShell::CommandDispatcher
9
10
@@irb_opts = Rex::Parser::Arguments.new(
11
%w[-h --help] => [false, 'Help menu.' ],
12
'-e' => [true, 'Expression to evaluate.']
13
)
14
15
@@sessions_opts = Rex::Parser::Arguments.new(
16
['-h', '--help'] => [ false, 'Show this message' ],
17
['-i', '--interact'] => [ true, 'Interact with a provided session ID', '<id>' ]
18
)
19
20
def commands
21
{
22
'?' => 'Help menu',
23
'background' => 'Backgrounds the current session',
24
'bg' => 'Alias for background',
25
'exit' => 'Terminate the session',
26
'help' => 'Help menu',
27
'irb' => 'Open an interactive Ruby shell on the current session',
28
'pry' => 'Open the Pry debugger on the current session',
29
'quit' => 'Terminate the session',
30
'resource' => 'Run the commands stored in a file',
31
'uuid' => 'Get the UUID for the current session',
32
'sessions' => 'Quickly switch to another session'
33
}
34
end
35
36
def cmd_background_help
37
print_line('Usage: background')
38
print_line
39
print_line('Stop interacting with this session and return to the parent prompt')
40
print_line
41
end
42
43
def cmd_background(*args)
44
if args.include?('-h') || args.include?('--help')
45
cmd_background_help
46
return
47
end
48
print_status("Backgrounding session #{session.name}...")
49
session.interacting = false
50
end
51
52
alias cmd_bg cmd_background
53
alias cmd_bg_help cmd_background_help
54
55
#
56
# Terminates the session.
57
#
58
def cmd_exit(*args)
59
print_status("Shutting down session: #{session.sid}")
60
session.exit
61
end
62
63
alias cmd_quit cmd_exit
64
65
def cmd_irb_help
66
print_line('Usage: irb')
67
print_line
68
print_line('Open an interactive Ruby shell on the current session.')
69
print @@irb_opts.usage
70
end
71
72
def cmd_irb_tabs(str, words)
73
return [] if words.length > 1
74
75
@@irb_opts.option_keys
76
end
77
78
#
79
# Open an interactive Ruby shell on the current session
80
#
81
def cmd_irb(*args)
82
expressions = []
83
84
# Parse the command options
85
@@irb_opts.parse(args) do |opt, _idx, val|
86
case opt
87
when '-e'
88
expressions << val
89
when '-h', '--help'
90
return cmd_irb_help
91
end
92
end
93
94
framework = session.framework
95
96
if expressions.empty?
97
print_status('Starting IRB shell...')
98
print_status("You are in the session object\n")
99
framework.history_manager.with_context(name: :irb) do
100
Rex::Ui::Text::IrbShell.new(session).run
101
end
102
else
103
# XXX: No vprint_status here
104
if framework.datastore['VERBOSE'].to_s == 'true'
105
print_status("You are executing expressions in #{binding.receiver}")
106
end
107
108
expressions.each { |expression| eval(expression, binding) }
109
end
110
end
111
112
def cmd_pry_help
113
print_line 'Usage: pry'
114
print_line
115
print_line 'Open the Pry debugger on the current session.'
116
print_line
117
end
118
119
#
120
# Open the Pry debugger on the current session
121
#
122
def cmd_pry(*args)
123
if args.include?('-h') || args.include?('--help')
124
cmd_pry_help
125
return
126
end
127
128
begin
129
require 'pry'
130
rescue LoadError
131
print_error('Failed to load Pry, try "gem install pry"')
132
return
133
end
134
135
print_status('Starting Pry shell...')
136
print_status("You are in the session object\n")
137
138
Pry.config.history_load = false
139
session.framework.history_manager.with_context(history_file: Msf::Config.pry_history, name: :pry) do
140
session.pry
141
end
142
end
143
144
def cmd_sessions_help
145
print_line('Usage: sessions [options] or sessions [id]')
146
print_line
147
print_line('Interact with a different session ID.')
148
print(@@sessions_opts.usage)
149
print_line
150
end
151
152
def cmd_sessions(*args)
153
if args.empty?
154
cmd_sessions_help
155
return false
156
end
157
158
sid = nil
159
160
if args.length == 1 && args[0] =~ /-?\d+/
161
sid = args[0].to_i
162
else
163
@@sessions_opts.parse(args) do |opt, _idx, val|
164
case opt
165
when '-h', '--help'
166
cmd_sessions_help
167
return false
168
when '-i', '--interact'
169
sid = val.to_i
170
else
171
cmd_sessions_help
172
return false
173
end
174
end
175
end
176
177
if sid == 0 || sid.nil?
178
cmd_sessions_help
179
return false
180
end
181
182
if sid.to_s == session.name.to_s
183
print_status("Session #{session.name} is already interactive.")
184
else
185
print_status("Backgrounding session #{session.name}...")
186
# store the next session id so that it can be referenced as soon
187
# as this session is no longer interacting
188
session.next_session = sid
189
session.interacting = false
190
end
191
end
192
193
def cmd_resource_help
194
print_line 'Usage: resource path1 [path2 ...]'
195
print_line
196
print_line 'Run the commands stored in the supplied files. (- for stdin, press CTRL+D to end input from stdin)'
197
print_line 'Resource files may also contain ERB or Ruby code between <ruby></ruby> tags.'
198
print_line
199
end
200
201
def cmd_resource(*args)
202
if args.empty? || args.include?('-h') || args.include?('--help')
203
cmd_resource_help
204
return false
205
end
206
207
args.each do |res|
208
good_res = nil
209
if res == '-'
210
good_res = res
211
elsif ::File.exist?(res)
212
good_res = res
213
elsif [
214
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
215
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter'
216
].each do |dir|
217
res_path = dir + ::File::SEPARATOR + res
218
if ::File.exist?(res_path)
219
good_res = res_path
220
break
221
end
222
end
223
# let's check to see if it's in the scripts/resource dir (like when tab completed)
224
end
225
unless good_res
226
print_error("#{res} is not a valid resource file")
227
next
228
end
229
230
session.console.load_resource(good_res)
231
end
232
end
233
234
def cmd_resource_tabs(str, words)
235
tabs = []
236
# return tabs if words.length > 1
237
if (str && str =~ (/^#{Regexp.escape(::File::SEPARATOR)}/))
238
# then you are probably specifying a full path so let's just use normal file completion
239
return tab_complete_filenames(str, words)
240
elsif (!(words[1]) || !words[1].match(%r{^/}))
241
# then let's start tab completion in the scripts/resource directories
242
begin
243
[
244
::Msf::Config.script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
245
::Msf::Config.user_script_directory + ::File::SEPARATOR + 'resource' + ::File::SEPARATOR + 'meterpreter',
246
'.'
247
].each do |dir|
248
next if !::File.exist? dir
249
250
tabs += ::Dir.new(dir).find_all do |e|
251
path = dir + ::File::SEPARATOR + e
252
::File.file?(path) and ::File.readable?(path)
253
end
254
end
255
rescue StandardError => e
256
elog('Problem tab completing resource file names in the scripts/resource directories', error: e)
257
end
258
else
259
tabs += tab_complete_filenames(str, words)
260
end
261
262
return tabs
263
end
264
end
265
end
266
end
267
end
268
end
269
270