Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/ui/console/command_dispatcher/common.rb
36909 views
1
# -*- coding: binary -*-
2
3
require 'rexml/document'
4
5
module Msf
6
module Ui
7
module Console
8
module CommandDispatcher
9
10
# These are functions that are used in two or more command dispatchers.
11
12
module Common
13
14
# Parse +arg+ into a {Rex::Socket::RangeWalker} and append the result into +host_ranges+
15
#
16
# @note This modifies +host_ranges+ in place
17
#
18
# @param arg [String] The thing to turn into a RangeWalker
19
# @param host_ranges [Array] The array of ranges to append
20
# @param required [Boolean] Whether an empty +arg+ should be an error
21
# @return [Boolean] true if parsing was successful or false otherwise
22
def arg_host_range(arg, host_ranges, required=false)
23
if (!arg and required)
24
print_error("Missing required host argument")
25
return false
26
end
27
begin
28
rw = Rex::Socket::RangeWalker.new(arg)
29
rescue
30
print_error("Invalid host parameter, #{arg}.")
31
return false
32
end
33
34
if rw.valid?
35
host_ranges << rw
36
else
37
print_error("Invalid host parameter, #{arg}.")
38
return false
39
end
40
return true
41
end
42
43
#
44
# Parse +arg+ into an array of ports and append the result into +port_ranges+
45
#
46
# Returns true if parsing was successful or nil otherwise.
47
#
48
# NOTE: This modifies +port_ranges+
49
#
50
def arg_port_range(arg, port_ranges, required=false)
51
if (!arg and required)
52
print_error("Argument required for -p")
53
return
54
end
55
begin
56
port_ranges << Rex::Socket.portspec_to_portlist(arg)
57
rescue
58
print_error("Invalid port parameter, #{arg}.")
59
return
60
end
61
return true
62
end
63
64
#
65
# Set RHOSTS in the +active_module+'s (or global if none) datastore from an array of addresses
66
#
67
# This stores all the addresses to a temporary file and utilizes the
68
# <pre>file:/tmp/filename</pre> syntax to confer the addrs. +rhosts+
69
# should be an Array. NOTE: the temporary file is *not* deleted
70
# automatically.
71
#
72
def set_rhosts_from_addrs(rhosts)
73
if rhosts.empty?
74
print_status("The list is empty, cowardly refusing to set RHOSTS")
75
return
76
end
77
if active_module
78
mydatastore = active_module.datastore
79
else
80
# if there is no module in use set the list to the global variable
81
mydatastore = self.framework.datastore
82
end
83
84
if rhosts.length > 5
85
@rhosts_file_cleanup_proc ||= at_exit do
86
@temp_rhosts_files.each do |path|
87
File.delete(path)
88
rescue => e
89
elog(e)
90
end
91
end
92
# Lots of hosts makes 'show options' wrap which is difficult to
93
# read, store to a temp file
94
rhosts_file = Rex::Quickfile.create("msf-db-rhosts-")
95
@temp_rhosts_files ||= []
96
@temp_rhosts_files << rhosts_file.path
97
mydatastore['RHOSTS'] = 'file:'+rhosts_file.path
98
# create the output file and assign it to the RHOSTS variable
99
rhosts_file.write(rhosts.join("\n")+"\n")
100
rhosts_file.close
101
else
102
# For short lists, just set it directly
103
mydatastore['RHOSTS'] = rhosts.join(" ")
104
end
105
106
print_line "RHOSTS => #{mydatastore['RHOSTS']}"
107
print_line
108
end
109
110
def show_options(mod) # :nodoc:
111
mod_opt = Serializer::ReadableText.dump_options(mod, ' ')
112
print("\nModule options (#{mod.fullname}):\n\n#{mod_opt}\n") if (mod_opt and mod_opt.length > 0)
113
114
# If it's an exploit and a payload is defined, create it and
115
# display the payload's options
116
if ((mod.exploit? or mod.evasion? ) and mod.datastore['PAYLOAD'])
117
p = framework.payloads.create(mod.datastore['PAYLOAD'])
118
119
if (!p)
120
print_error("Invalid payload defined: #{mod.datastore['PAYLOAD']}\n")
121
return
122
end
123
124
p.share_datastore(mod.datastore)
125
126
if (p)
127
p_opt = Serializer::ReadableText.dump_options(p, ' ')
128
print("\nPayload options (#{mod.datastore['PAYLOAD']}):\n\n#{p_opt}\n") if (p_opt and p_opt.length > 0)
129
print(" **DisablePayloadHandler: True (no handler will be created!)**\n\n") if mod.datastore['DisablePayloadHandler'].to_s == 'true'
130
end
131
end
132
133
# Print the selected target
134
if (mod.exploit? and mod.target)
135
mod_targ = Serializer::ReadableText.dump_exploit_target(mod, ' ')
136
print("\nExploit target:\n\n#{mod_targ}\n") if (mod_targ and mod_targ.length > 0)
137
elsif mod.evasion? and mod.target
138
mod_targ = Serializer::ReadableText.dump_evasion_target(mod, ' ')
139
print("\nEvasion target:\n\n#{mod_targ}\n") if (mod_targ and mod_targ.length > 0)
140
end
141
142
# Print the selected action
143
if mod.kind_of?(Msf::Module::HasActions) && mod.action
144
mod_action = Serializer::ReadableText.dump_module_action(mod, ' ')
145
print("\n#{mod.type.capitalize} action:\n\n#{mod_action}\n") if (mod_action and mod_action.length > 0)
146
end
147
148
print("\nView the full module info with the #{Msf::Ui::Tip.highlight('info')}, or #{Msf::Ui::Tip.highlight('info -d')} command.\n\n")
149
150
# Uncomment this line if u want target like msf2 format
151
#print("\nTarget: #{mod.target.name}\n\n")
152
end
153
154
# This is for the "use" and "set" commands
155
def index_from_list(list, index, &block)
156
return unless list.kind_of?(Array) && index
157
158
begin
159
idx = Integer(index)
160
rescue ArgumentError
161
return
162
end
163
164
# Don't support negative indices
165
return if idx < 0
166
167
yield list[idx]
168
end
169
170
# Trims starting `.`, `./` `/`, `+path_head+/`, & `/+path_head+/` from +path+. Also trims trailing `.+extension+`
171
# from +path+, and any possible combination of misspellings of +extension+.
172
#
173
# @param path [String] The path to be trimmed
174
# @param path_head [String] The top-level directory that should be removed from the path
175
# @param extensions [Array] File extensions to be trimmed from +path+. `.` is automatically included. Defaults to ['rb', 'py', 'go'].
176
# @return [String] Altered +path+. Will return unaltered +path+ if regex constructed with +path_head+ & +path+ is not detected
177
def trim_path(path, path_head, extensions: ['rb', 'py', 'go'])
178
#Builds capture groups for all supported file extensions
179
regex_extension = ''
180
extensions.each do |ext|
181
regex_extension << "([#{ext}])+|"
182
end
183
regex_extension.delete_suffix!('|')
184
185
regexp = %r{
186
(
187
^\.? # Dot at beginning of path
188
/? # Slash at beginning of path
189
(#{path_head}/)? # top level directory (slash prepending directory name is optional)
190
)
191
192
| # OR
193
194
(
195
\.(#{regex_extension})$ # any possible file extension at end of path
196
)
197
198
| # OR
199
200
(
201
\.$ # trailing dot
202
)
203
}ix
204
205
path.gsub(regexp, '')
206
end
207
208
end
209
210
end
211
end
212
end
213
end
214
215