From b28d9517bc1572d4c75e862a4c5a308d8ba627c6 Mon Sep 17 00:00:00 2001 From: William Vu Date: Tue, 23 Jun 2020 00:03:31 -0500 Subject: [PATCH] Exclude multi from automatic PAYLOAD selection --- lib/msf/core/evasion.rb | 7 ++--- lib/msf/core/exploit.rb | 9 +++---- .../ui/console/command_dispatcher/exploit.rb | 26 ++++++++++++------- .../ui/console/command_dispatcher/modules.rb | 10 +++---- modules/exploits/multi/handler.rb | 1 + 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/msf/core/evasion.rb b/lib/msf/core/evasion.rb index 754e1d6a0c..e88279e576 100644 --- a/lib/msf/core/evasion.rb +++ b/lib/msf/core/evasion.rb @@ -118,15 +118,16 @@ module Msf # Returns a list of compatible payloads based on platform, architecture, # and size requirements. - def compatible_payloads + def compatible_payloads(excluded_platforms: [], excluded_archs: []) payloads = [] c_platform, c_arch = normalize_platform_arch + # The "All" platform name represents generic payloads results = Msf::Modules::Metadata::Cache.instance.find( 'type' => [['payload'], []], - 'platform' => [[*c_platform.names, 'All'], []], # "All" for generic - 'arch' => [c_arch, []] + 'platform' => [[*c_platform.names, 'All'], excluded_platforms], + 'arch' => [c_arch, excluded_archs] ) results.each do |res| diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 0773efeaf5..5b5e56e277 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -814,19 +814,18 @@ class Exploit < Msf::Module return true end - # # Returns a list of compatible payloads based on platform, architecture, # and size requirements. - # - def compatible_payloads + def compatible_payloads(excluded_platforms: [], excluded_archs: []) payloads = [] c_platform, c_arch = normalize_platform_arch + # The "All" platform name represents generic payloads results = Msf::Modules::Metadata::Cache.instance.find( 'type' => [['payload'], []], - 'platform' => [[*c_platform.names, 'All'], []], # "All" for generic - 'arch' => [c_arch, []] + 'platform' => [[*c_platform.names, 'All'], excluded_platforms], + 'arch' => [c_arch, excluded_archs] ) results.each do |res| diff --git a/lib/msf/ui/console/command_dispatcher/exploit.rb b/lib/msf/ui/console/command_dispatcher/exploit.rb index 938c524ae7..416b3471fa 100644 --- a/lib/msf/ui/console/command_dispatcher/exploit.rb +++ b/lib/msf/ui/console/command_dispatcher/exploit.rb @@ -290,17 +290,23 @@ class Exploit # Select a reasonable default payload and minimally configure it # TODO: Move this somewhere better or make it more dynamic? def self.choose_payload(mod) - compatible_payloads = mod.compatible_payloads.map(&:first) + compatible_payloads = mod.compatible_payloads( + excluded_platforms: ['Multi'] # We don't want to select a multi payload + ).map(&:first) - # XXX: This approach is subpar, but at least this list has been reevaluated - preferred_payloads = %w[ - meterpreter/reverse_https - meterpreter/reverse_http - meterpreter/reverse_tcp - shell_reverse_tcp - shell/reverse_tcp - generic/shell_reverse_tcp - generic/shell_bind_tcp + # If there is only one compatible payload, return it immediately + return compatible_payloads.first if compatible_payloads.length == 1 + + # XXX: This approach is subpar, and payloads should really be ranked! + preferred_payloads = [ + # These payloads are generally reliable and common enough in practice + '/meterpreter/reverse_tcp', + '/shell/reverse_tcp', + 'cmd/unix/reverse_netcat', + 'cmd/windows/powershell_reverse_tcp', + # Fall back on a generic payload to autoselect a specific payload + 'generic/shell_reverse_tcp', + 'generic/shell_bind_tcp' ] # XXX: Determine LHOST based on RHOST or an arbitrary internet address diff --git a/lib/msf/ui/console/command_dispatcher/modules.rb b/lib/msf/ui/console/command_dispatcher/modules.rb index 70487d6f02..c4fb3ed080 100644 --- a/lib/msf/ui/console/command_dispatcher/modules.rb +++ b/lib/msf/ui/console/command_dispatcher/modules.rb @@ -769,13 +769,11 @@ module Msf end # Choose a default payload when the module is used, not run - if mod.datastore['PAYLOAD'].nil? && dispatcher.respond_to?(:choose_payload) + if mod.datastore['PAYLOAD'] + print_status("Using configured payload #{mod.datastore['PAYLOAD']}") + elsif dispatcher.respond_to?(:choose_payload) chosen_payload = dispatcher.choose_payload(mod) - - # XXX: No vprint_status in this context - if framework.datastore['VERBOSE'].to_s == 'true' && chosen_payload - print_status("No payload configured, defaulting to #{chosen_payload}") - end + print_status("No payload configured, defaulting to #{chosen_payload}") if chosen_payload end mod.init_ui(driver.input, driver.output) diff --git a/modules/exploits/multi/handler.rb b/modules/exploits/multi/handler.rb index c6a94c8e79..b44f5f8358 100644 --- a/modules/exploits/multi/handler.rb +++ b/modules/exploits/multi/handler.rb @@ -34,6 +34,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Arch' => ARCH_ALL, 'Targets' => [ [ 'Wildcard Target', {} ] ], 'DefaultTarget' => 0, + 'DefaultOptions' => { 'PAYLOAD' => 'generic/shell_reverse_tcp' } ) )