Module: Msf::Ui::Console::ModuleOptionTabCompletion
- Includes:
- ModuleOptionValidation
- 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, include_aliases: false) ⇒ 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 OptAddressRoutable#interfaces, so we can’t put this in Rex.
Methods included from ModuleOptionValidation
#datastore_option_names, #unknown_datastore_option_message, #valid_datastore_option_names
Instance Method Details
#option_values_actions(mod) ⇒ Object
Provide valid action options for the current module
261 262 263 264 265 266 267 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 261 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
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 178 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 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 147 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
279 280 281 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 279 def option_values_encoders framework.encoders.module_refnames end |
#option_values_nops ⇒ Object
Provide valid nops options for the current exploit
272 273 274 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 272 def option_values_nops framework.nops.module_refnames end |
#option_values_payloads(mod) ⇒ Object
Provide valid payload options for the current exploit
224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 224 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
240 241 242 243 244 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 240 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
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 286 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
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 316 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
249 250 251 252 253 254 255 256 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 249 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
22 23 24 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 22 def tab_complete_datastore_names(datastore, _str, _words) datastore_option_names(datastore) end |
#tab_complete_module_datastore_names(mod, str, words) ⇒ Object
Tab completion for a module’s datastore names
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 34 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
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 49 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, include_aliases: false) ⇒ Object
Provide tab completion for name values
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 72 def tab_complete_option_names(mod, str, words, include_aliases: false) res = valid_datastore_option_names(mod, include_aliases: include_aliases, active_only: true) 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.sort end |
#tab_complete_option_values(mod, str, words, opt:) ⇒ Object
Provide tab completion for option values
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 93 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 OptAddressRoutable#interfaces, so we can’t put this in Rex
215 216 217 218 219 |
# File 'lib/msf/ui/console/module_option_tab_completion.rb', line 215 def tab_complete_source_interface(o) return [] unless o.is_a?(Msf::OptAddressRoutable) o.interfaces end |