Skip to content

Commit

Permalink
Land #18750, Update payload to_handler command to support option over…
Browse files Browse the repository at this point in the history
…rides
  • Loading branch information
dwelch-r7 authored Jan 26, 2024
2 parents 5ea35c9 + 94eeba3 commit 7a7c7eb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 6 deletions.
46 changes: 44 additions & 2 deletions lib/msf/ui/console/command_dispatcher/payload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class Payload
Msf::Simple::Buffer.transform_formats + \
Msf::Util::EXE.to_executable_fmt_formats

@@to_handler_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Show this message' ]
)

@@generate_opts = Rex::Parser::Arguments.new(
'-p' => [ true, 'The platform of the payload' ],
'-n' => [ true, 'Prepend a nopsled of [length] size on to the payload' ],
Expand Down Expand Up @@ -45,12 +49,40 @@ def commands
)
end

def cmd_to_handler_help
print_line 'Usage: to_handler [options]'
print_line
print_line 'Creates a handler a payload. Datastore options may be supplied after normal options.'
print_line 'This is convenient way of using multi/handler, setting the payload, and then setting datastore options.'
print_line
print_line 'Example: to_handler'
print_line 'Example: to_handler LHOST=192.168.123.1'
print @@to_handler_opts.usage
end

def cmd_to_handler(*args)
if args.include?('-r') || args.include?('--reload-libs')
driver.run_single('reload_lib -a')
end

mod_with_opts = mod.replicant
handler = framework.modules.create('exploit/multi/handler')
handler.share_datastore(mod_with_opts.datastore)

@@to_handler_opts.parse(args) do |opt, _idx, val|
case opt
when '-h'
cmd_to_handler_help
return false
else
unless val.include?('=')
cmd_to_handler_help
return false
end

handler.datastore.import_options_from_s(val)
end
end

handler_opts = {
'Payload' => mod.refname,
Expand All @@ -62,8 +94,6 @@ def cmd_to_handler(*args)
}
}

handler.share_datastore(mod.datastore)

replicant_handler = nil
handler.exploit_simple(handler_opts) do |yielded_replicant_handler|
replicant_handler = yielded_replicant_handler
Expand All @@ -83,6 +113,18 @@ def cmd_to_handler(*args)

alias cmd_exploit cmd_to_handler

#
# Tab completion for the generate command
#
def cmd_to_handler_tabs(str, words)
fmt = {
'-h' => [ nil ],
}
flags = tab_complete_generic(fmt, str, words)
options = tab_complete_option(active_module, str, words)
flags + options
end

#
# Returns the command dispatcher name.
#
Expand Down
2 changes: 1 addition & 1 deletion spec/acceptance/meterpreter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def initialize(path)
expect(payload.size).to be > 0
end

console.sendline 'to_handler'
console.sendline payload.handler_command(default_module_datastore: default_module_datastore)
console.recvuntil(/Started reverse TCP handler[^\n]*\n/)
payload_process = executed_payload
session_id = nil
Expand Down
18 changes: 15 additions & 3 deletions spec/support/acceptance/child_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,15 +368,27 @@ def setg_commands(default_global_datastore: {})
# @param [Hash] default_module_datastore
# @return [String] The command which can be used on msfconsole to generate the payload
def generate_command(default_module_datastore: {})
module_datastore = default_module_datastore.merge(@datastore[:module])
generate_options = @generate_options.map do |key, value|
"#{key} #{value}"
end
"generate -o #{path} #{generate_options.join(' ')} #{datastore_options(default_module_datastore: default_module_datastore)}"
end

# @param [Hash] default_module_datastore
# @return [String] The command which can be used on msfconsole to create the listener
def handler_command(default_module_datastore: {})
"to_handler #{datastore_options(default_module_datastore: default_module_datastore)}"
end

# @param [Hash] default_module_datastore
# @return [String] The datastore options string
def datastore_options(default_module_datastore: {})
module_datastore = default_module_datastore.merge(@datastore[:module])
module_options = module_datastore.map do |key, value|
"#{key}=#{value}"
end

"generate -o #{path} #{generate_options.join(' ')} #{module_options.join(' ')}"
module_options.join(' ')
end

# @param [Hash] default_global_datastore
Expand All @@ -394,7 +406,7 @@ def as_readable_text(default_global_datastore: {}, default_module_datastore: {})
#{generate_command(default_module_datastore: default_module_datastore)}
## Create listener
to_handler
#{handler_command(default_module_datastore: default_module_datastore)}
## Execute command
#{Shellwords.join(execute_command)}
Expand Down

0 comments on commit 7a7c7eb

Please sign in to comment.