From 8efc6caa8ab2cb4e1411bdf502ea784d5b006ed8 Mon Sep 17 00:00:00 2001 From: sjanusz-r7 Date: Wed, 27 Sep 2023 11:20:17 +0100 Subject: [PATCH] Show errors on inaccessible payload files --- Gemfile.lock | 4 ++-- LICENSE_GEMS | 2 +- lib/msf/core/feature_manager.rb | 7 +++++++ lib/msf/core/payload/stager.rb | 9 ++++----- lib/msf/ui/console/driver.rb | 14 +++++++++++++- metasploit-framework.gemspec | 2 +- scripts/resource/meterpreter_compatibility.rc | 2 +- test/modules/post/test/extapi.rb | 2 +- 8 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e55c5c0e21fda..4d2254af78722 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,7 +33,7 @@ PATH metasploit-concern metasploit-credential metasploit-model - metasploit-payloads (= 2.0.148) + metasploit-payloads (= 2.0.154) metasploit_data_models metasploit_payloads-mettle (= 1.0.26) mqtt @@ -275,7 +275,7 @@ GEM activemodel (~> 7.0) activesupport (~> 7.0) railties (~> 7.0) - metasploit-payloads (2.0.148) + metasploit-payloads (2.0.154) metasploit_data_models (6.0.2) activerecord (~> 7.0) activesupport (~> 7.0) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 425f0d8e99853..263c99e81cec0 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -80,7 +80,7 @@ metasploit-concern, 5.0.1, "New BSD" metasploit-credential, 6.0.5, "New BSD" metasploit-framework, 6.3.37, "New BSD" metasploit-model, 5.0.1, "New BSD" -metasploit-payloads, 2.0.148, "3-clause (or ""modified"") BSD" +metasploit-payloads, 2.0.154, "3-clause (or ""modified"") BSD" metasploit_data_models, 6.0.2, "New BSD" metasploit_payloads-mettle, 1.0.26, "3-clause (or ""modified"") BSD" method_source, 1.0.0, MIT diff --git a/lib/msf/core/feature_manager.rb b/lib/msf/core/feature_manager.rb index 227e3e9757a2c..baa79c1699676 100644 --- a/lib/msf/core/feature_manager.rb +++ b/lib/msf/core/feature_manager.rb @@ -18,6 +18,7 @@ class FeatureManager DATASTORE_FALLBACKS = 'datastore_fallbacks' FULLY_INTERACTIVE_SHELLS = 'fully_interactive_shells' MANAGER_COMMANDS = 'manager_commands' + METASPLOIT_PAYLOAD_WARNINGS = 'metasploit_payload_warnings' DEFAULTS = [ { name: WRAPPED_TABLES, @@ -39,6 +40,12 @@ class FeatureManager description: 'When enabled you can consistently set username across modules, instead of setting SMBUser/FTPUser/BIND_DN/etc', requires_restart: true, default_value: true + }.freeze, + { + name: METASPLOIT_PAYLOAD_WARNINGS, + description: 'When enabled Metasploit will output warnings about missing Metasploit payloads, for instance if they were removed by antivirus etc', + requires_restart: true, + default_value: false }.freeze ].freeze diff --git a/lib/msf/core/payload/stager.rb b/lib/msf/core/payload/stager.rb index 01840c6cf8368..354f1ad960fb3 100644 --- a/lib/msf/core/payload/stager.rb +++ b/lib/msf/core/payload/stager.rb @@ -188,15 +188,14 @@ def handle_connection(conn, opts={}) end end - p = generate_stage(opts) - - # Encode the stage if stage encoding is enabled + # Generate and encode the stage if stage encoding is enabled begin + p = generate_stage(opts) p = encode_stage(p) - rescue ::RuntimeError + rescue ::RuntimeError, ::StandardError => e warning_msg = "Failed to stage" warning_msg << " (#{conn.peerhost})" if conn.respond_to? :peerhost - warning_msg << ": #{$!}" + warning_msg << ": #{e}" print_warning warning_msg if conn.respond_to? :close && !conn.closed? conn.close diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index fd3ec84f4daeb..4b82016533283 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -364,7 +364,19 @@ def on_startup(opts = {}) run_single("banner") unless opts['DisableBanner'] - av_warning_message if framework.eicar_corrupted? + payloads_manifest_errors = framework.features.enabled?(::Msf::FeatureManager::METASPLOIT_PAYLOAD_WARNINGS) ? ::MetasploitPayloads.manifest_errors : [] + + av_warning_message if (framework.eicar_corrupted? || payloads_manifest_errors.any?) + + if framework.features.enabled?(::Msf::FeatureManager::METASPLOIT_PAYLOAD_WARNINGS) + if payloads_manifest_errors.any? + warn_msg = "Metasploit Payloads manifest errors:\n" + payloads_manifest_errors.each do |file| + warn_msg << "\t#{file[:path]} : #{file[:error]}\n" + end + $stderr.print(warn_msg) + end + end opts["Plugins"].each do |plug| run_single("load '#{plug}'") diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index ec91fba77e784..4ebfc3c277d47 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -72,7 +72,7 @@ Gem::Specification.new do |spec| # are needed when there's no database spec.add_runtime_dependency 'metasploit-model' # Needed for Meterpreter - spec.add_runtime_dependency 'metasploit-payloads', '2.0.148' + spec.add_runtime_dependency 'metasploit-payloads', '2.0.154' # Needed for the next-generation POSIX Meterpreter spec.add_runtime_dependency 'metasploit_payloads-mettle', '1.0.26' # Needed by msfgui and other rpc components diff --git a/scripts/resource/meterpreter_compatibility.rc b/scripts/resource/meterpreter_compatibility.rc index bef129ea4c4aa..072cc0493efbe 100644 --- a/scripts/resource/meterpreter_compatibility.rc +++ b/scripts/resource/meterpreter_compatibility.rc @@ -13,7 +13,7 @@ framework.sessions.values.map do |session| puts "[#{Time.now}][#{extension_name}] Starting to loading extension" session.core.use(extension_name) puts "[#{Time.now}][#{extension_name}] Loaded extension" - rescue ::RuntimeError + rescue ::RuntimeError, ::MetasploitPayloads::Error puts "[#{Time.now}][#{extension_name}] Failed loading" # noop end diff --git a/test/modules/post/test/extapi.rb b/test/modules/post/test/extapi.rb index 3e79250974148..630ece1dcb331 100644 --- a/test/modules/post/test/extapi.rb +++ b/test/modules/post/test/extapi.rb @@ -30,7 +30,7 @@ def setup vprint_status("Loading extapi extension...") begin session.core.use("extapi") - rescue Errno::ENOENT, Rex::Post::Meterpreter::ExtensionLoadError + rescue Errno::ENOENT, Rex::Post::Meterpreter::ExtensionLoadError, ::MetasploitPayloads::Error print_status("This module is only available in a windows meterpreter session.") return end