diff --git a/lib/msf/core/payload.rb b/lib/msf/core/payload.rb index d8bb963a68..6ce6255182 100644 --- a/lib/msf/core/payload.rb +++ b/lib/msf/core/payload.rb @@ -503,19 +503,22 @@ protected # # If the payload has assembly that needs to be compiled, do so now. - # This method takes the raw payload (p), the assembly text (asm), and the - # offsets hash for variables that need to be substituted (off). The suffix - # is used to localize the way the generated payload is cached (whether the - # blob is part of a single, stager, or stage, for example). # - def build(x, asm, off, suffix = '') - # If there is no assembly to be compiled, then we return a duplicated - # copy of the raw payload blob + # Blobs will be cached in the framework's PayloadSet + # + # @see PayloadSet#check_blob_cache + # @param asm [String] Assembly code to be assembled into a raw payload + # @return [String] The final, assembled payload + # @raise ArgumentError if +asm+ is blank + def build(asm, off={}) if(asm.nil? or asm.empty?) - return x.dup + raise ArgumentError, "Assembly must not be empty" end - cache_key = refname + suffix + # Use the refname so blobs can be flushed when the module gets + # reloaded and use the hash value to ensure that we're actually + # getting the right blob for the given assembly. + cache_key = refname + asm.hash.to_s cache_entry = framework.payloads.check_blob_cache(cache_key) off.each_pair { |option, val| @@ -573,7 +576,11 @@ protected def internal_generate # Build the payload, either by using the raw payload blob defined in the # module or by actually assembling it - raw = build(payload, assembly, offsets, '-stg0') + if assembly and !assembly.empty? + raw = build(assembly, offsets) + else + raw = payload.dup + end # If the payload is generated and there are offsets to substitute, # do that now. diff --git a/lib/msf/core/payload/stager.rb b/lib/msf/core/payload/stager.rb index c8db9f8462..b7a9cfd50a 100644 --- a/lib/msf/core/payload/stager.rb +++ b/lib/msf/core/payload/stager.rb @@ -107,13 +107,19 @@ module Msf::Payload::Stager # # @return [String] The generated payload stage, as a string. def generate_stage + # XXX: This is nearly identical to Payload#internal_generate + # Compile the stage as necessary - p = build(stage_payload, stage_assembly, stage_offsets, '-stg1') + if stage_assembly and !stage_assembly.empty? + raw = build(stage_assembly, stage_offsets) + else + raw = stage_payload.dup + end # Substitute variables in the stage - substitute_vars(p, stage_offsets) if (stage_offsets) + substitute_vars(raw, stage_offsets) if (stage_offsets) - return p + return raw end # diff --git a/lib/msf/core/payload_set.rb b/lib/msf/core/payload_set.rb index 899f48d814..9f5a919ac5 100644 --- a/lib/msf/core/payload_set.rb +++ b/lib/msf/core/payload_set.rb @@ -343,8 +343,11 @@ class PayloadSet < ModuleSet # it must be removed (if one exists) # def on_module_reload(mod) - @blob_cache.delete(mod.refname + "-stg0") - @blob_cache.delete(mod.refname + "-stg1") + @blob_cache.each_key do |key| + if key.start_with? mod.refname + @blob_cache.delete(key) + end + end end # diff --git a/lib/rex/proto/http/client_request.rb b/lib/rex/proto/http/client_request.rb index 76a4294af1..745d0b48a2 100644 --- a/lib/rex/proto/http/client_request.rb +++ b/lib/rex/proto/http/client_request.rb @@ -111,6 +111,9 @@ class ClientRequest end opts['vars_get'].each_pair do |var,val| + var = var.to_s + val = val.to_s + qstr << '&' if qstr.length > 0 qstr << (opts['encode_params'] ? set_encode_uri(var) : var) qstr << '=' @@ -129,6 +132,9 @@ class ClientRequest end opts['vars_post'].each_pair do |var,val| + var = var.to_s + val = val.to_s + pstr << '&' if pstr.length > 0 pstr << (opts['encode_params'] ? set_encode_uri(var) : var) pstr << '=' @@ -220,7 +226,7 @@ class ClientRequest end def set_encode_uri(str) - a = str.dup + a = str.to_s.dup opts['uri_encode_count'].times { a = Rex::Text.uri_encode(a, opts['uri_encode_mode']) }