Module: Msf::Ui::Console::ModuleOptionTabCompletion
- Included in:
- CommandDispatcher::Auxiliary, CommandDispatcher::Core, CommandDispatcher::Evasion, CommandDispatcher::Exploit, CommandDispatcher::Payload, CommandDispatcher::Post
- Defined in:
- lib/msf/ui/console/module_option_tab_completion.rb
Overview
Module-specific tab completion helper.
Instance Method Summary collapse
-
#option_values_actions(mod) ⇒ Object
Provide valid action options for the current module.
-
#option_values_dispatch(mod, o, str, words) ⇒ Object
Provide possible option values based on type.
-
#option_values_encoders ⇒ Object
Provide valid encoders options for the current exploit or payload.
-
#option_values_nops ⇒ Object
Provide valid nops options for the current exploit.
-
#option_values_payloads(mod) ⇒ Object
Provide valid payload options for the current exploit.
-
#option_values_sessions(mod) ⇒ Object
Provide valid session options for the current post-exploit module.
-
#option_values_target_addrs(mod) ⇒ Object
Provide the target addresses.
-
#option_values_target_ports(mod) ⇒ Object
Provide the target ports.
-
#option_values_targets(mod) ⇒ Object
Provide valid target options for the current exploit.
-
#tab_complete_datastore_names(mod, _str, _words) ⇒ Object
Tab completion for datastore names.
-
#tab_complete_option(mod, str, words) ⇒ Object
Tab completion options values.
-
#tab_complete_option_names(mod, str, words) ⇒ Object
Provide tab completion for name values.
-
#tab_complete_option_values(mod, str, words, opt:) ⇒ Object
Provide tab completion for option values.
-
#tab_complete_source_interface(o) ⇒ Object
XXX: We repurpose OptAddressLocal#interfaces, so we can't put this in Rex.
Instance Method Details
#option_values_actions(mod) ⇒ Object
Provide valid action options for the current module
293 294 295 296 297 298 299 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 293 def option_values_actions(mod) res = [] if mod.actions mod.actions.each { |i| res << i.name } end return res end |
#option_values_dispatch(mod, o, str, words) ⇒ Object
Provide possible option values based on type
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 179 def option_values_dispatch(mod, o, str, words) res = [] res << o.default.to_s if o.default case o when Msf::OptAddress case o.name.upcase when 'RHOST' option_values_target_addrs(mod).each do |addr| res << addr end when 'LHOST', 'SRVHOST', 'REVERSELISTENERBINDADDRESS' rh = mod.datastore['RHOST'] || framework.datastore['RHOST'] if rh && !rh.empty? res << Rex::Socket.source_address(rh) else res += tab_complete_source_address res += tab_complete_source_interface(o) end end when Msf::OptAddressRange, Msf::OptRhosts case str when /^file:(.*)/ files = tab_complete_filenames(Regexp.last_match(1), words) res += files.map { |f| 'file:' + f } if files when %r{^(.*)/\d{0,2}$} left = Regexp.last_match(1) if Rex::Socket.is_ipv4?(left) res << left + '/32' res << left + '/24' res << left + '/16' end when /^(.*)\-$/ left = Regexp.last_match(1) if Rex::Socket.is_ipv4?(left) res << str + str[0, str.length - 1] end else option_values_target_addrs(mod).each do |addr| res << addr end end when Msf::OptPort case o.name.upcase when 'RPORT' option_values_target_ports(mod).each do |port| res << port end end when Msf::OptEnum o.enums.each do |val| res << val end when Msf::OptPath files = tab_complete_filenames(str, words) res += files if files when Msf::OptBool res << 'true' res << 'false' when Msf::OptString if (str =~ /^file:(.*)/) files = tab_complete_filenames(Regexp.last_match(1), words) res += files.map { |f| 'file:' + f } if files end end return res end |
#option_values_encoders ⇒ Object
Provide valid encoders options for the current exploit or payload
311 312 313 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 311 def option_values_encoders framework.encoders.map { |refname, _mod| refname } end |
#option_values_nops ⇒ Object
Provide valid nops options for the current exploit
304 305 306 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 304 def option_values_nops framework.nops.map { |refname, _mod| refname } end |
#option_values_payloads(mod) ⇒ Object
Provide valid payload options for the current exploit
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 256 def option_values_payloads(mod) if @cache_payloads && mod == @previous_module && mod.target == @previous_target return @cache_payloads end @previous_module = mod @previous_target = mod.target @cache_payloads = mod.compatible_payloads.map do |refname, _payload| refname end @cache_payloads end |
#option_values_sessions(mod) ⇒ Object
Provide valid session options for the current post-exploit module
272 273 274 275 276 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 272 def option_values_sessions(mod) if mod.respond_to?(:compatible_sessions) mod.compatible_sessions.map { |sid| sid.to_s } end end |
#option_values_target_addrs(mod) ⇒ Object
Provide the target addresses
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 318 def option_values_target_addrs(mod) res = [ ] res << Rex::Socket.source_address return res if !framework.db.active # List only those hosts with matching open ports? mport = mod.datastore['RPORT'] if mport mport = mport.to_i hosts = {} framework.db.services.each do |service| if service.port == mport hosts[service.host.address] = true end end hosts.keys.each do |host| res << host end # List all hosts in the database else framework.db.hosts.each do |host| res << host.address end end return res end |
#option_values_target_ports(mod) ⇒ Object
Provide the target ports
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 348 def option_values_target_ports(mod) return [] unless framework.db.active return [] if mod.datastore['RHOST'].nil? host_addresses = mod.datastore['RHOST'].split.map do |addr| address, _scope = addr.split('%', 2) address end hosts = framework.db.hosts({:address => host_addresses, :workspace => framework.db.workspace}) return [] if hosts.empty? res = [] hosts.each do |host| host.services.each do |service| res << service.port.to_s end end res.uniq end |
#option_values_targets(mod) ⇒ Object
Provide valid target options for the current exploit
281 282 283 284 285 286 287 288 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 281 def option_values_targets(mod) res = [] if mod.targets 1.upto(mod.targets.length) { |i| res << (i - 1).to_s } res += mod.targets.map(&:name) end return res end |
#tab_complete_datastore_names(mod, _str, _words) ⇒ Object
Tab completion for datastore names
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 17 def tab_complete_datastore_names(mod, _str, _words) datastore = mod ? mod.datastore : framework.datastore keys = datastore.keys if mod keys = keys.delete_if do |name| !(mod_opt = mod.[name]).nil? && !Msf::OptCondition.show_option(mod, mod_opt) end end keys end |
#tab_complete_option(mod, str, words) ⇒ Object
Tab completion options values
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 32 def tab_complete_option(mod, str, words) if str.end_with?('=') option_name = str.chop option_value = '' ::Readline.completion_append_character = ' ' return tab_complete_option_values(mod, option_value, words, opt: option_name).map { |value| "#{str}#{value}" } elsif str.include?('=') str_split = str.split('=') option_name = str_split[0].strip option_value = str_split[1].strip ::Readline.completion_append_character = ' ' return tab_complete_option_values(mod, option_value, words, opt: option_name).map { |value| "#{option_name}=#{value}" } end ::Readline.completion_append_character = '' tab_complete_option_names(mod, str, words).map { |name| "#{name}=" } end |
#tab_complete_option_names(mod, str, words) ⇒ Object
Provide tab completion for name values
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 55 def tab_complete_option_names(mod, str, words) res = tab_complete_datastore_names(mod, str, words) || [ ] # There needs to be a better way to register global options, but for # now all we have is an ad-hoc list of opts that the shell treats # specially. res += %w[ ConsoleLogging LogLevel MinimumRank SessionLogging TimestampOutput Prompt PromptChar PromptTimeFormat MeterpreterPrompt SessionTlvLogging ] if !mod return res end mod..sorted.each do |e| name, _opt = e next unless Msf::OptCondition.show_option(mod, _opt) res << name end # Exploits provide these three default options if mod.exploit? res << 'PAYLOAD' res << 'NOP' res << 'TARGET' res << 'ENCODER' elsif mod.evasion? res << 'PAYLOAD' res << 'TARGET' res << 'ENCODER' elsif mod.payload? res << 'ENCODER' end if mod.is_a?(Msf::Module::HasActions) res << 'ACTION' end if ((mod.exploit? || mod.evasion?) && mod.datastore['PAYLOAD']) p = framework.payloads.create(mod.datastore['PAYLOAD']) if p p..sorted.each do |e| name, _opt = e res << name end end end unless str.blank? res = res.select { |term| term.upcase.start_with?(str.upcase) } res = res.map do |term| if str == str.upcase str + term[str.length..-1].upcase elsif str == str.downcase str + term[str.length..-1].downcase else str + term[str.length..-1] end end end return res end |
#tab_complete_option_values(mod, str, words, opt:) ⇒ Object
Provide tab completion for option values
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 125 def tab_complete_option_values(mod, str, words, opt:) if words.last.casecmp?('SessionTlvLogging') return %w[console true false file:<file>] end res = [] # With no module, we have nothing to complete if !mod return res end # Well-known option names specific to exploits if mod.exploit? return option_values_payloads(mod) if opt.upcase == 'PAYLOAD' return option_values_targets(mod) if opt.upcase == 'TARGET' return option_values_nops if opt.upcase == 'NOPS' return option_values_encoders if opt.upcase == 'STAGEENCODER' elsif mod.evasion? return option_values_payloads(mod) if opt.upcase == 'PAYLOAD' return option_values_targets(mod) if opt.upcase == 'TARGET' end # Well-known option names specific to modules with actions if mod.is_a?(Msf::Module::HasActions) return option_values_actions(mod) if opt.upcase == 'ACTION' end # The ENCODER option works for evasions, payloads and exploits if ((mod.evasion? || mod.exploit? || mod.payload?) && (opt.upcase == 'ENCODER')) return option_values_encoders end # Well-known option names specific to post-exploitation if (mod.post? || mod.exploit?) return option_values_sessions(mod) if opt.upcase == 'SESSION' end # Is this option used by the active module? mod..each_key do |key| if key.downcase == opt.downcase res.concat(option_values_dispatch(mod, mod.[key], str, words)) end end # How about the selected payload? if ((mod.evasion? || mod.exploit?) && mod.datastore['PAYLOAD']) if p = framework.payloads.create(mod.datastore['PAYLOAD']) p..each_key do |key| res.concat(option_values_dispatch(mod, p.[key], str, words)) if key.downcase == opt.downcase end end end return res end |
#tab_complete_source_interface(o) ⇒ Object
XXX: We repurpose OptAddressLocal#interfaces, so we can't put this in Rex
247 248 249 250 251 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 247 def tab_complete_source_interface(o) return [] unless o.is_a?(Msf::OptAddressLocal) o.interfaces end |