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(datastore, _str, _words) ⇒ Object
Tab completion for datastore names.
-
#tab_complete_module_datastore_names(mod, str, words) ⇒ Object
Tab completion for a module’s 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
296 297 298 299 300 301 302 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 296 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
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 245 246 247 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 182 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
314 315 316 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 314 def option_values_encoders framework.encoders.module_refnames end |
#option_values_nops ⇒ Object
Provide valid nops options for the current exploit
307 308 309 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 307 def option_values_nops framework.nops.module_refnames end |
#option_values_payloads(mod) ⇒ Object
Provide valid payload options for the current exploit
259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 259 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
275 276 277 278 279 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 275 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
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 321 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
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 351 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
284 285 286 287 288 289 290 291 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 284 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(datastore, _str, _words) ⇒ Object
Tab completion for datastore names
18 19 20 21 22 23 24 25 26 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 18 def tab_complete_datastore_names(datastore, _str, _words) keys = ( Msf::DataStoreWithFallbacks::GLOBAL_KEYS + datastore.keys ) keys.concat(datastore..values.flat_map(&:fallbacks)) if datastore.is_a?(Msf::DataStoreWithFallbacks) keys.uniq! { |key| key.downcase } keys end |
#tab_complete_module_datastore_names(mod, str, words) ⇒ Object
Tab completion for a module’s datastore names
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 36 def tab_complete_module_datastore_names(mod, str, words) datastore = mod ? mod.datastore : framework.datastore keys = tab_complete_datastore_names(datastore, str, words) 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
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 51 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
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 121 122 123 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 74 def tab_complete_option_names(mod, str, words) res = tab_complete_module_datastore_names(mod, str, words) || [ ] if !mod return res end mod..sorted.each do |e| name, _opt = e 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
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 175 176 177 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 128 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
250 251 252 253 254 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 250 def tab_complete_source_interface(o) return [] unless o.is_a?(Msf::OptAddressLocal) o.interfaces end |