Module: Msf::Ui::Console::CommandDispatcher::Common

Included in:
Core, Creds, Db, Jobs, Modules
Defined in:
lib/msf/ui/console/command_dispatcher/common.rb

Overview

These are functions that are used in two or more command dispatchers.

Instance Method Summary collapse

Instance Method Details

#arg_host_range(arg, host_ranges, required = false) ⇒ Boolean

Note:

This modifies host_ranges in place

Parse arg into a Rex::Socket::RangeWalker and append the result into host_ranges

Parameters:

  • arg (String)

    The thing to turn into a RangeWalker

  • host_ranges (Array)

    The array of ranges to append

  • required (Boolean) (defaults to: false)

    Whether an empty arg should be an error

Returns:

  • (Boolean)

    true if parsing was successful or false otherwise


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 24

def arg_host_range(arg, host_ranges, required=false)
  if (!arg and required)
    print_error("Missing required host argument")
    return false
  end
  begin
    rw = Rex::Socket::RangeWalker.new(arg)
  rescue
    print_error("Invalid host parameter, #{arg}.")
    return false
  end

  if rw.valid?
    host_ranges << rw
  else
    print_error("Invalid host parameter, #{arg}.")
    return false
  end
  return true
end

#arg_port_range(arg, port_ranges, required = false) ⇒ Object

Parse arg into an array of ports and append the result into port_ranges

Returns true if parsing was successful or nil otherwise.

NOTE: This modifies port_ranges


52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 52

def arg_port_range(arg, port_ranges, required=false)
  if (!arg and required)
    print_error("Argument required for -p")
    return
  end
  begin
    port_ranges << Rex::Socket.portspec_to_portlist(arg)
  rescue
    print_error("Invalid port parameter, #{arg}.")
    return
  end
  return true
end

#index_from_list(list, index) {|list[idx]| ... } ⇒ Object

This is for the “use” and “set” commands

Yields:

  • (list[idx])

146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 146

def index_from_list(list, index, &block)
  return unless list.kind_of?(Array) && index

  begin
    idx = Integer(index)
  rescue ArgumentError
    return
  end

  # Don't support negative indices
  return if idx < 0

  yield list[idx]
end

#set_rhosts_from_addrs(rhosts) ⇒ Object

Set RHOSTS in the active_module's (or global if none) datastore from an array of addresses

This stores all the addresses to a temporary file and utilizes the <pre>file:/tmp/filename</pre> syntax to confer the addrs. rhosts should be an Array. NOTE: the temporary file is not deleted automatically.


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
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 74

def set_rhosts_from_addrs(rhosts)
  if rhosts.empty?
    print_status("The list is empty, cowardly refusing to set RHOSTS")
    return
  end
  if active_module
    mydatastore = active_module.datastore
  else
    # if there is no module in use set the list to the global variable
    mydatastore = self.framework.datastore
  end

  if rhosts.length > 5
    # Lots of hosts makes 'show options' wrap which is difficult to
    # read, store to a temp file
    rhosts_file = Rex::Quickfile.new("msf-db-rhosts-")
    mydatastore['RHOSTS'] = 'file:'+rhosts_file.path
    # create the output file and assign it to the RHOSTS variable
    rhosts_file.write(rhosts.join("\n")+"\n")
    rhosts_file.close
  else
    # For short lists, just set it directly
    mydatastore['RHOSTS'] = rhosts.join(" ")
  end

  print_line "RHOSTS => #{mydatastore['RHOSTS']}"
  print_line
end

#show_options(mod) ⇒ Object

:nodoc:


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
143
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 103

def show_options(mod) # :nodoc:
  mod_opt = Serializer::ReadableText.dump_options(mod, '   ')
  print("\nModule options (#{mod.fullname}):\n\n#{mod_opt}\n") if (mod_opt and mod_opt.length > 0)

  # If it's an exploit and a payload is defined, create it and
  # display the payload's options
  if ((mod.exploit? or mod.evasion? ) and mod.datastore['PAYLOAD'])
    p = framework.payloads.create(mod.datastore['PAYLOAD'])

    if (!p)
      print_error("Invalid payload defined: #{mod.datastore['PAYLOAD']}\n")
      return
    end

    p.share_datastore(mod.datastore)

    if (p)
      p_opt = Serializer::ReadableText.dump_options(p, '   ')
      print("\nPayload options (#{mod.datastore['PAYLOAD']}):\n\n#{p_opt}\n") if (p_opt and p_opt.length > 0)
      print("   **DisablePayloadHandler: True   (no handler will be created!)**\n\n") if mod.datastore['DisablePayloadHandler'].to_s == 'true'
    end
  end

  # Print the selected target
  if (mod.exploit? and mod.target)
    mod_targ = Serializer::ReadableText.dump_exploit_target(mod, '   ')
    print("\nExploit target:\n\n#{mod_targ}\n") if (mod_targ and mod_targ.length > 0)
  elsif mod.evasion? and mod.target
    mod_targ = Serializer::ReadableText.dump_evasion_target(mod, '   ')
    print("\nEvasion target:\n\n#{mod_targ}\n") if (mod_targ and mod_targ.length > 0)
  end

  # Print the selected action
  if mod.kind_of?(Msf::Module::HasActions) && mod.action
    mod_action = Serializer::ReadableText.dump_module_action(mod, '   ')
    print("\n#{mod.type.capitalize} action:\n\n#{mod_action}\n") if (mod_action and mod_action.length > 0)
  end

  # Uncomment this line if u want target like msf2 format
  #print("\nTarget: #{mod.target.name}\n\n")
end

#trim_path(path, path_head, extensions: ['rb', 'py', 'go']) ⇒ String

Trims starting `.`, `./` `/`, `path_head/`, & `/path_head/` from path. Also trims trailing `.extension` from path, and any possible combination of misspellings of extension.

Parameters:

  • path (String)

    The path to be trimmed

  • path_head (String)

    The top-level directory that should be removed from the path

  • extensions (Array) (defaults to: ['rb', 'py', 'go'])

    File extensions to be trimmed from path. `.` is automatically included. Defaults to ['rb', 'py', 'go'].

Returns:

  • (String)

    Altered path. Will return unaltered path if regex constructed with path_head & path is not detected


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
# File 'lib/msf/ui/console/command_dispatcher/common.rb', line 168

def trim_path(path, path_head, extensions: ['rb', 'py', 'go'])
  #Builds capture groups for all supported file extensions
  regex_extension = ''
  extensions.each do |ext|
    regex_extension << "([#{ext}])+|"
  end
  regex_extension.delete_suffix!('|')

  regexp = %r{
      (
        ^\.?                      # Dot at beginning of path
        /?                        # Slash at beginning of path
        (#{path_head}/)?          # top level directory (slash prepending directory name is optional)
      )

      |                           # OR

      (
        \.(#{regex_extension})$   # any possible file extension at end of path
      )

      |                           # OR

      (
        \.$                       # trailing dot
      )
  }ix

  path.gsub(regexp, '')
end