From 7774a240725b48092655b680f5910f369314f8a6 Mon Sep 17 00:00:00 2001 From: sjanusz-r7 Date: Thu, 3 Sep 2026 14:43:16 +0100 Subject: [PATCH] Resolve generic payload arch to prevent hanging encoder --- lib/msf/core/exploit.rb | 12 ++++++++++++ lib/msf/core/payload/generic.rb | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 81c37cab047c5..cacc39667c9e4 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -544,6 +544,18 @@ def generate_single_payload(pinst = nil, platform = nil, arch = nil, explicit_ta # Incorporate any context encoding requirements that are needed define_context_encoding_reqs(reqs) + # For generic payloads, constrain encoder (and NOP) module selection to the + # architecture and platform of the concrete payload that was resolved above. + # Without this, EncodedPayload#compatible_encoders falls back to the generic + # payload's ARCH_ALL and considers encoders for every architecture. An + # arch-inappropriate encoder (e.g. riscv64le/byte_xori applied to x86 + # shellcode) can then spin effectively forever brute-forcing a key that + # avoids the exploit's bad characters. + if real_payload.is_a?(Msf::Payload::Generic) + reqs['Arch'] ||= real_payload.resolved_arch + reqs['Platform'] ||= real_payload.resolved_platform + end + # Call the encode begin routine. encode_begin(real_payload, reqs) diff --git a/lib/msf/core/payload/generic.rb b/lib/msf/core/payload/generic.rb index 1a5e387fe1fd2..4a2c580a379b3 100644 --- a/lib/msf/core/payload/generic.rb +++ b/lib/msf/core/payload/generic.rb @@ -161,6 +161,31 @@ def redirect_to_actual(name, *args) # attr_accessor :explicit_arch + # + # Returns the architecture of the concrete payload that this generic payload + # resolves to, or nil if it cannot be determined yet. Unlike {#arch} (which + # advertises ARCH_ALL for compatibility matching), this reflects the payload + # that will actually be generated, so callers such as encoder selection can + # scope themselves to the right architecture. + # + # @return [Array, nil] + def resolved_arch + actual_arch + rescue NoCompatiblePayloadError + nil + end + + # + # Returns the platform of the concrete payload that this generic payload + # resolves to, or nil if it cannot be determined yet. + # + # @return [Msf::Module::PlatformList, nil] + def resolved_platform + actual_platform + rescue NoCompatiblePayloadError + nil + end + protected #